"""Bundled Magogi brand fonts — loading and QFont helpers.

Registers the vendored static TTFs (Inter, Space Grotesk, JetBrains
Mono — see ``assets/ASSETS_MANIFEST.md``) with :class:`QFontDatabase`
and exposes small typed helpers so the rest of the GUI never spells a
family name or point size directly.

Degradation is deliberate (03-target-design §D5): a font that fails to
load logs a warning and is skipped — QFont then falls back to the
system family. The app must never fail to start over fonts.
"""

from __future__ import annotations

import logging
from importlib import resources

from PySide6.QtGui import QFont, QFontDatabase

from mgf.brand_qt.tokens import FONT_BODY, FONT_DISPLAY, FONT_MONO, TEXT_PT, WEIGHT

LOG = logging.getLogger(__name__)


def load_fonts() -> list[str]:
    """Register every bundled ``.ttf`` and return the loaded family names.

    Requires a constructed :class:`QGuiApplication`. Failures are
    logged and skipped, never raised.
    """
    families: list[str] = []
    try:
        fonts_root = resources.files("mgf.brand_qt").joinpath("assets/fonts")
        entries = list(fonts_root.iterdir())
    except OSError:
        LOG.warning("bundled font directory unavailable; using system fonts", exc_info=True)
        return families
    for entry in sorted(entries, key=lambda e: e.name):
        if not entry.name.endswith(".ttf"):
            continue
        try:
            with resources.as_file(entry) as path:
                font_id = QFontDatabase.addApplicationFont(str(path))
        except OSError:
            LOG.warning("cannot materialise bundled font %s", entry.name, exc_info=True)
            continue
        if font_id < 0:
            LOG.warning("Qt rejected bundled font %s", entry.name)
            continue
        families.extend(QFontDatabase.applicationFontFamilies(font_id))
    return families


def default_font() -> QFont:
    """The application-wide body font: Inter at the 10.5pt base size."""
    font = QFont(FONT_BODY)
    font.setPointSizeF(TEXT_PT["base"])
    font.setWeight(QFont.Weight(WEIGHT["regular"]))
    return font


def display_font(pt: float, weight: int = 600) -> QFont:
    """Space Grotesk display font for headings/titles (default semibold)."""
    font = QFont(FONT_DISPLAY)
    font.setPointSizeF(pt)
    font.setWeight(QFont.Weight(weight))
    return font


def mono_font(pt: float, weight: int = 400) -> QFont:
    """JetBrains Mono for machine-ish content, numerals, and eyebrows."""
    font = QFont(FONT_MONO)
    font.setPointSizeF(pt)
    font.setWeight(QFont.Weight(weight))
    font.setStyleHint(QFont.StyleHint.Monospace)
    font.setFixedPitch(True)
    return font


__all__ = ["default_font", "display_font", "load_fonts", "mono_font"]
