"""主题管理：注册 Calman 风格深色主题 + 提供运行时切换。

主题在启动时通过 ``apply_initial_theme(root_style)`` 注入到 ttkbootstrap，
当前选择持久化到 ``settings/ui_preferences.json``。运行时调用
``toggle_theme(root_style)`` / ``set_theme(root_style, name)`` 可即时切换，
并自动重新调用 ``apply_modern_styles()`` 让自定义样式跟上新色板。
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Optional

from ttkbootstrap.style import Style, ThemeDefinition

from app.views.modern_styles import apply_modern_styles


_PREFS_PATH = Path("settings/ui_preferences.json")

# 浅色主题：自定义轻量蓝灰色板，恢复旧版浅色观感
LIGHT_THEME = "calman_light"
# 深色主题：自定义 Calman 风格
DARK_THEME = "calman_dark"

_LEGACY_LIGHT_THEMES = {"yeti"}


_CALMAN_LIGHT_COLORS = {
    "primary": "#1755a6",
    "secondary": "#3572B4",
    "success": "#2F9E44",
    "info": "#247BA0",
    "warning": "#C98700",
    "danger": "#CC3300",
    "light": "#F7FAFC",
    "dark": "#1F2A36",
    "bg": "#F5F8FB",
    "fg": "#1F2933",
    "selectbg": "#2B6CB0",
    "selectfg": "#FFFFFF",
    "border": "#C8D4E3",
    "inputfg": "#243240",
    "inputbg": "#FFFFFF",
    "active": "#D9E6F2",
}


# ----------------------------------------------------------------------
# Calman 风格深色主题色板
# ----------------------------------------------------------------------
_CALMAN_DARK_COLORS = {
    # "primary": "#2A2F36",     
    # "secondary": "#444A51",
    "primary": "#6FAFCC",
    "secondary": "#AEAEAE",
    "success": "#4FB960",
    "info": "#6FAFCC",
    "warning": "#F2A93B",
    "danger": "#E0524A",
    "light": "#BFC6CE",       # 高亮文本
    "dark": "#0D1014",        # 最深背景（侧栏底色）
    "bg": "#1B1F24",          # 主窗口背景
    "fg": "#E4E8EE",          # 主文本颜色
    "selectbg": "#5A6169",
    "selectfg": "#E4E8EE",
    "border": "#2A2F36",
    "inputfg": "#E4E8EE",
    "inputbg": "#24292F",
    "active": "#2A2F36",
}


def register_themes() -> None:
    """把自定义深色主题注册到 ttkbootstrap（可重复调用，幂等）。"""
    style = Style()
    if LIGHT_THEME not in style.theme_names():
        light_def = ThemeDefinition(
            name=LIGHT_THEME,
            themetype="light",
            colors=_CALMAN_LIGHT_COLORS,
        )
        style.register_theme(light_def)
    if DARK_THEME in style.theme_names():
        return
    dark_def = ThemeDefinition(
        name=DARK_THEME,
        themetype="dark",
        colors=_CALMAN_DARK_COLORS,
    )
    style.register_theme(dark_def)


def _normalize_theme_name(name: Optional[str]) -> str:
    if not name or name in _LEGACY_LIGHT_THEMES:
        return LIGHT_THEME
    return name


# ----------------------------------------------------------------------
# 偏好持久化
# ----------------------------------------------------------------------
def _read_prefs() -> dict:
    try:
        return json.loads(_PREFS_PATH.read_text(encoding="utf-8"))
    except (FileNotFoundError, json.JSONDecodeError):
        return {}


def _write_prefs(data: dict) -> None:
    try:
        _PREFS_PATH.parent.mkdir(parents=True, exist_ok=True)
        _PREFS_PATH.write_text(
            json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8"
        )
    except OSError:
        # 写入失败不应影响 UI
        pass


def get_saved_theme() -> Optional[str]:
    return _read_prefs().get("theme")


def save_theme(name: str) -> None:
    prefs = _read_prefs()
    prefs["theme"] = name
    _write_prefs(prefs)


# ----------------------------------------------------------------------
# 主题应用 / 切换
# ----------------------------------------------------------------------
def apply_initial_theme() -> str:
    """启动时调用：注册主题 + 加载偏好 + 切到对应主题。

    返回最终生效的主题名。
    """
    register_themes()
    name = _normalize_theme_name(get_saved_theme())
    style = Style()
    if name not in style.theme_names():
        name = LIGHT_THEME
    style.theme_use(name)
    apply_modern_styles()
    return name


def set_theme(name: str) -> str:
    """切换到指定主题，持久化偏好，并刷新自定义样式。"""
    register_themes()
    name = _normalize_theme_name(name)
    style = Style()
    if name not in style.theme_names():
        name = LIGHT_THEME
    style.theme_use(name)
    apply_modern_styles()
    save_theme(name)
    return name


def toggle_theme() -> str:
    """在浅 / 深之间切换。返回新主题名。"""
    style = Style()
    current = style.theme.name
    target = DARK_THEME if current != DARK_THEME else LIGHT_THEME
    return set_theme(target)


def is_dark() -> bool:
    return Style().theme.name == DARK_THEME
