-- EbonholdHub: modules/ui/SiteTheme.lua
-- Website design tokens (globals.css) — single source for SiteWidgets + future UIKit migration.
-- Port path: UI.Colors → SiteTheme.C, views use SiteWidgets factories.

EbonholdHub.SiteTheme = EbonholdHub.SiteTheme or {}

local ST = EbonholdHub.SiteTheme

ST.FLAT = "Interface\\Buttons\\WHITE8X8"

ST.FONT = {
    regular  = "Interface\\AddOns\\EbonholdHub\\media\\fonts\\Geist-Regular.ttf",
    medium   = "Interface\\AddOns\\EbonholdHub\\media\\fonts\\Geist-Medium.ttf",
    semibold = "Interface\\AddOns\\EbonholdHub\\media\\fonts\\Geist-SemiBold.ttf",
    fallback = "Fonts\\FRIZQT__.TTF",
}

ST.Layout = {
    PAD          = 16,
    NAV_H        = 48,
    CHIP_H       = 24,
    SIDEBAR_W    = 300,
    MAIN_W       = 740,
    WIN_W        = 1040,
    WIN_H        = 720,
    ICON_TIER    = 32,
    ICON_LOCKED  = 36,
    ICON_GAP     = 6,
    TIER_LABEL_W = 32,
    CLASS_ICON   = 44,
    SPEC_ICON    = 18,
}

-- Raw RGB from globals.css (:root)
ST.Base = {
    bg          = { 29/255,  31/255,  41/255 },
    bgElevated  = { 34/255,  37/255,  47/255 },
    bgHeader    = { 37/255,  40/255,  51/255 },
    border      = { 46/255,  46/255,  56/255 },
    borderHover = { 61/255,  61/255,  74/255 },
    accent      = { 77/255, 191/255, 242/255 },
    text        = {235/255, 235/255, 240/255 },
    textDim     = {140/255, 140/255, 153/255 },
    textMuted   = {110/255, 110/255, 122/255 },
    elementBg   = { 31/255,  31/255,  38/255 },
}

function ST.BlendRgb(fg, bg, alpha)
    local inv = 1 - alpha
    return {
        fg[1] * alpha + bg[1] * inv,
        fg[2] * alpha + bg[2] * inv,
        fg[3] * alpha + bg[3] * inv,
        1.00,
    }
end

local function Opaque(rgb)
    return { rgb[1], rgb[2], rgb[3], 1.00 }
end

local B = ST.Base

-- Pre-blended opaque colors (CSS opacity layers on --eh-bg)
ST.C = {
    bg          = Opaque(B.bg),
    bgElevated  = Opaque(B.bgElevated),
    bgHeader    = Opaque(B.bgHeader),
    border      = Opaque(B.border),
    borderHover = Opaque(B.borderHover),
    borderSoft  = ST.BlendRgb(B.border, B.bg, 0.70),
    accent      = Opaque(B.accent),
    text        = Opaque(B.text),
    textDim     = Opaque(B.textDim),
    textMuted   = Opaque(B.textMuted),
    elementBg   = Opaque(B.elementBg),
    navBg         = ST.BlendRgb(B.bgHeader, B.bg, 0.85),
    sidebarBg     = ST.BlendRgb(B.bgElevated, B.bg, 0.40),
    mainBg        = ST.BlendRgb(B.bg, B.bg, 0.20),
    tabBarBg      = ST.BlendRgb(B.bgElevated, B.bg, 0.20),
    tierRowBg     = ST.BlendRgb(B.bg, B.bg, 0.40),
    statCellBg    = ST.BlendRgb(B.bg, ST.BlendRgb(B.bgElevated, B.bg, 0.40), 0.80),
    accentBg10    = ST.BlendRgb(B.accent, B.bg, 0.10),
    accentBg12    = ST.BlendRgb(B.accent, B.bg, 0.12),
    accentBg18    = ST.BlendRgb(B.accent, B.bg, 0.18),
    accentBorder30 = ST.BlendRgb(B.accent, B.border, 0.30),
    accentBorder35 = ST.BlendRgb(B.accent, B.border, 0.35),
    accentBorder55 = ST.BlendRgb(B.accent, B.border, 0.55),
    emptySlotBg   = ST.BlendRgb(B.bg, ST.BlendRgb(B.bgElevated, B.bg, 0.40), 0.60),
    chipBg        = ST.BlendRgb(B.bgHeader, B.bg, 0.92),
    accentGlow    = ST.BlendRgb(B.accent, B.bg, 0.45),
    shadow        = { 0, 0, 0, 0.35 },
    success       = { 74/255, 222/255, 128/255 },
    successBg10   = ST.BlendRgb({ 74/255, 222/255, 128/255 }, B.bg, 0.10),
    successBorder30 = ST.BlendRgb({ 74/255, 222/255, 128/255 }, B.border, 0.30),
    rankBadge     = { 230/255, 200/255, 74/255 },
    rankBadgeBg   = ST.BlendRgb({ 230/255, 200/255, 74/255 }, B.bg, 0.10),
    rankBadgeBorder = ST.BlendRgb({ 230/255, 200/255, 74/255 }, B.border, 0.40),
    dollInset     = ST.BlendRgb({ 0, 0, 0 }, B.bg, 0.35),
}

