"""Generated application stylesheet — the Qt analog of the brand CSS kit.

:func:`build_qss` assembles the app-wide stylesheet from a
:class:`~mgf.brand_qt.tokens.SemanticColors` theme instance.
Qt has no CSS custom properties, so this module plays the role the
generated ``global-tokens.css`` + ``base.css`` play on the web: every
colour is interpolated from tokens — **no raw hex may appear in this
module** (enforced by the palette-lint test).

Chrome zones (widgets carrying the ``mgfChrome`` dynamic property)
stay Ink/Mist in BOTH themes — "it is an instrument" (00-brand §5/§6).

This module is Qt-free (pure string assembly) so it unit-tests
without PySide6. Widgets opt into variants via ``mgf*`` dynamic
properties (see :mod:`mgf.brand_qt.widgets.props`), declared
either in ``.ui`` files (``stdset="0"``) or at runtime.
"""

from __future__ import annotations

from mgf.brand_qt._mix import _channels
from mgf.brand_qt.tokens import (
    BUTTON_ACCENT_HOVER,
    BUTTON_PRIMARY_HOVER,
    FONT_DISPLAY,
    FONT_MONO,
    RADIUS,
    RAW,
    STATE_HUES,
    SemanticColors,
)

#: The complete ``mgf*`` dynamic-property vocabulary this stylesheet
#: selects on — key (without the ``mgf`` prefix) → the closed set of
#: values that have selectors. :func:`mgf.brand_qt.widgets.set_mgf`
#: validates against this map (PAPER-10: a key or value outside the
#: vocabulary styles nothing, so it is a defect, not a preference).
#: New vocabulary lands HERE first — a selector without a registry row
#: (or vice versa) is pinned by the kit's own tests.
MGF_PROPS: dict[str, frozenset[str]] = {
    "Accent": frozenset({"true", "false"}),
    "Chip": frozenset({"true", "false"}),
    "Chrome": frozenset({"true", "false"}),
    "Class": frozenset(
        {
            "emptyState",
            "errorText",
            "eyebrow",
            "hint",
            "ledger",
            "ledgerAccent",
            "ledgerKey",
            "pageTitle",
            "railKind",
            "sectionTitle",
            "statLabel",
            "statTile",
            "statValue",
            "strongLabel",
        }
    ),
    "State": frozenset(STATE_HUES),
    "Variant": frozenset({"accent", "danger", "primary"}),
}


def _chip_rules(sem: SemanticColors) -> str:
    """Per-state chip surfaces (tint bg, strong text, soft hue border)."""
    tints = {
        "success": sem.status_success_tint,
        "warning": sem.status_warning_tint,
        "error": sem.status_error_tint,
        "info": sem.status_info_tint,
        "busy": sem.state_busy_tint,
        "derived": sem.state_derived_tint,
        "neutral": sem.bg_muted,
        "quarantine": sem.state_derived_tint,
    }
    strongs = {
        "success": sem.status_success_strong,
        "warning": sem.status_warning_strong,
        "error": sem.status_error_strong,
        "info": sem.status_info_strong,
        "busy": sem.state_busy_strong,
        "derived": sem.state_derived_strong,
        "neutral": sem.text_secondary,
        "quarantine": sem.state_derived_strong,
    }
    rules = [
        """
        QFrame[mgfChip="true"] {
            border-radius: 999px;
            border: 1px solid transparent;
        }
        """
    ]
    for state, hue in STATE_HUES.items():
        rules.append(
            f"""
        QFrame[mgfChip="true"][mgfState="{state}"] {{
            background: {tints[state]};
            border-color: {_rgba(hue, 0.45)};
        }}
        QFrame[mgfChip="true"][mgfState="{state}"] QLabel {{
            background: transparent;
            color: {strongs[state]};
        }}
        """
        )
    return "\n".join(r.strip() for r in rules)


def _rgba(color: str, alpha: float) -> str:
    """Render a ``#rrggbb`` token at ``alpha`` as a QSS ``rgba()`` literal."""
    r, g, b = _channels(color)
    return f"rgba({r},{g},{b},{alpha})"


