"""
H1 — Console status (home). Replaces the old S1 category grid.

A status console, not a launcher: 8 pillar cards (4×2) that each answer
"is this OK?" first — a color-coded state verdict + a small detail line —
plus an action-queue strip that aggregates "what should I fix" at the top.

  status bar : AAhead Control wordmark · system indicator chips
  queue      : peach strip @ y54 (608×38), hidden when nothing needs a look
  grid       : 4×2 cards, 146×166, gutter 8, from y100 to y440
  footer     : A open · B quit · X fix · Y support

Navigation: D-pad moves focus across the grid. A opens a module (modules
not built yet show a coming-soon toast). X/Y are real buttons now.
"""

from __future__ import annotations

import pygame

from ..design import tokens as t
from ..shared import widgets as w
from ..shared import fonts, icons
from ..shared import backend

# ── grid geometry (640×480 stage) ────────────────────────────────────
Q_Y, Q_H = 54, 38
GRID_TOP, GRID_BOTTOM = 100, 440
COLS, ROWS = 4, 2
GAP = 8
CARD_W = (608 - GAP * (COLS - 1)) // COLS              # 146
CARD_H = (GRID_BOTTOM - GRID_TOP - GAP * (ROWS - 1)) // ROWS  # 166
COL_X = [16 + c * (CARD_W + GAP) for c in range(COLS)]
ROW_Y = [GRID_TOP + r * (CARD_H + GAP) for r in range(ROWS)]


