import { Gtk } from "ags/gtk4";
import { createState } from "ags";
import GLib from "gi://GLib";
import Gio from "gi://Gio";
import { watchFile } from "../../lib/fileMonitor";

type FeedItem = {
    title: string;
    link: string;
    date: string;
    summary: string;
    author: string;
    feed_title: string;
    tag: string;
};

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

export default function RSSList() {
    const [items, setItems] = createState<FeedItem[]>([]);
    let listContainer: Gtk.Box | null = null;

    function readItemsFromCache(): FeedItem[] {
        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((item: any) => ({
                title: item.title || "(untitled)",
                link: item.link || "",
                date: item.date ? formatDate(item.date) : "",
                summary: item.summary || "",
                author: item.author || "",
                feed_title: item.feed_title || "",
                tag: item.tag || "",
            }));
        } catch (err) {
            console.error("Failed to read RSS cache", err);
            return [];
        }
    }

    function formatDate(iso: string): string {
        try {
            const d = new Date(iso);
            const now = new Date();
            const diff = now.getTime() - d.getTime();
            const hours = Math.floor(diff / (1000 * 60 * 60));

            if (hours < 1) return "just now";
            if (hours < 24) return `${hours}h ago`;
            if (hours < 48) return "yesterday";
            return d.toLocaleDateString();
        } catch {
            return iso;
        }
    }

    function rebuildList() {
        if (!listContainer) return;

        let child = listContainer.get_first_child();
        while (child) {
            const next = child.get_next_sibling();
            listContainer.remove(child);
            child = next;
        }

        const currentItems = items();
        if (currentItems.length === 0) {
            const emptyBox = new Gtk.Box({
                halign: Gtk.Align.CENTER,
                cssClasses: ["status-box"],
            });
            emptyBox.append(new Gtk.Label({ label: "📰", cssClasses: ["empty-icon"] }));
            emptyBox.append(new Gtk.Label({ label: "No feed items", cssClasses: ["status-text"] }));
            listContainer.append(emptyBox);
        } else {
            for (const item of currentItems) {
                const entry = new Gtk.Box({
                    orientation: Gtk.Orientation.VERTICAL,
                    cssClasses: ["rss-item"],
                });

                // Title
                const titleLabel = new Gtk.Label({
                    label: item.title,
                    halign: Gtk.Align.START,
                    hexpand: false,
                    cssClasses: ["rss-title"],
                    wrap: true,
                    wrapMode: 2,
                });
                entry.append(titleLabel);

                // Meta: tag badge, feed title, date
                const meta = new Gtk.Box({ spacing: 8, cssClasses: ["rss-meta"] });
                if (item.tag) {
                    const tagBadge = new Gtk.Label({
                        label: item.tag,
                        cssClasses: ["rss-tag", `rss-tag-${item.tag}`],
                    });
                    meta.append(tagBadge);
                }
                meta.append(new Gtk.Label({
                    label: item.feed_title,
                    cssClasses: ["rss-feed-title"],
                }));
                meta.append(new Gtk.Label({
                    label: "•",
                    cssClasses: ["rss-separator"],
                }));
                meta.append(new Gtk.Label({
                    label: item.date,
                    cssClasses: ["rss-date"],
                }));
                entry.append(meta);

                // Summary (truncated)
                if (item.summary) {
                    const maxLen = 160;
                    const text = item.summary.length <= maxLen
                        ? item.summary
                        : item.summary.slice(0, maxLen).trimEnd() + "…";
                    const summaryLabel = new Gtk.Label({
                        label: text,
                        halign: Gtk.Align.START,
                        cssClasses: ["rss-summary"],
                        wrap: true,
                        wrapMode: 2,
                    });
                    entry.append(summaryLabel);
                }

                // Make clickable if link exists
                if (item.link) {
                    entry.add_css_class("rss-item-link");
                    const gesture = new Gtk.GestureClick();
                    gesture.connect("pressed", () => {
                        GLib.spawn_command_line_async(`xdg-open '${item.link.replace(/'/g, "'\''")}'`);
                    });
                    entry.add_controller(gesture);
                }

                listContainer.append(entry);
            }
        }
    }

    function updateDisplay() {
        const parsed = readItemsFromCache();
        setItems(parsed);
        rebuildList();
    }

    const root = new Gtk.Box({
        orientation: Gtk.Orientation.VERTICAL,
        cssClasses: ["rss-list-container"],
        widthRequest: 300,
    });

    const scrolled = new Gtk.ScrolledWindow({
        vexpand: true,
        cssClasses: ["rss-scroll", "grid-card"],
    });
    listContainer = new Gtk.Box({
        orientation: Gtk.Orientation.VERTICAL,
        spacing: 12,
        hexpand: true,
        cssClasses: ["rss-list"],
    });
    scrolled.set_child(listContainer);
    root.append(scrolled);

    updateDisplay();
    watchFile(CACHE_FILE, updateDisplay, root);

    return root;
}
