-- zAddonFramework/zAF_Chrome.lua
-- Panel chrome utilities: tooltip system, gradient border, and section header.
-- Stateless display helpers.
-- Depends on zAF_Primitives (zAF_FillBG, zAF_DrawBorder, zAF_DisablePixelSnap).
local ZAF = _G.ZAF  -- namespace for style constants and easing functions
local NC  = zAF_NormalizeColor
local function CtxPri() local t = ZAF._buildCtx and ZAF._buildCtx._themeColors; return t and t.primary end
local function CtxSec() local t = ZAF._buildCtx and ZAF._buildCtx._themeColors; return t and t.secondary end

-- ── Custom tooltip ───────────────────────────────────────────────────────────

---@type Frame|nil
local _tooltip = nil

local function EnsureTooltip()
    if _tooltip then return end

    local tt = CreateFrame("Frame", nil, UIParent)
    tt:SetFrameStrata("TOOLTIP")
    tt:SetFrameLevel(900)
    tt:SetClampedToScreen(true)
    tt:EnableMouse(false)
    tt:Hide()

    zAF_FillBG(tt, 0, 0, 0, 0.88)

    local titleFS = tt:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    titleFS:SetJustifyH("LEFT")
    titleFS:SetWordWrap(true)
    tt._title = titleFS

    local bodyFS = tt:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    bodyFS:SetJustifyH("LEFT")
    bodyFS:SetWordWrap(true)
    bodyFS:SetTextColor(1, 1, 1, 1)
    bodyFS:SetPoint("TOPLEFT", titleFS, "BOTTOMLEFT", 0, -4)
    tt._body = bodyFS

    _tooltip = tt
end

--- Show a styled tooltip anchored below-left of a region.
--- Title uses the secondary accent colour; body is white.
---@param anchor    Region
---@param titleText string
---@param bodyText  string|nil
---@param secondary table  Colour table { r, g, b[, a] } or ColorMixin.
function zAF_ShowTooltip(anchor, titleText, bodyText, secondary)
    secondary = NC(secondary or CtxSec() or ZAF.DEFAULT_SECONDARY)
    EnsureTooltip()
    local tt = _tooltip

    local W = 230
    tt:SetWidth(W)
    tt._title:SetWidth(W - 20)
    tt._body:SetWidth(W - 20)

    tt._title:SetText(titleText or "")
    tt._title:SetTextColor(secondary[1], secondary[2], secondary[3], 1)
    tt._title:SetPoint("TOPLEFT", tt, "TOPLEFT", 10, -10)

    if bodyText and bodyText ~= "" then
        tt._body:SetText(bodyText)
        tt._body:Show()
    else
        tt._body:Hide()
    end

    -- Draw border using current primary theme colour.
    local _ctx = ZAF._buildCtx
    local pri  = (_ctx and _ctx._themeColors and _ctx._themeColors.primary) or ZAF.DEFAULT_PRIMARY
    zAF_DrawBorder(tt, pri[1], pri[2], pri[3], 1)

    -- Size to fit content.
    local th = tt._title:GetStringHeight()
    local bh = (bodyText and bodyText ~= "" and tt._body:GetStringHeight()) or 0
    tt:SetHeight(10 + th + (bh > 0 and (4 + bh) or 0) + 10)

    tt:ClearAllPoints()
    tt:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 4, -4)
    tt:Show()
end

--- Hide the custom tooltip.
function zAF_HideTooltip()
    if _tooltip then _tooltip:Hide() end
end

--- Wire custom tooltip show/hide to a region.
---@param region    Region
---@param titleText string
---@param bodyText  string|nil
---@param secondary table  Colour table { r, g, b[, a] } or ColorMixin.
function zAF_AddTooltip(region, titleText, bodyText, secondary)
    secondary = NC(secondary or CtxSec() or ZAF.DEFAULT_SECONDARY)
    region:EnableMouse(true)
    region:SetScript("OnEnter", function(self)
        zAF_ShowTooltip(self, titleText, bodyText, secondary)
    end)
    region:SetScript("OnLeave", function() zAF_HideTooltip() end)
end

-- ── Gradient border ──────────────────────────────────────────────────────────

