"""
Drivers — install the Bluetooth + Wi-Fi dongle drivers bundled with the CSR-BT
kernel fix. Reached from the Bluetooth settings ("Install BT + Wi-Fi drivers").

One-tap, console-free: A starts the install; the modules are copied into the
running kernel + depmod'd + loaded off the render thread (backend.call_async →
driversops, output captured), while AAhead renders its own progress / done /
reboot-needed modal. On a dev box (not live) it simulates the flow.
"""

from __future__ import annotations

import pygame

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

STAGE_W = t.VIEWPORT_WIDTH
STAGE_H = t.VIEWPORT_HEIGHT
SAFE = t.Space.SAFE_AREA


class DriversScreen:
    name = "drivers"

    def __init__(self, app):
        self.app = app
        self.phase = "idle"          # idle | running | done | error
        self.job = None
        self.result = None
        self.elapsed = 0.0
        self.status = backend.drivers_status()   # None on dev → generic copy

    # ── input ────────────────────────────────────────────────────────
    def on_action(self, action):
        if self.phase == "running":
            return
        if self.phase in ("done", "error"):
            if action in ("a", "b"):
                ok = self.phase == "done"
                self.phase = "idle"; self.job = None; self.result = None
                if ok:
                    self.app.pop()       # back to Bluetooth after a good install
            return
        if action == "a":
            self._begin()
        elif action == "b":
            self.app.pop()

    def _begin(self):
        self.phase = "running"
        self.elapsed = 0.0
        self.result = None
        self.job = None
        if backend.live_enabled():
            self.job = backend.call_async("drivers.install", backend.drivers_install)
        # not live → update() simulates

    def _resolve(self, res):
        if res is None:
            self.phase = "error"
            self.result = {"error": "couldn't start install"}
        elif res.get("ok"):
            self.phase = "done"
            self.result = res
        else:
            self.phase = "error"
            self.result = res

    def update(self, dt_ms):
        if self.phase != "running":
            return
        self.elapsed += dt_ms
        if self.job is not None:
            if self.job.done:
                self._resolve(self.job.result)
        elif self.elapsed >= 1800:        # dev simulation
            self._resolve({"ok": True, "wlan_up": True, "needs_reboot": False,
                           "count": 9})

    # ── draw ─────────────────────────────────────────────────────────
    def draw(self, surf):
        w.status_bar(surf, title="Drivers", back=True)

        # hero
        hero_y = 64
        gbox = 48
        box = render.rounded_gradient((gbox, gbox), t.Color.ACCENT_ROSE,
                                      t.Color.ACCENT_CYAN, 12, 135)
        box.blit(icons.icon("ph-download-simple", 26, t.Color.BG_MID),
                 ((gbox - 26) // 2, (gbox - 26) // 2))
        surf.blit(box, (SAFE, hero_y))
        tx = SAFE + gbox + 16
        title = fonts.render(t.Type.HERO, "BT + Wi-Fi drivers", t.Color.TEXT_PRIMARY)
        surf.blit(title, (tx, hero_y + 2))
        sub = fonts.render(t.Type.BODY, "Drivers for your Bluetooth and Wi-Fi dongles.",
                           t.Color.TEXT_SECONDARY)
        surf.blit(sub, (tx, hero_y + 2 + title.get_height() + 6))

        # status strip (real when live)
        y = hero_y + 84
        lines = self._status_lines()
        for i, (label, val, col) in enumerate(lines):
            ly = y + i * 22
            ls = fonts.render(t.Type.BODY_SM, label, t.Color.TEXT_MUTED)
            surf.blit(ls, (SAFE + 2, ly))
            vs = fonts.render(t.Type.BODY_SM, val, col)
            surf.blit(vs, (SAFE + 180, ly))

        # explanatory note
        note_y = y + len(lines) * 22 + 10
        for i, ln in enumerate([
            "Installs the bundled kernel modules, then loads them.",
            "If Wi-Fi doesn't appear right away, a reboot finishes it.",
        ]):
            n = fonts.render(t.Type.BODY_SM, ln, t.Color.TEXT_SECONDARY)
            surf.blit(n, (SAFE + 2, note_y + i * 20))

        # CTA
        btn_w, btn_h = 260, 46
        brect = pygame.Rect((STAGE_W - btn_w) // 2, STAGE_H - 92, btn_w, btn_h)
        w.button(surf, brect, "Install now", icon_name="ph-download-simple",
                 focused=True)

        w.footer_hints(surf, [("A", "install"), ("B", "back")])

        if self.phase != "idle":
            self._draw_modal(surf)

    def _status_lines(self):
        s = self.status
        if not s:
            return [("status", "ready to install (preview)", t.Color.TEXT_SECONDARY)]
        return [
            ("driver package", "found on card" if s.get("package_present")
             else "not found", t.Color.SUCCESS if s.get("package_present")
             else t.Color.WARNING),
            ("installed", "yes" if s.get("installed") else "no",
             t.Color.SUCCESS if s.get("installed") else t.Color.TEXT_SECONDARY),
            ("Wi-Fi adapter", "up" if s.get("wlan_up") else "not detected",
             t.Color.SUCCESS if s.get("wlan_up") else t.Color.WARNING),
        ]

    def _draw_modal(self, surf):
        """In-UI progress/result — no console; install runs off-thread."""
        w.scrim(surf, alpha=0.55)
        cw, ch = 400, 188
        rect = pygame.Rect((STAGE_W - cw) // 2, (STAGE_H - ch) // 2, cw, ch)
        w.modal_card(surf, rect)
        surf.blit(render.gradient_border((cw, ch), t.Radius.CARD), rect.topleft)
        cx = rect.centerx
        pad = 24

        if self.phase == "running":
            w.conic_ring(surf, cx, rect.y + 52, 18,
                         (self.elapsed % 1100) / 1100, thickness=4)
            title = fonts.render(t.Type.TITLE, "Installing drivers…",
                                 t.Color.TEXT_PRIMARY)
            surf.blit(title, (cx - title.get_width() // 2, rect.y + 80))
            sub = fonts.render(t.Type.BODY_SM, "copying modules · loading",
                               t.Color.TEXT_SECONDARY)
            surf.blit(sub, (cx - sub.get_width() // 2, rect.y + 80 + 26))
            note = fonts.render(t.Type.META_SM, "keep the device powered",
                                t.Color.TEXT_MUTED)
            surf.blit(note, (cx - note.get_width() // 2, rect.bottom - pad - 4))
            return

        ok = self.phase == "done"
        col = t.Color.SUCCESS if ok else t.Color.ERROR
        ic = icons.icon("ph-check-circle" if ok else "ph-warning-circle", 34, col)
        surf.blit(ic, (cx - ic.get_width() // 2, rect.y + 24))
        if ok:
            up = (self.result or {}).get("wlan_up")
            head = "Wi-Fi ready" if up else "Drivers installed"
            detail = ("Open Wi-Fi to connect." if up
                      else "Reboot to finish — then Wi-Fi will appear.")
        else:
            head = "Install failed"
            detail = (self.result or {}).get("error") or "something went wrong"
        ht = fonts.render(t.Type.TITLE, head, col)
        surf.blit(ht, (cx - ht.get_width() // 2, rect.y + 64))
        ds = fonts.render(t.Type.BODY_SM, detail, t.Color.TEXT_SECONDARY)
        if ds.get_width() > cw - pad * 2:
            ds = ds.subsurface((0, 0, cw - pad * 2, ds.get_height()))
        surf.blit(ds, (cx - ds.get_width() // 2, rect.y + 64 + 28))
        hint = fonts.render(t.Type.META_SM, "A  continue", t.Color.ACCENT_CYAN)
        surf.blit(hint, (cx - hint.get_width() // 2, rect.bottom - pad - 4))
