"""Onglet « À propos » de la GUI V6 (G4 — alignement maquette).

Grille d'informations (agrid) + bloc licence (activation par clef, vérification).
La logique licence est inchangée : aucun token journalisé, aucun appel réseau au
démarrage (seul ``local_status`` est lu).
"""

from __future__ import annotations

from tkinter import messagebox
from typing import Optional

import customtkinter as ctk

from gui_v6 import __version__ as GUI_VERSION
from gui_v6 import theme as theme_mod
from gui_v6 import ui_kit
from gui_v6.license_client import LicenseClient, LicenseStatus
from gui_v6.machine_id import default_machine_id

_HELP_ABOUT = (
    "Cet écran affiche la version de l'application, les moteurs utilisés et "
    "l'identifiant de ce poste.\n\n"
    "La licence s'active avec une clef fournie par votre administrateur. "
    "L'activation se fait sans envoyer aucun document : seule la clef est vérifiée.\n\n"
    "Le traitement des documents reste 100 % local sur ce poste."
)

_STATUS_LABELS = {
    "active": "Licence active",
    "grace": "Licence en période de grâce",
    "expired": "Licence expirée",
    "revoked": "Poste révoqué",
    "invalid": "Licence invalide",
    "unavailable": "Serveur de licence indisponible",
    "autre_poste": "Licence liée à un autre poste",
    "none": "Aucune licence",
}

_UPDATE_CHECK_MESSAGE = (
    "Aucune version publiée n'a été trouvée sur le portail.\n\n"
    "Vérifiez que le serveur web est joignable ou contactez votre administrateur."
)


def _build_info() -> str:
    try:
        import build_info  # type: ignore

        return f"{getattr(build_info, 'BUILD_COMMIT', '?')} ({getattr(build_info, 'BUILD_BRANCH', '?')})"
    except Exception:
        return "indisponible"


