"""
Paperclip Outlook Sent Email Finder — GUI (tkinter)
"""
import threading
import time
import tkinter as tk
from tkinter import ttk, messagebox

from find_email import (
    connect_outlook,
    folder_display_name,
    list_search_folders,
    load_emails_from_folders,
    search_emails,
    check_ai_available,
    format_results_text,
)


class OutlookFinderGUI:

    def __init__(self, root: tk.Tk):
        self.root = root
        self.root.title("AI_Studioxyz Email-Sucher")
        self.root.geometry("820x520")
        self.root.minsize(600, 400)

        import os, sys
        if getattr(sys, 'frozen', False):
            icon_path = os.path.join(sys._MEIPASS, 'email-sucher.ico')
        else:
            icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'email-sucher.ico')
        if os.path.exists(icon_path):
            self.root.iconbitmap(icon_path)

        self.namespace = None
        self.emails: list[dict] = []
        self.results: list[dict] = []
        self.folder_options: list[tuple[str, list]] = []
        self.use_ai = False

        self._build_ui()
        self.root.after(100, self._load_outlook)

    # ── UI ───────────────────────────────────────────────────────────────

    def _build_ui(self):
        # Folder selector
        folder_bar = ttk.Frame(self.root, padding=(8, 8, 8, 0))
        folder_bar.pack(fill=tk.X)

        ttk.Label(folder_bar, text="Ordner:").pack(side=tk.LEFT, padx=(0, 6))
        self.folder_var = tk.StringVar(value="Alle Outlook-Ordner")
        self.folder_select = ttk.Combobox(
            folder_bar,
            textvariable=self.folder_var,
            state="disabled",
            width=44,
        )
        self.folder_select.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 6))
        self.folder_select.bind("<<ComboboxSelected>>", lambda _: self._load_selected_folder())

        self.reload_btn = ttk.Button(
            folder_bar,
            text="Ordner laden",
            command=self._load_selected_folder,
            state=tk.DISABLED,
        )
        self.reload_btn.pack(side=tk.RIGHT)

        # Search bar
        top = ttk.Frame(self.root, padding=8)
        top.pack(fill=tk.X)

        self.search_var = tk.StringVar()
        self.search_entry = ttk.Entry(top, textvariable=self.search_var, font=("Segoe UI", 13))
        self.search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 6))
        self.search_entry.insert(0, "E-Mail suchen...")
        self.search_entry.bind("<FocusIn>", self._clear_placeholder)
        self.search_entry.bind("<Return>", lambda _: self._do_search())

        self.search_btn = ttk.Button(top, text="Suchen", command=self._do_search)
        self.search_btn.pack(side=tk.RIGHT)

        # Results list
        cols = ("date", "to", "subject")
        self.tree = ttk.Treeview(self.root, columns=cols, show="headings", selectmode="browse")
        self.tree.heading("date", text="Datum")
        self.tree.heading("to", text="Empfänger")
        self.tree.heading("subject", text="Betreff")
        self.tree.column("date", width=130, minwidth=100, stretch=False)
        self.tree.column("to", width=200, minwidth=120)
        self.tree.column("subject", width=400, minwidth=150)
        self.tree.pack(fill=tk.BOTH, expand=True, padx=8, pady=(0, 4))
        self.tree.bind("<Double-1>", lambda _: self._open_in_outlook())

        scrollbar = ttk.Scrollbar(self.tree, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # Buttons
        btn_frame = ttk.Frame(self.root, padding=(8, 4))
        btn_frame.pack(fill=tk.X)

        self.open_btn = ttk.Button(btn_frame, text="In Outlook öffnen", command=self._open_in_outlook)
        self.open_btn.pack(side=tk.LEFT, padx=(0, 6))

        self.copy_btn = ttk.Button(btn_frame, text="Kopieren", command=self._copy_results)
        self.copy_btn.pack(side=tk.LEFT)

        # Status bar
        self.status_var = tk.StringVar(value="Starte...")
        ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, padding=4).pack(
            fill=tk.X, side=tk.BOTTOM
        )

    def _clear_placeholder(self, _event):
        if self.search_var.get() == "E-Mail suchen...":
            self.search_entry.delete(0, tk.END)

    # ── Outlook loading ──────────────────────────────────────────────────

    def _load_outlook(self):
        self.status_var.set("Verbinde mit Outlook...")
        self.search_btn.config(state=tk.DISABLED)
        self.reload_btn.config(state=tk.DISABLED)
        threading.Thread(target=self._load_worker, daemon=True).start()

    def _load_worker(self):
        try:
            self.namespace = connect_outlook()
            self.use_ai = check_ai_available()
            folders = list_search_folders(self.namespace)
            self.root.after(0, self._set_folder_options, folders)
            self.emails = load_emails_from_folders(folders, days=730)
            mode = "KI-Suche" if self.use_ai else "Stichwortsuche"
            self.root.after(0, self._on_loaded, f"{len(self.emails)} E-Mails geladen — {mode} aktiv")
        except Exception as exc:
            self.root.after(0, self._on_loaded, f"Fehler: {exc}")

    def _set_folder_options(self, folders: list):
        options: list[tuple[str, list]] = [("Alle Outlook-Ordner", folders)]
        seen = {"Alle Outlook-Ordner"}

        for folder in folders:
            label = folder_display_name(folder)
            if label in seen:
                label = f"{label} ({len(seen)})"
            seen.add(label)
            options.append((label, [folder]))

        self.folder_options = options
        self.folder_select["values"] = [label for label, _ in options]
        self.folder_var.set("Alle Outlook-Ordner")
        self.folder_select.config(state="readonly")
        self.reload_btn.config(state=tk.NORMAL)

    def _load_selected_folder(self):
        if not self.folder_options:
            return
        selected = self.folder_var.get()
        folders = next((items for label, items in self.folder_options if label == selected), None)
        if not folders:
            return

        self.search_btn.config(state=tk.DISABLED)
        self.reload_btn.config(state=tk.DISABLED)
        self.tree.delete(*self.tree.get_children())
        self.results = []
        self.status_var.set(f"Lade {selected}...")
        threading.Thread(target=self._folder_load_worker, args=(selected, folders), daemon=True).start()

    def _folder_load_worker(self, selected: str, folders: list):
        try:
            self.emails = load_emails_from_folders(folders, days=730)
            self.root.after(0, self._on_loaded, f"{len(self.emails)} E-Mails aus {selected} geladen")
        except Exception as exc:
            self.root.after(0, self._on_loaded, f"Fehler: {exc}")

    def _on_loaded(self, msg: str):
        self.status_var.set(msg)
        self.search_btn.config(state=tk.NORMAL)
        if self.folder_options:
            self.reload_btn.config(state=tk.NORMAL)
        self.search_entry.focus_set()

    # ── Search ───────────────────────────────────────────────────────────

    def _do_search(self):
        query = self.search_var.get().strip()
        if not query or query == "E-Mail suchen...":
            return
        if not self.emails:
            self.status_var.set("Keine E-Mails geladen.")
            return

        self.search_btn.config(state=tk.DISABLED)
        self.status_var.set("Suche läuft...")
        threading.Thread(target=self._search_worker, args=(query,), daemon=True).start()

    def _search_worker(self, query: str):
        t0 = time.perf_counter()
        results = search_emails(self.emails, query, self.use_ai)
        elapsed = time.perf_counter() - t0
        self.root.after(0, self._show_results, results, elapsed)

    def _show_results(self, results: list[dict], elapsed: float):
        self.results = results
        self.tree.delete(*self.tree.get_children())
        for email in results:
            self.tree.insert("", tk.END, values=(
                email["date"].strftime("%d.%m.%Y %H:%M"),
                email["to"],
                email["subject"],
            ))
        self.status_var.set(
            f"{len(results)} Treffer — {elapsed:.1f}s — {len(self.emails)} E-Mails durchsucht"
        )
        self.search_btn.config(state=tk.NORMAL)

    # ── Actions ──────────────────────────────────────────────────────────

    def _selected_index(self) -> int | None:
        sel = self.tree.selection()
        if not sel:
            messagebox.showinfo("Hinweis", "Bitte zuerst eine E-Mail auswählen.")
            return None
        return self.tree.index(sel[0])

    def _open_in_outlook(self):
        idx = self._selected_index()
        if idx is None:
            return
        item = self.results[idx].get("_com_item")
        if item:
            try:
                item.Display()
                self.status_var.set("E-Mail in Outlook geöffnet.")
            except Exception as exc:
                messagebox.showerror("Fehler", f"Konnte E-Mail nicht öffnen: {exc}")
        else:
            messagebox.showerror("Fehler", "COM-Objekt nicht verfügbar.")

    def _copy_results(self):
        if not self.results:
            self.status_var.set("Keine Ergebnisse zum Kopieren.")
            return
        text = format_results_text(self.results)
        self.root.clipboard_clear()
        self.root.clipboard_append(text)
        self.status_var.set(f"{len(self.results)} Ergebnisse in die Zwischenablage kopiert.")


def main():
    root = tk.Tk()
    OutlookFinderGUI(root)
    root.mainloop()


if __name__ == "__main__":
    main()
