import os
import pickle
import pandas as pd
import plotly.express as px
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import tkinter as tk
from tkinter import messagebox, filedialog, ttk
import threading
import logging
from datetime import datetime

# Configurare logging
logging.basicConfig(filename='gmail_alerts.log', level=logging.INFO, 
                    format='%(asctime)s - %(levelname)s - %(message)s')

# Configurare inițială
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
TOKEN_FILE = 'token.pickle'
CREDENTIALS_FILE = 'credentials.json'

def authenticate_gmail(credentials_path):
    """Autentifică utilizatorul și returnează serviciul Gmail API."""
    creds = None
    if os.path.exists(TOKEN_FILE):
        with open(TOKEN_FILE, 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            if not os.path.exists(credentials_path):
                raise FileNotFoundError("Fișierul de credențiale nu a fost găsit!")
            flow = InstalledAppFlow.from_client_secrets_file(credentials_path, SCOPES)
            creds = flow.run_local_server(port=0)
        with open(TOKEN_FILE, 'wb') as token:
            pickle.dump(creds, token)
    return build('gmail', 'v1', credentials=creds)

def get_alert_emails(service, query):
    """Caută e-mailurile bazate pe un query personalizat."""
    logging.info(f"Căutare e-mailuri cu query: {query}")
    results = service.users().messages().list(userId='me', q=query).execute()
    return results.get('messages', [])

def extract_data(service, messages):
    """Extrage datele din e-mailuri."""
    data = []
    for msg in messages:
        msg_data = service.users().messages().get(userId='me', id=msg['id']).execute()
        headers = msg_data['payload']['headers']
        date = next(header['value'] for header in headers if header['name'] == 'Date')
        subject = next(header['value'] for header in headers if header['name'] == 'Subject')
        data.append({'date': date, 'subject': subject})
    logging.info(f"Extrase {len(data)} e-mailuri.")
    return pd.DataFrame(data)

def create_plot(df):
    """Creează un grafic frumos cu Plotly."""
    df['date'] = pd.to_datetime(df['date'], errors='coerce')
    df['date'] = df['date'].dt.date
    alert_counts = df.groupby('date').size().reset_index(name='count')
    fig = px.bar(alert_counts, x='date', y='count', 
                 title='Frecvența Alertelor',
                 labels={'date': 'Data', 'count': 'Număr de Alerte'},
                 color='count', color_continuous_scale='Viridis')
    fig.update_layout(
        xaxis_title="Data", 
        yaxis_title="Număr de Alerte", 
        title_font_size=20,
        template='plotly_dark'
    )
    fig.show()

def save_to_csv(df):
    """Salvează datele într-un fișier CSV."""
    filename = f"alerts_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
    df.to_csv(filename, index=False)
    logging.info(f"Date salvate în {filename}")
    return filename

def process_data():
    """Procesează datele într-un thread separat."""
    credentials_path = entry_credentials.get()
    query = entry_query.get() or 'subject:"Google Alert"'
    progress_bar.start()
    submit_button.config(state='disabled')

    try:
        service = authenticate_gmail(credentials_path)
        messages = get_alert_emails(service, query)
        if messages:
            df = extract_data(service, messages)
            create_plot(df)
            saved_file = save_to_csv(df)
            messagebox.showinfo("Succes", f"Date procesate și salvate în {saved_file}")
        else:
            messagebox.showinfo("Info", "Nu s-au găsit e-mailuri cu acest query.")
    except Exception as e:
        logging.error(f"Eroare: {str(e)}")
        messagebox.showerror("Eroare", f"A apărut o eroare: {str(e)}")
    finally:
        progress_bar.stop()
        submit_button.config(state='normal')

def on_submit():
    """Handler pentru butonul de submit."""
    if not entry_credentials.get():
        messagebox.showerror("Eroare", "Te rog să selectezi fișierul de credențiale!")
        return
    threading.Thread(target=process_data, daemon=True).start()

def select_credentials():
    """Permite selectarea fișierului de credențiale."""
    file_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])
    if file_path:
        entry_credentials.delete(0, tk.END)
        entry_credentials.insert(0, file_path)

# Crearea interfeței grafice
root = tk.Tk()
root.title("Monitorizare Alerte Gmail")
root.geometry("600x300")

tk.Label(root, text="Fișier credențiale (JSON):").grid(row=0, column=0, padx=10, pady=10)
entry_credentials = tk.Entry(root, width=50)
entry_credentials.grid(row=0, column=1, padx=10, pady=10)
tk.Button(root, text="Selectează", command=select_credentials).grid(row=0, column=2, padx=5)

tk.Label(root, text="Cuvânt cheie (opțional):").grid(row=1, column=0, padx=10, pady=10)
entry_query = tk.Entry(root, width=50)
entry_query.grid(row=1, column=1, padx=10, pady=10)

submit_button = tk.Button(root, text="Procesează și Generează Grafic", command=on_submit)
submit_button.grid(row=2, column=0, columnspan=3, pady=20)

progress_bar = ttk.Progressbar(root, mode='indeterminate')
progress_bar.grid(row=3, column=0, columnspan=3, pady=10, sticky='ew')

root.mainloop()
