"""现代化 UI 样式注册（跟随 ttkbootstrap 当前主题）。

由 backgroud_style_set() 调用一次。这里集中定义"配置项卡片化"、
"现代化标题栏"、"工具条"、"状态栏" 等所需的所有 ttk Style，
保持主题切换时颜色自动跟随。
"""

from __future__ import annotations

import ttkbootstrap as ttk


def _hex_to_rgb(h: str) -> tuple[int, int, int]:
    h = h.lstrip("#")
    return int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)


def _rgb_to_hex(r: int, g: int, b: int) -> str:
    return f"#{r:02x}{g:02x}{b:02x}"


def _mix(c1: str, c2: str, ratio: float) -> str:
    """按 ratio (0~1) 将 c1 与 c2 线性混合。"""
    r1, g1, b1 = _hex_to_rgb(c1)
    r2, g2, b2 = _hex_to_rgb(c2)
    return _rgb_to_hex(
        int(r1 * (1 - ratio) + r2 * ratio),
        int(g1 * (1 - ratio) + g2 * ratio),
        int(b1 * (1 - ratio) + b2 * ratio),
    )


def _is_dark(color: str) -> bool:
    r, g, b = _hex_to_rgb(color)
    # ITU-R BT.601 亮度
    return (r * 299 + g * 587 + b * 114) / 1000 < 128


def _contrast_text(color: str, *, dark_text: str, light_text: str) -> str:
    return dark_text if _is_dark(color) else light_text