def build_qss(sem: SemanticColors, *, chrome_ink: str, chrome_text: str) -> str:
    """Build the full application stylesheet for one resolved theme.

    ``chrome_ink`` / ``chrome_text`` are the theme-invariant instrument
    colours (Ink / Mist) passed in by the theme engine so this module
    needs no direct raw-palette access.
    """
    radius_input = RADIUS["sm"]
    radius_button = RADIUS["md"]
    text_disabled = (
        _rgba(sem.text_primary, 0.4) if sem.text_primary.startswith("#") else sem.text_primary
    )
    border_disabled = (
        _rgba(sem.border_strong, 0.3) if sem.border_strong.startswith("#") else sem.border_strong
    )

    sections = [
        # ── canvas ───────────────────────────────────────────────────
        f"""
        QMainWindow, QDialog, QWizard {{
            background: {sem.bg_canvas};
        }}
        """,
        # ── text inputs ──────────────────────────────────────────────
        f"""
        QLineEdit, QComboBox, QSpinBox, QDoubleSpinBox, QTextEdit, QPlainTextEdit {{
            background: {sem.bg_surface};
            color: {sem.text_primary};
            border: 1px solid {sem.border_strong};
            border-radius: {radius_input}px;
            padding: 4px 8px;
            selection-background-color: {sem.link};
            selection-color: {sem.text_inverse};
        }}
        QLineEdit:focus, QComboBox:focus, QSpinBox:focus, QDoubleSpinBox:focus,
        QTextEdit:focus, QPlainTextEdit:focus {{
            border: 2px solid {sem.focus_ring};
            padding: 3px 7px;
        }}
        QLineEdit:disabled, QComboBox:disabled, QSpinBox:disabled,
        QDoubleSpinBox:disabled, QTextEdit:disabled, QPlainTextEdit:disabled {{
            color: {text_disabled};
            border-color: {border_disabled};
        }}
        """,
        # ── buttons (default = secondary variant; more variants in C2) ─
        f"""
        QPushButton {{
            background: transparent;
            color: {sem.action_secondary_text};
            border: 1px solid {sem.border_strong};
            border-radius: {radius_button}px;
            padding: 6px 16px;
            font-weight: 600;
        }}
        QPushButton:hover {{
            background: {sem.bg_muted};
        }}
        QPushButton:pressed {{
            background: {sem.border_subtle};
        }}
        QPushButton:focus {{
            border: 2px solid {sem.focus_ring};
            padding: 5px 15px;
        }}
        QPushButton:disabled {{
            color: {text_disabled};
            border-color: {border_disabled};
        }}
        """,
        # ── button variants (D7; gold = max one per view) ────────────
        f"""
        QPushButton[mgfVariant="primary"] {{
            background: {RAW.indigo};
            color: {RAW.paper};
            border: 1px solid {sem.border_strong};
        }}
        QPushButton[mgfVariant="primary"]:hover {{
            background: {BUTTON_PRIMARY_HOVER};
        }}
        QPushButton[mgfVariant="accent"] {{
            background: {RAW.gold};
            color: {RAW.ink};
            border: 1px solid {RAW.gold};
        }}
        QPushButton[mgfVariant="accent"]:hover {{
            background: {BUTTON_ACCENT_HOVER};
            border-color: {BUTTON_ACCENT_HOVER};
        }}
        QPushButton[mgfVariant="danger"] {{
            background: transparent;
            color: {sem.status_error_strong};
            border: 1px solid {sem.status_error_strong};
        }}
        QPushButton[mgfVariant="danger"]:hover {{
            background: {sem.status_error_bg};
            color: {sem.status_error_text};
            border-color: {sem.status_error_bg};
        }}
        QPushButton[mgfVariant]:disabled {{
            background: transparent;
            color: {text_disabled};
            border: 1px solid {border_disabled};
        }}
        """,
        # ── label classes ────────────────────────────────────────────
        f"""
        QLabel[mgfClass="hint"] {{
            color: {sem.text_secondary};
        }}
        QLabel[mgfClass="errorText"] {{
            color: {sem.status_error_strong};
        }}
        QLabel[mgfClass="strongLabel"] {{
            font-weight: 600;
        }}
        QLabel[mgfClass="sectionTitle"] {{
            font-family: "{FONT_DISPLAY}";
            font-size: 13pt;
            font-weight: 600;
        }}
        QLabel[mgfClass="pageTitle"] {{
            font-family: "{FONT_DISPLAY}";
            font-size: 16pt;
            font-weight: 600;
        }}
        QLabel[mgfClass="eyebrow"] {{
            font-family: "{FONT_MONO}";
            font-size: 8pt;
            font-weight: 500;
            color: {sem.text_secondary};
        }}
        QLabel[mgfClass="statValue"] {{
            font-family: "{FONT_MONO}";
            font-size: 18pt;
            font-weight: 600;
        }}
        QLabel[mgfClass="statLabel"] {{
            font-family: "{FONT_MONO}";
            font-size: 8pt;
            color: {sem.text_secondary};
        }}
        """,
        # ── chips / stat tiles / empty states (C5 widgets) ───────────
        _chip_rules(sem),
        f"""
        QFrame[mgfClass="statTile"] {{
            background: {sem.bg_surface_raised};
            border: 1px solid {sem.border_subtle};
            border-left: 3px solid {sem.border_strong};
            border-radius: {RADIUS["lg"]}px;
        }}
        QFrame[mgfClass="statTile"][mgfAccent="true"] {{
            border-left: 3px solid {RAW.gold};
        }}
        QFrame[mgfClass="statTile"] QLabel {{
            background: transparent;
        }}
        QWidget[mgfClass="emptyState"] {{
            border: 1px dashed {sem.border_strong};
            border-radius: {RADIUS["lg"]}px;
        }}
        """,
        # ── item views + headers ─────────────────────────────────────
        f"""
        QTableView, QTreeView, QListView {{
            background: {sem.bg_surface};
            color: {sem.text_primary};
            border: 1px solid {sem.border_subtle};
            border-radius: {RADIUS["sm"]}px;
            gridline-color: transparent;
            selection-background-color: {sem.bg_muted};
            selection-color: {sem.text_primary};
            alternate-background-color: {sem.bg_muted};
        }}
        QTableView::item, QTreeView::item, QListView::item {{
            padding: 4px 8px;
        }}
        QTableView:focus, QTreeView:focus, QListView:focus {{
            border: 1px solid {sem.focus_ring};
        }}
        QHeaderView::section {{
            background: transparent;
            color: {sem.text_secondary};
            border: none;
            border-bottom: 1px solid {sem.border_strong};
            padding: 6px 10px;
            font-family: "{FONT_MONO}";
            font-size: 8pt;
            font-weight: 500;
        }}
        QTableCornerButton::section {{
            background: transparent;
            border: none;
        }}
        """,
        # ── tabs (active = gold underline) ───────────────────────────
        f"""
        QTabWidget::pane {{
            border: 1px solid {sem.border_subtle};
            border-radius: {RADIUS["sm"]}px;
        }}
        QTabBar::tab {{
            background: transparent;
            color: {sem.text_secondary};
            padding: 8px 16px;
            border: none;
            border-bottom: 2px solid transparent;
        }}
        QTabBar::tab:selected {{
            color: {sem.text_primary};
            font-weight: 600;
            border-bottom: 2px solid {RAW.gold};
        }}
        QTabBar::tab:hover:!selected {{
            color: {sem.text_primary};
        }}
        """,
        # ── scrollbars (slim, quiet) ─────────────────────────────────
        f"""
        QScrollBar:vertical {{
            background: transparent;
            width: 10px;
            margin: 0;
        }}
        QScrollBar:horizontal {{
            background: transparent;
            height: 10px;
            margin: 0;
        }}
        QScrollBar::handle {{
            background: {sem.border_strong};
            border-radius: 5px;
        }}
        QScrollBar::handle:vertical {{
            min-height: 24px;
        }}
        QScrollBar::handle:horizontal {{
            min-width: 24px;
        }}
        QScrollBar::add-line, QScrollBar::sub-line {{
            height: 0;
            width: 0;
        }}
        QScrollBar::add-page, QScrollBar::sub-page {{
            background: transparent;
        }}
        """,
        # ── progress (teal chunk) ────────────────────────────────────
        f"""
        QProgressBar {{
            background: {sem.bg_muted};
            color: {sem.text_primary};
            border: 1px solid {sem.border_subtle};
            border-radius: {RADIUS["sm"]}px;
            text-align: center;
            font-family: "{FONT_MONO}";
            font-size: 8pt;
        }}
        QProgressBar::chunk {{
            background: {RAW.teal};
            border-radius: {RADIUS["sm"] - 1}px;
        }}
        """,
        # ── group boxes (eyebrow-style titles) ───────────────────────
        f"""
        QGroupBox {{
            border: 1px solid {sem.border_subtle};
            border-radius: {RADIUS["md"]}px;
            margin-top: 12px;
            padding-top: 8px;
        }}
        QGroupBox::title {{
            subcontrol-origin: margin;
            left: 12px;
            padding: 0 4px;
            color: {sem.text_secondary};
            font-family: "{FONT_MONO}";
            font-size: 8pt;
            font-weight: 500;
        }}
        """,
        # ── check / radio indicators ─────────────────────────────────
        f"""
        QCheckBox, QRadioButton {{
            color: {sem.text_primary};
            spacing: 6px;
        }}
        QCheckBox::indicator, QRadioButton::indicator {{
            width: 16px;
            height: 16px;
            border: 1px solid {sem.border_strong};
            border-radius: 4px;
            background: {sem.bg_surface};
        }}
        QRadioButton::indicator {{
            border-radius: 8px;
        }}
        QCheckBox::indicator:checked, QRadioButton::indicator:checked {{
            background: {RAW.teal};
            border-color: {RAW.teal};
        }}
        QCheckBox::indicator:disabled, QRadioButton::indicator:disabled {{
            border-color: {border_disabled};
        }}
        """,
        # ── menus / status bar / tooltips ────────────────────────────
        f"""
        QMenuBar {{
            background: {sem.bg_canvas};
            color: {sem.text_primary};
        }}
        QMenuBar::item:selected {{
            background: {sem.bg_muted};
        }}
        QMenu {{
            background: {sem.bg_surface};
            color: {sem.text_primary};
            border: 1px solid {sem.border_strong};
        }}
        QMenu::item {{
            padding: 6px 24px;
        }}
        QMenu::item:selected {{
            background: {sem.bg_muted};
        }}
        QMenu::separator {{
            height: 1px;
            background: {sem.border_subtle};
            margin: 4px 8px;
        }}
        QStatusBar {{
            background: {sem.bg_canvas};
            color: {sem.text_secondary};
        }}
        QToolTip {{
            background: {sem.bg_surface};
            color: {sem.text_primary};
            border: 1px solid {sem.border_strong};
            padding: 4px 8px;
        }}
        """,
        # ── structure ────────────────────────────────────────────────
        f"""
        QSplitter::handle {{
            background: {sem.border_subtle};
        }}
        QDockWidget {{
            color: {sem.text_primary};
        }}
        QWizard QLabel {{
            color: {sem.text_primary};
        }}
        """,
        # ── instrument chrome: Ink/Mist in BOTH themes ───────────────
        f"""
        *[mgfChrome="true"] {{
            background: {chrome_ink};
            color: {chrome_text};
        }}
        *[mgfChrome="true"] QLabel {{
            background: transparent;
            color: {chrome_text};
        }}
        *[mgfChrome="true"] QLabel[mgfClass="eyebrow"] {{
            color: {_rgba(chrome_text, 0.6)};
        }}
        *[mgfChrome="true"] QLabel[mgfClass="railKind"] {{
            color: {_rgba(chrome_text, 0.85)};
            border: 1px solid {_rgba(chrome_text, 0.35)};
            border-radius: 999px;
            padding: 1px 8px;
        }}
        QListWidget[mgfChrome="true"] {{
            background: {chrome_ink};
            color: {_rgba(chrome_text, 0.85)};
            border: none;
            border-radius: 0;
            padding-top: 4px;
        }}
        QListWidget[mgfChrome="true"]::item {{
            padding: 10px 14px;
            border-left: 2px solid transparent;
        }}
        QListWidget[mgfChrome="true"]::item:selected {{
            border-left: 2px solid {RAW.gold};
            background: rgba(255,255,255,0.08);
            color: {chrome_text};
        }}
        QListWidget[mgfChrome="true"]::item:hover:!selected {{
            background: rgba(255,255,255,0.04);
        }}
        QPlainTextEdit[mgfChrome="true"], QTextEdit[mgfChrome="true"] {{
            background: {chrome_ink};
            color: {chrome_text};
            border: 1px solid {_rgba(chrome_text, 0.15)};
            border-radius: {RADIUS["sm"]}px;
            selection-background-color: {_rgba(chrome_text, 0.25)};
            selection-color: {chrome_text};
        }}
        *[mgfClass="ledger"] {{
            background: {chrome_ink};
            border: none;
            border-radius: {RADIUS["lg"]}px;
            margin-top: 0;
            padding: 10px;
        }}
        *[mgfClass="ledger"] QLabel {{
            background: transparent;
            color: {chrome_text};
        }}
        QGroupBox[mgfClass="ledger"]::title {{
            color: {_rgba(chrome_text, 0.6)};
        }}
        QLabel[mgfClass="ledgerKey"] {{
            color: {_rgba(chrome_text, 0.65)};
            background: transparent;
        }}
        QLabel[mgfClass="ledgerAccent"] {{
            color: {RAW.gold};
            background: transparent;
        }}
        """,
    ]
    return "\n".join(section.strip() for section in sections)


__all__ = ["MGF_PROPS", "build_qss"]
