import { Gtk } from "ags/gtk4";
import { createState } from "ags";
import GLib from "gi://GLib";
import Gio from "gi://Gio";

type Email = { subject: string; sender: string; date: string };

const REFRESH_SECONDS = 1800;

const CACHE_FILE = GLib.build_filenamev([
    GLib.get_user_cache_dir(),
    "ags",
    "unread-emails.json",
]);

// Resolve script path relative to this source file.
const sourceFile = Gio.File.new_for_uri(import.meta.url);
const sourceDir = sourceFile.get_parent()!;
const projectDir = sourceDir.get_parent()!.get_parent()!;
const SCRIPT_PATH = projectDir
    .get_child("scripts")
    .get_child("ags-emails-fetch.sh")
    .get_path()!;

// Helpers

function readEmails(): Email[] {
    try {
        const file = Gio.File.new_for_path(CACHE_FILE);
        const [ok, contents] = file.load_contents(null);
        if (!ok) return [];
        const data = JSON.parse(new TextDecoder("utf-8").decode(contents));
        if (!Array.isArray(data)) return [];
        return data.map((m: any) => ({
            subject: m.subject || "(no subject)",
            sender: m.from?.name || m.from?.addr || "Unknown",
            date: m.date ? new Date(m.date).toLocaleString() : "Unknown date",
        }));
    } catch {
        return [];
    }
}

// Widget

export default function Email() {
    const [emails, setEmails] = createState<Email[]>([]);
    let timerId = 0;
    let popover: Gtk.Popover | null = null;
    let popoverList: Gtk.Box | null = null;
    let btnLabel: Gtk.Label | null = null;

    // UI updates

    function updateButtonLabel() {
        if (!btnLabel) return;
        const count = emails().length;
        btnLabel.label = count > 0 ? ` ${count}` : "";
    }

    function rebuildPopoverContent() {
        if (!popoverList) return;

        // Clear existing
        let child = popoverList.get_first_child();
        while (child) {
            const next = child.get_next_sibling();
            popoverList.remove(child);
            child = next;
        }

        const current = emails();

        if (current.length === 0) {
            const empty = new Gtk.Box({
                halign: Gtk.Align.CENTER,
                valign: Gtk.Align.CENTER,
                orientation: Gtk.Orientation.VERTICAL,
                cssClasses: ["email-empty"],
            });
            empty.append(new Gtk.Label({
                label: "📭",
                cssClasses: ["empty-icon"],
            }));
            empty.append(new Gtk.Label({
                label: "No unread emails",
                cssClasses: ["status-text"],
            }));
            popoverList.append(empty);
        } else {
            for (const email of current) {
                const item = new Gtk.Box({
                    orientation: Gtk.Orientation.VERTICAL,
                    cssClasses: ["email-item"],
                });

                item.append(new Gtk.Label({
                    label: email.subject,
                    halign: Gtk.Align.START,
                    cssClasses: ["email-subject"],
                }));

                const meta = new Gtk.Box({ spacing: 8 });
                meta.append(new Gtk.Label({
                    label: email.sender,
                    cssClasses: ["email-sender"],
                }));
                meta.append(new Gtk.Label({
                    label: "·",
                    cssClasses: ["email-separator"],
                }));
                meta.append(new Gtk.Label({
                    label: email.date,
                    cssClasses: ["email-date"],
                }));
                item.append(meta);
                popoverList.append(item);
            }
        }
    }

    function refresh() {
        const parsed = readEmails();
        setEmails(parsed);
        updateButtonLabel();
        rebuildPopoverContent();
    }

    // Fetch script

    function fetchThenRefresh() {
        try {
            const proc = Gio.Subprocess.new(
                ["bash", SCRIPT_PATH],
                Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE,
            );
            proc.wait_async(null, (_proc: Gio.Subprocess, result: Gio.AsyncResult) => {
                try {
                    proc.wait_finish(result);
                } catch (e) {
                    console.error("email fetch script failed:", e);
                }
                refresh();
            });
        } catch (e) {
            console.error("failed to launch email fetch:", e);
            refresh(); // still read whatever cache exists
        }
    }

    // Build UI

    const root = new Gtk.Box({ cssClasses: ["email-bar"] });

    // Button showing icon + count
    const button = new Gtk.Button({ cssClasses: ["email-btn"] });
    btnLabel = new Gtk.Label({ label: "", cssClasses: ["email-label"] });
    button.set_child(btnLabel);
    root.append(button);

    // Create the popover container (vertical box)
    const popoverContent = new Gtk.Box({
        orientation: Gtk.Orientation.VERTICAL,
        spacing: 0,
        cssClasses: ["email-popover-content"],
    });

    // Thunderbird button
    const emailClientButton = new Gtk.Button({ cssClasses: ["email-client-button"] });
    emailClientButton.set_halign(Gtk.Align.END);
    const emailClientButtonLabel = new Gtk.Label({
        label: "Open Thunderbird",
        cssClasses: ["email-client-label"],
    });
    emailClientButton.set_child(emailClientButtonLabel);

    emailClientButton.connect("clicked", () => {
        try {
            Gio.Subprocess.new(
                ["thunderbird"],
                Gio.SubprocessFlags.NONE
            );
        } catch (e) {
            console.error("Failed to launch Thunderbird:", e);
        }
        popover?.popdown();
    });

    // Scrolled window for emails
    const scrolled = new Gtk.ScrolledWindow({
        vexpand: true,
        cssClasses: ["email-scroll"],
    });
    scrolled.set_max_content_height(400);
    scrolled.set_min_content_width(320);

    popoverList = new Gtk.Box({
        orientation: Gtk.Orientation.VERTICAL,
        spacing: 8,
        cssClasses: ["email-list"],
    });
    scrolled.set_child(popoverList);

    popoverContent.append(emailClientButton);
    popoverContent.append(scrolled);

    popover = new Gtk.Popover({
        autohide: true,
        has_arrow: false,
        cssClasses: ["email-popover"],
    });
    popover.set_parent(button);
    popover.set_child(popoverContent);

    button.connect("clicked", () => {
        if (popover!.is_visible()) {
            popover!.popdown();
        } else {
            popover!.popup();
        }
    });

    // Timer

    timerId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, REFRESH_SECONDS, () => {
        fetchThenRefresh();
        return GLib.SOURCE_CONTINUE;
    });

    root.connect("destroy", () => {
        if (timerId) GLib.Source.remove(timerId);
    });

    refresh();
    fetchThenRefresh();

    return root;
}