class HomeScreen:
    name = "home"

    def __init__(self, app):
        self.app = app
        # (key, label, icon, state, detail, dot, state_level, tint)
        self.cards = [
            ("bluetooth", "Bluetooth", "ph-bluetooth", "Open to check",
             "USB audio", "off", "muted", "cyan"),
            ("wifi", "Wi-Fi", "ph-wifi-slash", "Open to check",
             "USB networking", "off", "muted", "cyan"),
            ("storage", "Storage", "ph-device-mobile", "Open to check",
             "SD card", "off", "muted", "mint"),
            ("input", "Controls", "ph-game-controller", "Ready",
             "Internal controls", "ok", "ok", "rose"),
            ("display", "Display", "ph-device-mobile", "Recognized",
             "R36S · 480p", "ok", "ok", "rose"),
            ("ports", "Ports", "ph-play-circle", "Not checked",
             "Open to scan", "off", "muted", "peach"),
            ("bios", "BIOS", "ph-file-text", "Not checked",
             "Open to scan", "off", "muted", "peach"),
            ("updates", "Updates", "ph-download-simple", "Manual check",
             "Open to check", "off", "muted", "rose"),
        ]
        self.focus = 0
        self.queue_msg = ""
        self.queue_count = 0
        self._load_status_snapshot()

    def _load_status_snapshot(self):
        env = backend.status()
        if not env or not env.get("ok"):
            backend.gui_log("home.snapshot_ignored", state=(env or {}).get("state"))
            return
        pillars = ((env.get("data") or {}).get("pillars") or {})
        if not pillars:
            return
        meta = {
            "bluetooth": ("Bluetooth", "ph-bluetooth", "cyan"),
            "wifi": ("Wi-Fi", "ph-wifi-slash", "cyan"),
            "storage": ("Storage", "ph-device-mobile", "mint"),
            "input": ("Controls", "ph-game-controller", "rose"),
            "display": ("Display", "ph-device-mobile", "rose"),
            "ports": ("Ports", "ph-play-circle", "peach"),
            "bios": ("BIOS", "ph-file-text", "peach"),
            "updates": ("Updates", "ph-download-simple", "rose"),
        }
        dots = {"ok": "ok", "warn": "warn", "err": "err", "error": "err", "off": "off", "muted": "off"}
        self.cards = [
            (
                key,
                label,
                icon,
                (pillars.get(key) or {}).get("state", "Not checked"),
                (pillars.get(key) or {}).get("detail", ""),
                dots.get((pillars.get(key) or {}).get("level", "muted"), "off"),
                (pillars.get(key) or {}).get("level", "muted"),
                tint,
            )
            for key, (label, icon, tint) in meta.items()
        ]
        queue = (env.get("data") or {}).get("queue") or {}
        self.queue_count = int(queue.get("count") or 0)
        self.queue_msg = queue.get("message") or ""
        backend.gui_log("home.snapshot_applied", queue_count=self.queue_count)

    # ── input ────────────────────────────────────────────────────────
    def on_action(self, action):
        r, c = divmod(self.focus, COLS)
        if action == "left":
            self.focus = r * COLS + max(0, c - 1)
        elif action == "right":
            self.focus = r * COLS + min(COLS - 1, c + 1)
        elif action == "up":
            self.focus = max(0, r - 1) * COLS + c
        elif action == "down":
            self.focus = min(ROWS - 1, r + 1) * COLS + c
        elif action == "a":
            self._open(self.cards[self.focus][0])
        elif action == "b":
            self.app.request_exit()
        elif action == "x":
            if self.queue_count:
                self.app.toast("Fix queue — coming soon")
        elif action == "y":
            from .support_report import SupportReportScreen
            self.app.push(SupportReportScreen(self.app))

    def _open(self, key):
        if key == "bluetooth":
            if backend.live_enabled():
                env = backend.bluetooth_status()
                data = (env or {}).get("data") or {}
                if env and not data.get("adapter_present"):
                    from .bt_states import S2bNoAdapter
                    self.app.push(S2bNoAdapter(self.app))
                    return
            from .bluetooth import BluetoothScreen
            self.app.push(BluetoothScreen(self.app))
        elif key == "wifi":
            # adapter-aware entry (mirrors the Bluetooth routing above): on a
            # live box pick the screen that matches reality; on dev (status
            # None) fall through to the demo hero.
            from .wifi import W1Home, W2Networks, W7Off, W9NoAdapter
            if backend.live_enabled() and backend.wifi_adapter_present() is False:
                self.app.push(W9NoAdapter(self.app))
                return
            st = backend.wifi_status()
            if st is None:
                self.app.push(W1Home(self.app))          # dev/mock → demo hero
            elif st.get("radio") is False:
                self.app.push(W7Off(self.app))           # radio is off
            elif st.get("connected"):
                self.app.push(W1Home(self.app))          # connected → real hero
            else:
                self.app.push(W2Networks(self.app))      # on, not connected → list
        elif key == "input":
            from .input import G1Controllers
            self.app.push(G1Controllers(self.app))
        elif key == "storage":
            from .storage import St1Storage
            self.app.push(St1Storage(self.app))
        elif key == "bios":
            from .bios import B1Bios
            self.app.push(B1Bios(self.app))
        elif key == "ports":
            from .ports import Pm1Ports
            self.app.push(Pm1Ports(self.app))
        elif key == "updates":
            from .updates import U1Updates
            self.app.push(U1Updates(self.app))
        elif key == "display":
            from .display import DisplayScreen
            self.app.push(DisplayScreen(self.app))
        else:
            self.app.toast(f"{key.capitalize()} — coming soon")

    def update(self, dt_ms):
        pass

    # ── draw ─────────────────────────────────────────────────────────
    def draw(self, surf):
        self._draw_status_bar(surf)
        if self.queue_count:
            w.action_queue(surf, pygame.Rect(16, Q_Y, 608, Q_H),
                           self.queue_msg, self.queue_count)
        for i, (key, label, icon, state, detail, dot, lvl, tint) in enumerate(self.cards):
            r, c = divmod(i, COLS)
            rect = pygame.Rect(COL_X[c], ROW_Y[r], CARD_W, CARD_H)
            w.status_card(surf, rect, icon_name=icon, label=label, state=state,
                          detail=detail, dot=dot, state_level=lvl, tint=tint,
                          focused=(i == self.focus))
        self._draw_footer(surf)

    def _draw_status_bar(self, surf):
        brand = w.brand_wordmark()
        surf.blit(brand, (t.Space.SAFE_AREA, (48 - brand.get_height()) // 2))
        rx = 640 - t.Space.SAFE_AREA
        clk = fonts.render(t.Type.MONO_TECH, "14:32", t.Color.TEXT_PRIMARY)
        rx -= clk.get_width(); surf.blit(clk, (rx, 18))
        rx -= t.Space.L
        batt = w.battery_chip(87)
        rx -= batt.get_width(); surf.blit(batt, (rx, 16))
        rx -= t.Space.L
        bt = icons.icon("ph-bluetooth", 16, t.Color.TEXT_SECONDARY)
        rx -= bt.get_width(); surf.blit(bt, (rx, 16))
        rx -= t.Space.M
        wf = icons.icon("ph-wifi-slash", 16, t.Color.TEXT_MUTED)
        rx -= wf.get_width(); surf.blit(wf, (rx, 16))

    def _draw_footer(self, surf):
        pygame.draw.line(surf, t.Color.BORDER_SOFT, (0, 448), (640, 448), 1)
        cy = 448 + t.Space.FOOTER_HINT_HEIGHT // 2
        # build cluster: (A)open (B)back/quit (X)fix (Y)support — "back" when
        # embedded as the shell's Settings section, "quit" when standalone
        b_label = "back" if getattr(self.app, "embedded", False) else "quit"
        items = []  # list of surfaces laid left→right within the cluster
        for g, lbl in (("A", "open"), ("B", b_label), ("X", "fix"), ("Y", "support")):
            items.append(("glyph", w._btn_glyph(g)))
            items.append(("label", fonts.render(t.Type.CAPTION, lbl, t.Color.TEXT_SECONDARY)))

        # spacing: tight within a hint, wide between hints
        gaps = []
        kinds = [k for k, _ in items]
        for i in range(len(items) - 1):
            k, nk = kinds[i], kinds[i + 1]
            if k == "glyph":
                gaps.append(8)
            elif k == "label":
                gaps.append(t.Space.XL)        # gap to next hint
            elif k == "pill" and nk == "plus":
                gaps.append(4)
            elif k == "plus":
                gaps.append(4)
            elif k == "pill" and nk == "label":
                gaps.append(8)
            else:
                gaps.append(8)
        total = sum(s.get_width() for _, s in items) + sum(gaps)
        x = (640 - total) // 2
        for i, (_, s) in enumerate(items):
            surf.blit(s, (x, cy - s.get_height() // 2))
            x += s.get_width() + (gaps[i] if i < len(gaps) else 0)


def _pill(text: str) -> pygame.Surface:
    """Small rounded key-cap for combo hints (SELECT / START)."""
    style = t.TextStyle(t.JETBRAINS_MONO, 9, "Regular", 0.5)
    lbl = fonts.render(style, text, t.Color.TEXT_SECONDARY)
    pw, ph = lbl.get_width() + 12, 18
    s = pygame.Surface((pw, ph), pygame.SRCALPHA)
    pygame.draw.rect(s, t.Color.TEXT_MUTED, (0, 0, pw, ph), width=1, border_radius=4)
    s.blit(lbl, ((pw - lbl.get_width()) // 2, (ph - lbl.get_height()) // 2))
    return s
