"""External UI theme loader for the warehouse desktop application.

The module reads ``ui_theme.json`` from the workspace root and exposes a few
helpers to resolve fonts, colors, paddings and section-specific configuration
without hardcoding presentation details inside each window module.
"""

from __future__ import annotations

import json
from functools import lru_cache
from pathlib import Path
from typing import Any

from version_info import module_version

__version__ = module_version(__name__)

THEME_PATH = Path(__file__).with_name("ui_theme.json")


@lru_cache(maxsize=1)
def load_theme() -> dict[str, Any]:
    """Load the external JSON theme, returning an empty dict on failure."""

    try:
        return json.loads(THEME_PATH.read_text(encoding="utf-8"))
    except Exception:
        return {}


def reload_theme() -> dict[str, Any]:
    """Clear cache and reload the theme from disk."""

    load_theme.cache_clear()
    return load_theme()


def theme_section(name: str, default: dict[str, Any] | None = None) -> dict[str, Any]:
    """Return one top-level theme section as a dictionary."""

    theme = load_theme()
    value = theme.get(name)
    if isinstance(value, dict):
        return value
    return dict(default or {})


def theme_value(section: dict[str, Any], key: str, default: Any = None) -> Any:
    """Return a scalar theme value from a section."""

    return section.get(key, default)


def theme_color(section: dict[str, Any], key: str, default: Any = None) -> Any:
    """Return a CTk-compatible color value (string or light/dark tuple)."""

    value = section.get(key, default)
    if isinstance(value, list) and len(value) == 2:
        return tuple(value)
    return value


def theme_padding(section: dict[str, Any], key: str, default: tuple[int, ...]) -> tuple[int, ...]:
    """Return tuple-like padding values from a JSON list."""

    value = section.get(key)
    if isinstance(value, list):
        try:
            return tuple(int(v) for v in value)
        except Exception:
            return default
    return default


def theme_font(section: dict[str, Any], key: str, default: tuple[Any, ...]) -> tuple[Any, ...]:
    """Resolve a Tk font tuple from JSON."""

    spec = section.get(key)
    if not isinstance(spec, dict):
        return default

    family = spec.get("family", default[0] if default else "Segoe UI")
    size = int(spec.get("size", default[1] if len(default) > 1 else 10))

    parts: list[Any] = [family, size]

    weight = str(spec.get("weight", "")).strip().lower()
    if weight in {"bold", "normal"} and weight != "normal":
        parts.append(weight)

    slant = str(spec.get("slant", "")).strip().lower()
    if slant == "italic":
        parts.append(slant)

    if bool(spec.get("underline", False)):
        parts.append("underline")
    if bool(spec.get("overstrike", False)):
        parts.append("overstrike")

    return tuple(parts)