ST.TIER_META = {
    { id = "S", label = "S", desc = "Must have", color = {246/255, 200/255, 67/255} },
    { id = "A", label = "A", desc = "Good",      color = {200/255, 124/255, 255/255} },
    { id = "B", label = "B", desc = "Decent",    color = { 94/255, 174/255, 255/255} },
    { id = "F", label = "F", desc = "Banned",    color = {107/255, 107/255, 122/255} },
}

ST.CLASS_DISPLAY = {
    WARRIOR = "Warrior", PALADIN = "Paladin", HUNTER = "Hunter", ROGUE = "Rogue",
    PRIEST = "Priest", DEATHKNIGHT = "Death Knight", SHAMAN = "Shaman",
    MAGE = "Mage", WARLOCK = "Warlock", DRUID = "Druid",
}

ST.CLASS_COLORS = {
    WARRIOR     = { 0.78, 0.61, 0.43 },
    PALADIN     = { 0.96, 0.55, 0.73 },
    HUNTER      = { 0.67, 0.83, 0.45 },
    ROGUE       = { 1.0,  0.96, 0.41 },
    PRIEST      = { 1.0,  1.0,  1.0  },
    DEATHKNIGHT = { 0.77, 0.12, 0.23 },
    SHAMAN      = { 0.0,  0.44, 0.87 },
    MAGE        = { 0.41, 0.8,  0.94 },
    WARLOCK     = { 0.58, 0.51, 0.79 },
    DRUID       = { 1.0,  0.49, 0.04 },
}

ST.QUALITY_BORDER = {
    [0] = { 1.0, 1.0, 1.0 },
    [1] = { 25/255, 1.0, 25/255 },
    [2] = { 0.0, 102/255, 1.0 },
    [3] = { 204/255, 102/255, 1.0 },
    [4] = { 1.0, 128/255, 0.0 },
}

function ST.BrightenColor(c, amount)
    amount = amount or 0.12
    return {
        math.min(1, c[1] + amount),
        math.min(1, c[2] + amount),
        math.min(1, c[3] + amount),
    }
end

function ST.DarkenColor(c, factor)
    factor = factor or 0.45
    return { c[1] * factor, c[2] * factor, c[3] * factor }
end

function ST.ClassTint(classColor, alpha, baseRgb)
    baseRgb = baseRgb or B.bg
    return ST.BlendRgb(classColor, baseRgb, alpha)
end

-- Matches site: linear-gradient(180deg, classTint(color, 0.14) 0%, transparent 100%)
-- on sidebar bg. WoW uses pre-blended opaque stops (no real alpha compositing).
function ST.ApplyClassBackgroundGradient(tex, classColor, baseRgb)
    baseRgb = baseRgb or B.bg
    local top = ST.ClassTint(classColor, 0.14, baseRgb)
    local bottom = { baseRgb[1], baseRgb[2], baseRgb[3], 1.00 }
    tex:SetTexture(ST.FLAT)
    tex:SetGradientAlpha("VERTICAL",
        top[1], top[2], top[3], 1.00,
        bottom[1], bottom[2], bottom[3], 1.00)
end

function ST.ApplyClassStripe(tex, classColor)
    tex:SetTexture(ST.FLAT)
    tex:SetVertexColor(classColor[1], classColor[2], classColor[3], 1.00)
end

function ST.SpecIndex(classToken, specNameOrIndex)
    if type(specNameOrIndex) == "number" then return specNameOrIndex end
    local specs = EbonholdHub.SpecData and EbonholdHub.SpecData[classToken]
    if not specs then return 1 end
    for i, entry in ipairs(specs) do
        if entry.name == specNameOrIndex then return i end
    end
    return 1
end

function ST.SpecDisplay(classToken, specNameOrIndex)
    local idx = ST.SpecIndex(classToken, specNameOrIndex)
    local specs = EbonholdHub.SpecData and EbonholdHub.SpecData[classToken]
    local entry = specs and specs[idx]
    return entry and entry.name or "", entry and entry.icon
end
