"""The 42-icon Magogi set as recolorable, DPR-aware QIcons.

Icons are the brand's hand-authored 24-grid SVGs (stroke 1.25,
``currentColor`` — see ``assets/ASSETS_MANIFEST.md``). :func:`icon`
substitutes ``currentColor`` with a concrete token colour and renders
at the device pixel ratio, caching per ``(name, colour, size, dpr)``.

Colour discipline: icons are monochrome by law, themed by their
surrounding text colour. The default is Slate — legible on both
themes — so callers only pass a colour when the icon sits on chrome
(Mist) or carries the view's one gold emphasis.
"""

from __future__ import annotations

from importlib import resources

from PySide6.QtCore import QRectF, Qt
from PySide6.QtGui import QGuiApplication, QIcon, QPainter, QPixmap
from PySide6.QtSvg import QSvgRenderer

from mgf.brand_qt.tokens import RAW

ICON_NAMES: frozenset[str] = frozenset(
    {
        # navigation (9)
        "home",
        "menu",
        "close",
        "chevron-up",
        "chevron-down",
        "chevron-left",
        "chevron-right",
        "external",
        "search",
        # actions (9)
        "copy",
        "download",
        "refresh",
        "filter",
        "settings",
        "plus",
        "minus",
        "check",
        "x",
        # status (7)
        "info",
        "warning",
        "error",
        "success",
        "pending",
        "paused",
        "live-dot",
        # domain (17)
        "proof",
        "manifest",
        "artifact",
        "ledger",
        "chain",
        "build",
        "review",
        "publish",
        "kernel",
        "forge",
        "mesh",
        "witness",
        "registry",
        "lock",
        "key",
        "terminal",
        "chart",
    }
)

_CACHE: dict[tuple[str, str, int, float], QIcon] = {}


def icon(
    name: str,
    *,
    color: str | None = None,
    size: int = 24,
    ratio: float | None = None,
) -> QIcon:
    """Return the named brand icon rendered in ``color`` at ``size`` px.

    Raises ``ValueError`` for a name outside the 42-icon set (the set
    is locked upstream; a missing name is a programming error, not a
    runtime condition).

    ``ratio`` pins the device-pixel ratio the pixmap is rendered at.
    Leave it ``None`` for the application-level ratio (re-read on
    every call — never baked in); pass ``widget.devicePixelRatioF()``
    on mixed-DPI setups so the icon renders for the screen it actually
    sits on (PAPER-03).
    """
    if name not in ICON_NAMES:
        raise ValueError(f"unknown brand icon {name!r} (not in the 42-icon set)")
    resolved = color if color is not None else RAW.slate
    if ratio is not None:
        dpr = ratio
    else:
        app = QGuiApplication.instance()
        dpr = app.devicePixelRatio() if isinstance(app, QGuiApplication) else 1.0
    key = (name, resolved, size, dpr)
    cached = _CACHE.get(key)
    if cached is not None:
        return cached
    svg = (
        resources.files("mgf.brand_qt")
        .joinpath(f"assets/icons/{name}.svg")
        .read_bytes()
        .replace(b"currentColor", resolved.encode("ascii"))
    )
    renderer = QSvgRenderer(svg)
    px = max(1, round(size * dpr))
    pixmap = QPixmap(px, px)
    pixmap.fill(Qt.GlobalColor.transparent)
    painter = QPainter(pixmap)
    painter.setRenderHint(QPainter.RenderHint.Antialiasing)
    renderer.render(painter, QRectF(0, 0, px, px))
    painter.end()
    pixmap.setDevicePixelRatio(dpr)
    result = QIcon(pixmap)
    _CACHE[key] = result
    return result


_LOGO_FILES: dict[str, str] = {
    "color": "magogi-icon.svg",
    "mono": "magogi-icon-mono.svg",
    "on-dark": "magogi-icon-on-dark.svg",
}


def logo_pixmap(
    variant: str = "color",
    *,
    size: int = 24,
    ratio: float | None = None,
) -> QPixmap:
    """Return the Cornerstone Orbit mark as a pixmap (PAPER-05).

    ``variant`` is ``"color"`` / ``"mono"`` / ``"on-dark"`` — the three
    vendored marks. Rendered at ``size`` px times the device-pixel
    ratio (``ratio`` overrides, same contract as :func:`icon`).
    """
    filename = _LOGO_FILES.get(variant)
    if filename is None:
        raise ValueError(
            f"unknown logo variant {variant!r}; use one of: {', '.join(sorted(_LOGO_FILES))}"
        )
    if ratio is not None:
        dpr = ratio
    else:
        app = QGuiApplication.instance()
        dpr = app.devicePixelRatio() if isinstance(app, QGuiApplication) else 1.0
    svg = resources.files("mgf.brand_qt").joinpath(f"assets/logo/{filename}").read_bytes()
    renderer = QSvgRenderer(svg)
    px = max(1, round(size * dpr))
    pixmap = QPixmap(px, px)
    pixmap.fill(Qt.GlobalColor.transparent)
    painter = QPainter(pixmap)
    painter.setRenderHint(QPainter.RenderHint.Antialiasing)
    renderer.render(painter, QRectF(0, 0, px, px))
    painter.end()
    pixmap.setDevicePixelRatio(dpr)
    return pixmap


__all__ = ["ICON_NAMES", "icon", "logo_pixmap"]
