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

interface WeatherData {
    current: {
        temp: number;
        wind: number;
        icon: string;
    };
    today: {
        high: number;
        low: number;
        rain_pct: number;
        icon: string;
    };
    forecast: Array<{
        day: string;
        high: number;
        low: number;
        rain: number;
        icon: string;
    }>;
}

export default function WeatherWidget() {
    const cachePath = GLib.build_filenamev([
        GLib.get_user_cache_dir(),
        "ags",
        "weather.json",
    ]);

    // --- Current ---
    const currentIcon  = new Gtk.Label({ cssClasses: ["weather-current-icon"] });
    const currentTemp  = new Gtk.Label({ cssClasses: ["weather-current-temp"] });
    const currentWind  = new Gtk.Label({ cssClasses: ["weather-current-wind"] });

    // --- Today summary ---
    const todayIcon    = new Gtk.Label({ cssClasses: ["weather-today-icon"] });
    const todayHighLow = new Gtk.Label({ cssClasses: ["weather-today-highlow"] });
    const rainPill     = new Gtk.Label({ cssClasses: ["weather-rain-pill"] });

    // --- Forecast ---
    const forecastBox  = new Gtk.Box({
        orientation: Gtk.Orientation.HORIZONTAL,
        homogeneous: true,
        cssClasses: ["weather-forecast-box"],
    });

    function makeForecastDay(day: WeatherData["forecast"][number]) {
        const wrap = new Gtk.Box({
            orientation: Gtk.Orientation.VERTICAL,
            cssClasses: ["weather-forecast-day"],
        });

        wrap.append(new Gtk.Label({ label: day.day,  cssClasses: ["weather-forecast-label"] }));
        wrap.append(new Gtk.Label({ label: day.icon, cssClasses: ["weather-forecast-icon"] }));
        wrap.append(new Gtk.Label({
            label: `${Math.round(day.high)}° ${Math.round(day.low)}°`,
            cssClasses: ["weather-forecast-temps"],
        }));

        // Rain bar
        const barBg = new Gtk.Box({ cssClasses: ["weather-rain-bar-bg"], heightRequest: 4 });
        const barFg = new Gtk.Box({
            cssClasses: ["weather-rain-bar-fg"],
            heightRequest: 4,
            widthRequest: Math.round(day.rain * 0.6), // max ~60px at 100%
        });
        barBg.append(barFg);
        wrap.append(barBg);
        wrap.append(new Gtk.Label({
            label: `${day.rain}%`,
            cssClasses: ["weather-forecast-rain"],
        }));

        return wrap;
    }

    function updateDisplay(data: WeatherData) {
        // Current
        currentIcon.label  = data.current.icon;
        currentTemp.label  = `${Math.round(data.current.temp)}°`;
        currentWind.label  = `💨 ${data.current.wind} m/s`;

        // Today
        todayIcon.label    = data.today.icon;
        todayHighLow.label = `▲ ${Math.round(data.today.high)}°  ▼ ${Math.round(data.today.low)}°`;
        rainPill.label     = `🌧 ${data.today.rain_pct}%`;

        // Forecast
        let child = forecastBox.get_first_child();
        while (child) {
            const next = child.get_next_sibling();
            forecastBox.remove(child);
            child = next;
        }
        data.forecast.forEach(d => forecastBox.append(makeForecastDay(d)));
    }

    function readWeatherFile(): WeatherData | null {
        try {
            const file = Gio.File.new_for_path(cachePath);
            if (!file.query_exists(null)) return null;
            const [ok, contents] = file.load_contents(null);
            if (ok) return JSON.parse(new TextDecoder("utf-8").decode(contents));
        } catch (e) {
            log(`WeatherWidget: ${e}`);
        }
        return null;
    }

    const initial = readWeatherFile();
    if (initial) updateDisplay(initial);

    // Build the root widget
    const root = new Gtk.Box({
        orientation: Gtk.Orientation.VERTICAL,
        cssClasses: ["grid-card", "weather-card"],
        hexpand: true,
    });

    watchFile(cachePath, () => {
        const d = readWeatherFile();
        if (d) updateDisplay(d);
    }, root);

    // Build the UI structure
    const currentRow = new Gtk.Box({
        cssClasses: ["weather-current-row"],
        halign: Gtk.Align.CENTER,
    });
    currentRow.append(currentIcon);
    const currentInfoBox = new Gtk.Box({
        orientation: Gtk.Orientation.VERTICAL,
        valign: Gtk.Align.CENTER,
    });
    currentInfoBox.append(currentTemp);
    currentInfoBox.append(currentWind);
    currentRow.append(currentInfoBox);
    root.append(currentRow);

    root.append(new Gtk.Box({ vexpand: true }));

    const sep1 = new Gtk.Box({ cssClasses: ["weather-sep"], heightRequest: 1, hexpand: true });
    root.append(sep1);

    const todayRow = new Gtk.Box({
        cssClasses: ["weather-today-row"],
        halign: Gtk.Align.CENTER,
    });
    todayRow.append(todayIcon);
    const todayInfoBox = new Gtk.Box({
        orientation: Gtk.Orientation.VERTICAL,
        valign: Gtk.Align.CENTER,
    });
    todayInfoBox.append(todayHighLow);
    todayInfoBox.append(rainPill);
    todayRow.append(todayInfoBox);
    root.append(todayRow);

    root.append(new Gtk.Box({ vexpand: true }));

    const sep2 = new Gtk.Box({ cssClasses: ["weather-sep"], heightRequest: 1, hexpand: true });
    root.append(sep2);

    root.append(forecastBox);

    return root;
}