"""Weather quad: wttr.in rendered with its original ANSI/CLI art (via AnsiRenderer).

Reuses the shared LocationService for the city; if none is known yet, wttr.in
geolocates the caller's IP itself, so the widget still works standalone. The
'ascii_art' feature toggle swaps the art for a compact one-line text summary.
"""

from __future__ import annotations

import gi

gi.require_version("Gtk", "4.0")
from gi.repository import Gtk  # noqa: E402

from lib.ansi import AnsiRenderer
from lib.proc import run_text
from module_base import Feature, ModuleContext, ModuleInstance, ModuleSpec
from paths import BACKEND_DIR

_SCRIPT = str(BACKEND_DIR / "weather.sh")


class _WeatherView(Gtk.Box):
    def __init__(self, ctx: ModuleContext, opts: str):
        super().__init__(orientation=Gtk.Orientation.VERTICAL)
        self.add_css_class("weather-view")
        self.ctx = ctx
        self.opts = opts
        self._loc = ""

        self.renderer = AnsiRenderer()
        self.append(self.renderer.view)
        self._status = Gtk.Label(label="Loading weather…")
        self._status.add_css_class("weather-status")
        self.append(self._status)

        ctx.services.location.subscribe(self._on_location)
        self.refresh()

    def _on_location(self, data: dict) -> None:
        self._loc = data.get("city") or ""
        self.refresh()

    def refresh(self) -> None:
        art = self.ctx.feature("ascii_art", True)
        opts = self.opts if art else "format=%l:+%c+%t,+%w"
        run_text([_SCRIPT, self._loc, opts], self._on_result)

    def _on_result(self, ok: bool, out: str, err: str) -> None:
        if ok and out.strip() and "<html" not in out.lower():
            self.renderer.set_text(out.rstrip("\n"))
            self._status.set_visible(False)
        else:
            self._status.set_text("Weather unavailable")
            self._status.set_visible(True)


def build(ctx: ModuleContext) -> ModuleInstance:
    # The ascii_art toggle rebuilds the whole card via QuadCard, so both views are
    # recreated and re-fetch with the current format — no partial refresh here.
    compact = _WeatherView(ctx, opts="0")        # current conditions only
    expanded = _WeatherView(ctx, opts="")        # full 3-day forecast
    return ModuleInstance(compact=compact, expanded=expanded)


SPEC = ModuleSpec(
    id="weather",
    title="Weather",
    icon="",  # nf-weather
    build=build,
    features=[Feature("ascii_art", "CLI art", True)],
)