--- Draw (or recolour) a 1px gradient border around a frame.
--- Textures are created once and stored in frame._zsfBorderTextures; subsequent
--- calls simply update the gradient colours without creating new regions.
---@param frame Frame
---@param cTL   table  Colour table { r, g, b[, a] } or ColorMixin for top-left.
---@param cTR   table  Colour table { r, g, b[, a] } or ColorMixin for top-right.
---@param cBL   table  Colour table { r, g, b[, a] } or ColorMixin for bottom-left.
---@param cBR   table  Colour table { r, g, b[, a] } or ColorMixin for bottom-right.
function zAF_DrawGradientBorder(frame, cTL, cTR, cBL, cBR)
    local function toColor(c)
        local n = NC(c)
        return CreateColor(n[1], n[2], n[3], n[4])
    end
    local colTL = toColor(cTL)
    local colTR = toColor(cTR)
    local colBL = toColor(cBL)
    local colBR = toColor(cBR)

    local top, bot, lft, rgt
    local ts = frame._zsfBorderTextures
    if ts then
        top, bot, lft, rgt = ts[1], ts[2], ts[3], ts[4]
    else
        top = frame:CreateTexture(nil, "OVERLAY")
        top:SetColorTexture(1, 1, 1, 1)
        top:SetPoint("TOPLEFT",  frame, "TOPLEFT",  0, 0)
        top:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, 0)
        top:SetHeight(1)

        bot = frame:CreateTexture(nil, "OVERLAY")
        bot:SetColorTexture(1, 1, 1, 1)
        bot:SetPoint("BOTTOMLEFT",  frame, "BOTTOMLEFT",  0, 0)
        bot:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
        bot:SetHeight(1)

        lft = frame:CreateTexture(nil, "OVERLAY")
        lft:SetColorTexture(1, 1, 1, 1)
        lft:SetPoint("TOPLEFT",    frame, "TOPLEFT",    0, -1)
        lft:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 0,  1)
        lft:SetWidth(1)

        rgt = frame:CreateTexture(nil, "OVERLAY")
        rgt:SetColorTexture(1, 1, 1, 1)
        rgt:SetPoint("TOPRIGHT",    frame, "TOPRIGHT",    0, -1)
        rgt:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0,  1)
        rgt:SetWidth(1)

        frame._zsfBorderTextures = { top, bot, lft, rgt }
    end

    top:SetGradient("HORIZONTAL", colTL, colTR)
    bot:SetGradient("HORIZONTAL", colBL, colBR)
    lft:SetGradient("VERTICAL",   colBL, colTL)
    rgt:SetGradient("VERTICAL",   colBR, colTR)
    -- SetGradient re-enables pixel snapping; disable after every call.
    zAF_DisablePixelSnap(top)
    zAF_DisablePixelSnap(bot)
    zAF_DisablePixelSnap(lft)
    zAF_DisablePixelSnap(rgt)
end

-- ── Section header ───────────────────────────────────────────────────────────

--- Section title in the theme primary colour with a secondary trailing rule line.
---@param parent    Frame
---@param text      string
---@param padX      number
---@param primary   table  Colour table { r, g, b[, a] } or ColorMixin for the text.
---@param secondary table  Colour table { r, g, b[, a] } or ColorMixin for the rule line.
function zAF_BuildSectionHeader(parent, text, padX, primary, secondary)
    primary   = NC(primary   or CtxPri() or ZAF.DEFAULT_PRIMARY)
    secondary = NC(secondary or CtxSec() or ZAF.DEFAULT_SECONDARY)
    local ctx = ZAF._buildCtx
    local fo = (ctx and ctx.FONTOBJ_HEADING) or ZAF.FONTOBJ_HEADING or "GameFontNormal"
    local hdr = zAF_Text(parent, fo)
    hdr:SetText(text)
    hdr:SetTextColor(primary[1], primary[2], primary[3])
    hdr:SetPoint("LEFT", parent, "LEFT", padX, 0)

    local sc = secondary or ZAF.COLOR_BORDER
    local line = parent:CreateTexture(nil, "ARTWORK")
    line:SetTexture(zAF_AssetPath("1px.png"))
    line:SetVertexColor(sc[1], sc[2], sc[3])
    line:SetAlpha(0.30)
    PixelUtil.SetHeight(line, 1, 1)
    PixelUtil.SetPoint(line, "LEFT",  hdr,    "RIGHT",  6,     0)
    PixelUtil.SetPoint(line, "RIGHT", parent, "RIGHT",  -padX, 0)
end