def get_theme_palette() -> dict[str, str]:
    """返回当前主题的语义色板，供 ttk / tk 自定义控件共用。"""
    style = ttk.Style()
    theme = style.colors

    bg = theme.bg
    fg = theme.fg
    primary = theme.primary
    secondary = theme.secondary
    success = theme.success
    info = theme.info
    warning = theme.warning
    danger = theme.danger
    dark = theme.dark
    border = theme.border
    inputbg = theme.inputbg
    inputfg = getattr(theme, "inputfg", fg)

    dark_theme = _is_dark(bg)
    select_bg = getattr(theme, "selectbg", _mix(primary, bg, 0.30 if dark_theme else 0.12))
    select_fg = getattr(theme, "selectfg", "#ffffff" if _is_dark(select_bg) else fg)

    if dark_theme:
        card_bg = _mix(bg, "#ffffff", 0.04)
        card_border = _mix(bg, fg, 0.18)
        header_fg = _contrast_text(
            "#444A51",
            dark_text="#ffffff",
            light_text="#1a1a1a",
        )
        sidebar_bg = _mix(dark, bg, 0.18)
        sidebar_hover = _mix(sidebar_bg, "#ffffff", 0.07)
        sidebar_selected = _mix(sidebar_bg, "#ffffff", 0.14)
        sidebar_fg = _mix(fg, "#ffffff", 0.04)
        sidebar_muted = _mix(sidebar_fg, sidebar_bg, 0.45)
        muted_fg = _mix(fg, bg, 0.32)
        disabled_fg = _mix(fg, bg, 0.42)
        disabled_bg = _mix(inputbg, bg, 0.18)
        disabled_border = _mix(border, fg, 0.22)
        readonly_bg = _mix(inputbg, "#ffffff", 0.06)
        success_fg = _mix(success, "#ffffff", 0.08)
        warning_fg = _mix(warning, "#ffffff", 0.06)
        info_fg = _mix(info, "#ffffff", 0.06)
        statusbar_bg = _mix(bg, "#ffffff", 0.06)
        tooltip_bg = _mix(inputbg, bg, 0.08)
        tooltip_fg = inputfg
        tooltip_border = _mix(border, fg, 0.20)
        surface_alt_bg = _mix(card_bg, "#ffffff", 0.05)
        surface_hover_bg = _mix(card_bg, "#ffffff", 0.09)
        badge_bg = _mix(danger, bg, 0.12)
        badge_fg = "#ffffff"
        focus = _mix(primary, "#ffffff", 0.18)
        config_bg = _mix("#444A51", bg, 0.30)
    else:
        card_bg = inputbg
        card_border = border
        header_fg = bg
        config_bg = _mix(primary, bg, 0.25)
        sidebar_bg = _mix(primary, bg, 0.82)
        sidebar_hover = _mix(primary, bg, 0.72)
        sidebar_selected = primary
        sidebar_fg = fg
        sidebar_muted = _mix(fg, sidebar_bg, 0.35)
        muted_fg = _mix(fg, bg, 0.38)
        disabled_fg = _mix(fg, bg, 0.55)
        disabled_bg = _mix(bg, border, 0.18)
        disabled_border = _mix(border, bg, 0.18)
        readonly_bg = _mix(inputbg, primary, 0.04)
        success_fg = success
        warning_fg = _mix(warning, fg, 0.18)
        info_fg = info
        statusbar_bg = _mix(bg, dark, 0.04)
        tooltip_bg = inputbg
        tooltip_fg = inputfg
        tooltip_border = border
        surface_alt_bg = _mix(bg, dark, 0.03)
        surface_hover_bg = _mix(bg, dark, 0.05)
        badge_bg = danger
        badge_fg = "#ffffff"
        focus = _mix(primary, bg, 0.20)

    return {
        "bg": bg,
        "fg": fg,
        "primary": primary,
        "secondary": secondary,
        "success": success,
        "info": info,
        "warning": warning,
        "danger": danger,
        "border": border,
        "input_bg": inputbg,
        "input_fg": inputfg,
        "select_bg": select_bg,
        "select_fg": select_fg,
        "card_bg": card_bg,
        "card_border": card_border,
        "header_fg": header_fg,
        "sidebar_bg": sidebar_bg,
        "sidebar_hover": sidebar_hover,
        "sidebar_selected": sidebar_selected,
        "sidebar_fg": sidebar_fg,
        "sidebar_muted": sidebar_muted,
        "muted_fg": muted_fg,
        "disabled_fg": disabled_fg,
        "disabled_bg": disabled_bg,
        "disabled_border": disabled_border,
        "readonly_bg": readonly_bg,
        "success_fg": success_fg,
        "warning_fg": warning_fg,
        "info_fg": info_fg,
        "statusbar_bg": statusbar_bg,
        "tooltip_bg": tooltip_bg,
        "tooltip_fg": tooltip_fg,
        "tooltip_border": tooltip_border,
        "surface_alt_bg": surface_alt_bg,
        "surface_hover_bg": surface_hover_bg,
        "badge_bg": badge_bg,
        "badge_fg": badge_fg,
        "focus": focus,
        "config_bg": config_bg,
    }


def apply_listbox_theme(widget) -> None:
    """将 tk.Listbox 颜色同步到当前主题。"""
    palette = get_theme_palette()
    widget.configure(
        background=palette["input_bg"],
        foreground=palette["input_fg"],
        highlightbackground=palette["border"],
        highlightcolor=palette["focus"],
        selectbackground=palette["select_bg"],
        selectforeground=palette["select_fg"],
        disabledforeground=palette["disabled_fg"],
    )


def apply_tooltip_theme(toplevel, label) -> None:
    """将 tooltip 的 tk.Toplevel / Label 同步到当前主题。"""
    palette = get_theme_palette()
    toplevel.configure(background=palette["tooltip_border"])
    label.configure(
        bg=palette["tooltip_bg"],
        fg=palette["tooltip_fg"],
        highlightbackground=palette["tooltip_border"],
    )