class AboutTab(ctk.CTkFrame):
    def __init__(
        self,
        master,
        status: Optional[LicenseStatus] = None,
        theme_name: str = theme_mod.DEFAULT_THEME,
        license_client: Optional[LicenseClient] = None,
        palette: dict | None = None,
        **kwargs,
    ) -> None:
        self._p = palette or theme_mod.get_palette(theme_name)
        super().__init__(master, fg_color=self._p["bg"], **kwargs)
        self._theme_name = theme_name
        self._client = license_client
        self._machine_id = default_machine_id()
        self._status = status or LicenseStatus.none()
        self._build()

    def _build(self) -> None:
        p = self._p

        # Bandeau d'introduction + aide « ? »
        intro = ctk.CTkFrame(self, fg_color="transparent")
        intro.pack(fill="x", padx=14, pady=(12, 0))
        ctk.CTkLabel(
            intro,
            text="Informations sur l'application et activation de votre licence.",
            text_color=p["text_dim"],
            font=ui_kit.font(12),
            anchor="w",
        ).pack(side="left", padx=(2, 6))
        ui_kit.help_button(intro, p, _HELP_ABOUT, title="À propos / Licence").pack(side="right", padx=2)

        # Grille d'informations
        info = ui_kit.Card(self, p, title="ℹ️ Informations")
        info.pack(fill="x", padx=14, pady=(14, 7))
        grid = ctk.CTkFrame(info, fg_color="transparent")
        grid.pack(fill="x", padx=16, pady=(0, 14))
        items = [
            ("🏷️", "Version", f"Interface V6 — {GUI_VERSION}"),
            ("📅", "Build", _build_info()),
            ("🧠", "Moteurs NER", "CamemBERT inclus · EDS/GLiNER optionnels non embarqués"),
            ("🔒", "Traitement", "100 % local — aucune donnée transmise"),
            ("📚", "Bases de données", "INSEE 219K · FINESS 108K · BDPM 7K"),
            ("📁", "Formats", "PDF · DOCX · ODT · RTF · TXT · Images"),
            ("🖥️", "Poste", self._machine_id),
        ]
        for col in (0, 1):
            grid.grid_columnconfigure(col, weight=1)
        for idx, (icon, key, val) in enumerate(items):
            cell = ctk.CTkFrame(grid, fg_color="transparent")
            cell.grid(row=idx // 2, column=idx % 2, sticky="w", padx=4, pady=5)
            ctk.CTkLabel(cell, text=icon, font=ui_kit.font(18)).pack(side="left", padx=(0, 8))
            txt = ctk.CTkFrame(cell, fg_color="transparent")
            txt.pack(side="left")
            ctk.CTkLabel(txt, text=key.upper(), text_color=p["text_muted"], font=ui_kit.font(10), anchor="w").pack(anchor="w")
            ctk.CTkLabel(txt, text=val, text_color=p["text"], font=ui_kit.font(12, "bold"), anchor="w").pack(anchor="w")
        ui_kit.secondary_button(info, p, "🔄 Rechercher une mise à jour", command=self._check_updates).pack(
            anchor="w", padx=16, pady=(0, 14)
        )

        # Bloc licence
        lic = ui_kit.Card(self, p, title="🔑 Licence")
        lic.pack(fill="x", padx=14, pady=7)
        self._status_label = ctk.CTkLabel(lic, text="", text_color=p["text"], font=ui_kit.font(13), anchor="w", justify="left")
        self._status_label.pack(anchor="w", padx=16, pady=(0, 8))
        block = ctk.CTkFrame(lic, fg_color="transparent")
        block.pack(fill="x", padx=16, pady=(0, 14))
        self._key_entry = ctk.CTkEntry(block, width=240, placeholder_text="Clef d'activation",
                                       fg_color=p["btn_sec_bg"], border_color=p["btn_sec_border"], text_color=p["text"])
        self._key_entry.pack(side="left", padx=(0, 8))
        self._activate_btn = ui_kit.primary_button(block, p, "Activer", command=self._activate)
        self._activate_btn.pack(side="left", padx=(0, 8))
        self._check_btn = ui_kit.secondary_button(block, p, "Vérifier", command=self._check)
        self._check_btn.pack(side="left")
        if self._client is None:
            self._activate_btn.configure(state="disabled")
            self._check_btn.configure(state="disabled")

        self.set_status(self._status)

    def set_status(self, status: LicenseStatus) -> None:
        self._status = status
        label = _STATUS_LABELS.get(status.status, status.status)
        text = f"État : {label}"
        if status.expires_at:
            text += f"  ·  expire le {status.expires_at}"
        if status.message:
            text += f"\n{status.message}"
        self._status_label.configure(text=text, text_color=theme_mod.status_color(self._theme_name, status.status))

    def _activate(self) -> None:
        if self._client is None:
            return
        token = self._key_entry.get().strip()
        if not token:
            return
        status = self._client.activate(token, self._machine_id)
        self.set_status(status)
        self._key_entry.delete(0, "end")

    def _check(self) -> None:
        if self._client is None:
            return
        ref = self._status.license_ref
        if not ref:
            self.set_status(LicenseStatus.none("Aucune licence à vérifier"))
            return
        self.set_status(self._client.check(ref, self._machine_id))

    def _check_updates(self) -> None:
        if self._client is None:
            messagebox.showinfo("Mise à jour", _UPDATE_CHECK_MESSAGE)
            return
        payload = self._client.latest_version()
        if not payload:
            messagebox.showinfo("Mise à jour", _UPDATE_CHECK_MESSAGE)
            return
        version = str(payload.get("version") or "version inconnue")
        channel = str(payload.get("channel") or "canal non précisé")
        filename = str(payload.get("filename") or "fichier non précisé")
        messagebox.showinfo(
            "Mise à jour",
            f"Version publiée : {version}\nCanal : {channel}\nFichier : {filename}",
        )
