"""Unit tests for the generated stylesheet (Qt-free)."""

from __future__ import annotations

import re

from mgf.brand_qt import tokens
from mgf.brand_qt.qss import build_qss

_HEX_RE = re.compile(r"#[0-9a-fA-F]{6}\b")


def _token_hexes() -> set[str]:
    from dataclasses import fields

    values = {getattr(tokens.RAW, f.name) for f in fields(tokens.RAW)}
    for theme in (tokens.LIGHT, tokens.DARK):
        values.update(getattr(theme, f.name) for f in fields(theme))
    values.update(tokens.VIZ_CATEGORICAL)
    values.update(tokens.VIZ_SEQ_INDIGO)
    values.update(tokens.VIZ_DIVERGING)
    return {v.lower() for v in values if v.startswith("#")} | {"#ffffff", "#000000"}


def _build(theme: tokens.SemanticColors) -> str:
    return build_qss(theme, chrome_ink=tokens.RAW.ink, chrome_text=tokens.RAW.mist)


def test_builds_for_both_themes_and_differs() -> None:
    light = _build(tokens.LIGHT)
    dark = _build(tokens.DARK)
    assert light and dark and light != dark


def test_contains_chrome_section_with_ink_in_both_themes() -> None:
    for theme in (tokens.LIGHT, tokens.DARK):
        sheet = _build(theme)
        assert '*[mgfChrome="true"]' in sheet
        chrome_part = sheet[sheet.index('*[mgfChrome="true"]') :]
        assert tokens.RAW.ink in chrome_part
        assert tokens.RAW.mist in chrome_part


def test_focus_ring_is_theme_law() -> None:
    # Dark focus ring is gold; light focus ring is darkened teal (never
    # gold). `border:` is the focus-ring spelling; the gold active-tab
    # underline (`border-bottom:`) is canon in both themes.
    assert f"border: 2px solid {tokens.DARK.focus_ring}" in _build(tokens.DARK)
    assert tokens.DARK.focus_ring == tokens.RAW.gold
    light = _build(tokens.LIGHT)
    assert f"border: 2px solid {tokens.LIGHT.focus_ring}" in light
    assert f"border: 2px solid {tokens.RAW.gold}" not in light


def test_palette_lint_every_hex_is_a_token() -> None:
    allowed = _token_hexes() | {tokens.BUTTON_PRIMARY_HOVER, tokens.BUTTON_ACCENT_HOVER}
    for theme in (tokens.LIGHT, tokens.DARK):
        for hex_value in _HEX_RE.findall(_build(theme)):
            assert hex_value.lower() in allowed, hex_value


def test_component_vocabulary_is_present() -> None:
    for theme in (tokens.LIGHT, tokens.DARK):
        sheet = _build(theme)
        for selector in (
            'QPushButton[mgfVariant="primary"]',
            'QPushButton[mgfVariant="accent"]',
            'QPushButton[mgfVariant="danger"]',
            'QLabel[mgfClass="hint"]',
            'QLabel[mgfClass="sectionTitle"]',
            'QLabel[mgfClass="strongLabel"]',
            'QLabel[mgfClass="errorText"]',
            'QLabel[mgfClass="eyebrow"]',
            "QHeaderView::section",
            "QTabBar::tab:selected",
            "QScrollBar::handle",
            "QProgressBar::chunk",
            "QGroupBox::title",
        ):
            assert selector in sheet, selector


def test_accent_button_is_gold_with_ink_text_and_tab_underline_is_gold() -> None:
    sheet = _build(tokens.LIGHT)
    accent = sheet[sheet.index('QPushButton[mgfVariant="accent"]') :]
    accent = accent[: accent.index("}")]
    assert tokens.RAW.gold in accent
    assert tokens.RAW.ink in accent
    assert f"2px solid {tokens.RAW.gold}" in sheet  # active tab underline