def apply_modern_styles() -> None:
    """注册或刷新现代化样式集。可在主题切换后再次调用。"""
    style = ttk.Style()
    palette = get_theme_palette()

    bg = palette["bg"]
    fg = palette["fg"]
    primary = palette["primary"]
    secondary = palette["secondary"]
    info = palette["info"]
    card_bg = palette["card_bg"]
    card_border = palette["card_border"]
    header_bg = palette["config_bg"]
    header_fg = palette["header_fg"]
    dark_theme = _is_dark(bg)
    header_hover_bg = _mix(secondary, "#ffffff", 0.08) if _is_dark(secondary) else _mix(secondary, "#000000", 0.08)
    preview_fg = _mix(header_fg, header_bg, 0.35)
    sidebar_bg = palette["sidebar_bg"]
    sidebar_hover = palette["sidebar_hover"]
    sidebar_selected = palette["sidebar_selected"]
    sidebar_fg = palette["sidebar_fg"]
    sidebar_muted = palette["sidebar_muted"]
    muted_fg = palette["muted_fg"]
    disabled_fg = palette["disabled_fg"]
    disabled_bg = palette["disabled_bg"]
    disabled_border = palette["disabled_border"]
    readonly_bg = palette["readonly_bg"]
    success_fg = palette["success_fg"]
    warning_fg = palette["warning_fg"]

    # ---------------- 卡片 ----------------
    style.configure(
        "Card.TFrame",
        background=card_bg,
        bordercolor=card_border,
        relief="solid",
        borderwidth=1,
    )
    style.configure(
        "CardTitle.TLabel",
        background=card_bg,
        foreground=fg,
        font=("Segoe UI", 10, "bold"),
    )
    style.configure(
        "CardBody.TLabel",
        background=card_bg,
        foreground=fg,
        font=("Segoe UI", 9),
    )
    style.configure(
        "CardIcon.TLabel",
        background=card_bg,
        foreground=info if dark_theme else primary,
        font=("Segoe UI", 9, "bold"),
    )

    # 内嵌于 Card 的容器（与 Card.TFrame 同背景，无边框）
    style.configure("CardInner.TFrame", background=card_bg, borderwidth=0)

    # ---------------- 配置项 Header ----------------
    style.configure(
        "ConfigHeader.TFrame",
        background=header_bg,
        borderwidth=0,
    )
    style.configure(
        "ConfigHeaderHover.TFrame",
        background=header_hover_bg,
        borderwidth=0,
    )
    style.configure(
        "ConfigHeader.TLabel",
        background=header_bg,
        foreground=header_fg,
        font=("Segoe UI", 10, "bold"),
    )
    style.configure(
        "ConfigHeaderHover.TLabel",
        background=header_hover_bg,
        foreground=header_fg,
        font=("Segoe UI", 10, "bold"),
    )
    style.configure(
        "ConfigChevron.TLabel",
        background=header_bg,
        foreground=header_fg,
        font=("Segoe UI Symbol", 12, "bold"),
    )
    style.configure(
        "ConfigPreview.TLabel",
        background=header_bg,
        foreground=preview_fg,
        font=("Segoe UI", 9),
    )

    # ---------------- 通用文字语义 ----------------
    style.configure("Muted.TLabel", background=bg, foreground=muted_fg)
    style.configure("SuccessState.TLabel", background=bg, foreground=success_fg)
    style.configure("WarningState.TLabel", background=bg, foreground=warning_fg)
    style.configure("InfoState.TLabel", background=bg, foreground=palette["info_fg"])

    # ---------------- 顶部工具条 ----------------
    style.configure("Toolbar.TFrame", background=bg, borderwidth=0)
    # 工具条上的次要按钮（清理配置等）
    style.configure(
        "ToolbarMuted.TButton",
        font=("Segoe UI", 9),
        padding=(10, 5),
    )

    # ---------------- 区段标题（侧栏 / 卡片外） ----------------
    style.configure(
        "SectionTitle.TLabel",
        background=bg,
        foreground=_mix(fg, bg, 0.45),
        font=("Segoe UI", 8, "bold"),
    )
    style.configure("Sidebar.TFrame", background=sidebar_bg, borderwidth=0)
    # 侧栏内的小区段标题（侧栏背景是 primary）
    style.configure(
        "SidebarSection.TLabel",
        background=sidebar_bg,
        foreground=sidebar_muted,
        font=("Segoe UI", 8, "bold"),
    )
    # 侧栏顶部品牌区
    brand_bg = _mix(sidebar_bg, "#ffffff", 0.05) if dark_theme else _mix(sidebar_bg, "#000000", 0.05)
    style.configure(
        "SidebarBrand.TFrame",
        background=brand_bg,
        borderwidth=0,
    )
    style.configure(
        "SidebarBrand.TLabel",
        background=brand_bg,
        foreground=palette["badge_fg"],
        font=("Segoe UI Semibold", 12),
    )
    style.configure(
        "SidebarBadge.TLabel",
        background=palette["badge_bg"],
        foreground=palette["badge_fg"],
        font=("微软雅黑", 8, "bold"),
        anchor="center",
        padding=(6, 2),
    )

    # ---------------- 结果区无边框标题行 ----------------
    style.configure("ResultHeader.TFrame", background=bg, borderwidth=0)
    style.configure(
        "ResultHeader.TLabel",
        background=bg,
        foreground=fg,
        font=("Segoe UI", 11, "bold"),
    )

    # ---------------- 状态栏 ----------------
    statusbar_bg = palette["statusbar_bg"]
    statusbar_fg = _mix(fg, bg, 0.15)
    style.configure(
        "StatusBar.TFrame",
        background=statusbar_bg,
        borderwidth=0,
    )
    style.configure(
        "StatusBar.TLabel",
        background=statusbar_bg,
        foreground=statusbar_fg,
        font=("Segoe UI", 9),
        padding=(10, 4),
    )
    style.configure(
        "StatusBarAccent.TLabel",
        background=statusbar_bg,
        foreground=info if dark_theme else primary,
        font=("Segoe UI", 9, "bold"),
        padding=(10, 4),
    )

    # ---------------- 深色禁用态 / 只读态增强 ----------------
    style.map(
        "TLabel",
        foreground=[("disabled", disabled_fg)],
    )
    style.map(
        "TButton",
        foreground=[("disabled", disabled_fg)],
        background=[("disabled", disabled_bg)],
        bordercolor=[("disabled", disabled_border)],
        darkcolor=[("disabled", disabled_bg)],
        lightcolor=[("disabled", disabled_bg)],
    )
    style.map(
        "TEntry",
        foreground=[("disabled", disabled_fg)],
        fieldbackground=[("disabled", disabled_bg), ("readonly", readonly_bg)],
        bordercolor=[("disabled", disabled_border), ("readonly", disabled_border)],
    )
    style.map(
        "TCombobox",
        foreground=[("disabled", disabled_fg), ("readonly", fg)],
        fieldbackground=[("disabled", disabled_bg), ("readonly", readonly_bg)],
        bordercolor=[("disabled", disabled_border), ("readonly", disabled_border)],
        arrowcolor=[("disabled", disabled_fg), ("readonly", muted_fg)],
    )

    # ---------------- Sidebar 按钮（保留兼容名） ----------------
    style.configure(
        "Sidebar.TButton",
        background=sidebar_bg,
        foreground=sidebar_fg,
        font=("Segoe UI", 10),
        padding=(18, 9),
        borderwidth=0,
        anchor="w",
    )
    style.map(
        "Sidebar.TButton",
        background=[
            ("active", sidebar_hover),
            ("pressed", sidebar_selected),
        ],
        foreground=[("active", "#ffffff" if _is_dark(sidebar_hover) else sidebar_fg)],
    )
    style.configure(
        "SidebarSelected.TButton",
        background=sidebar_selected,
        foreground=_contrast_text(sidebar_selected, dark_text=palette["badge_fg"], light_text=sidebar_fg),
        font=("Segoe UI Semibold", 10),
        padding=(18, 9),
        borderwidth=0,
        anchor="w",
    )
    style.map(
        "SidebarSelected.TButton",
        background=[
            ("active", _mix(sidebar_selected, "#ffffff", 0.06) if dark_theme else _mix(sidebar_selected, "#000000", 0.06)),
            ("pressed", _mix(sidebar_selected, "#000000", 0.08)),
        ],
    )
