---@diagnostic disable: undefined-field, undefined-global
local _, namespace = ...

local WTUI = namespace.WildThingsUI
local Theme = namespace.Theme

local WINDOW_BG_BOTTOM = Theme.WINDOW_BG_BOTTOM
local WINDOW_BG_HOVER = Theme.WINDOW_BG_HOVER

-- UI/Widgets/ChromeWindow.lua
--
-- Phase 54 primitive: namespace:CreateChromeWindow(name, opts).
--
-- Single-call reusable chrome for any WTUI window -- titlebar (logo, two-tone
-- title, variable right-hand IconButton strip, divider, hover retint), status
-- bar (settable left/right captions), rounded panel, content host, drag, raise,
-- Escape-close, position persistence, off-screen clamping. Caller writes no
-- chrome code.
--
-- Titles are short labels, not free text. The primitive applies no truncation
-- and no width limit -- a long title grows rightward into the titlebar button
-- strip and the caller owns that collision.
--
-- Status-bar captions are likewise short, independently anchored to opposite
-- edges with no collision handling.
--
-- Name is REQUIRED -- the primitive carries NO default-name fallback. A shared
-- fallback would silently cross-contaminate two windows' saved positions in
-- WTUI.frameSettings. CreateShell keeps its own "name = name or \"WildThingsShell\""
-- line exactly as today; this primitive asserts instead.

function namespace:CreateChromeWindow(name, opts)
    opts = opts or {}
    assert(name, "CreateChromeWindow requires an explicit name (no default fallback)")

    -- exitable=false: Window.lua must never auto-add its legacy exit-cross button (the
    --   shell supplies its own close IconButton); movable=true: required so
    --   window.moverFrame exists (the titlebar mounts into it); resizable is caller-supplied.
    local window = namespace:CreateWindow(name, false, true, opts.resizable)

    -- Drag-leak backstop (WR-03 review fix): the titlebar close button and the global
    -- Escape-key handler (WindowRaiser.lua) both call window:Hide() directly on this outer
    -- frame -- a third ancestor boundary above any consumer root. WoW does not propagate
    -- OnHide to descendants of a hidden ancestor. Force-cancel any in-flight drag here too;
    -- CancelActiveDrag() is a no-op when nothing is being dragged, so this is harmless when
    -- the hide happens with no drag active.
    window:HookScript("OnHide", function()
        WTUI:CancelActiveDrag()
    end)

    -- Grow the drag hit-region to the full titlebar height. OnMouseDown/OnMouseUp ->
    -- StartMoving/StopMovingOrSizing handlers are untouched.
    window.moverFrame:SetHeight(Theme.H_TITLEBAR)

    -- Titlebar fill: a selective 2-corner rounded fill (AddRoundedFill with
    -- {TopLeft, TopRight}) so its top edge traces the same 8px arc as the window's own
    -- rounded corners beneath it. window.moverFrame is a child frame of window at
    -- a higher frame level, so its regions always draw in front of window's regions
    -- regardless of layer name -- the previous opaque plain-rect fill painted a hard square
    -- over window's rounded top corners no matter what layer it used (27-REVIEW WR-01).
    -- Giving moverFrame's own fill the identical masked cutout as window's fill (same radius,
    -- same corner anchor, frames flush at the top edge) makes both frames transparent at the
    -- same pixels near the shared corner, reading as one continuous rounded edge. Bottom
    -- corners stay square -- that's the titlebar/content seam, not a window corner.
    -- AddRoundedFill hardcodes the "BACKGROUND" layer for all 7 fill textures, which always
    -- draws before the "ARTWORK" logo/title/close siblings on the same frame -- satisfying
    -- the old under-content pin more robustly than the previous SetDrawLayer("ARTWORK", -1)
    -- hack, which is no longer needed.
    WTUI:AddRoundedFill(window.moverFrame, Theme.RADIUS_LG, WINDOW_BG_BOTTOM, {TopLeft = true, TopRight = true})

    -- Neutralize the base Window.lua drag texture (moverFrame.tex): a plain SQUARE opaque rect
    -- on the SAME BACKGROUND layer, created BEFORE this rounded fill, so the fill's transparent
    -- corner triangles reveal moverFrame.tex behind them and the top corners read square. It
    -- also fights the hover: Window.lua's own moverFrame OnEnter/OnLeave darken moverFrame.tex
    -- independently, so hovering the close button (which fires moverFrame's OnLeave) darkened
    -- the square tex while the rounded fill stayed lit -> a 2-tone titlebar with the arc peeking
    -- out. Hide it; the rounded fill IS the titlebar visual now, and drag stays on moverFrame
    -- itself, so hiding the texture is purely cosmetic-safe. (SetColorTexture from Window.lua's
    -- hover handlers does not re-show a hidden texture, so it stays hidden.)
    window.moverFrame.tex:Hide()

    -- Bottom divider: a 1px BORDER_STRONG hairline at the moverFrame's bottom marks the
    -- titlebar/content seam across the full width, framing the centered logo/title/buttons
    -- as a defined bar.
    window.titlebarDivider = window.moverFrame:CreateTexture(nil, "ARTWORK")
    window.titlebarDivider:SetHeight(1)
    window.titlebarDivider:SetColorTexture(Theme.BORDER_STRONG.r, Theme.BORDER_STRONG.g, Theme.BORDER_STRONG.b, Theme.BORDER_STRONG.a)
    window.titlebarDivider:SetPoint("BOTTOMLEFT", window.moverFrame, "BOTTOMLEFT")
    window.titlebarDivider:SetPoint("BOTTOMRIGHT", window.moverFrame, "BOTTOMRIGHT")
    window.titlebarDivider:SetSnapToPixelGrid(false)
    window.titlebarDivider:SetTexelSnappingBias(0)

    -- Drag-strip hover: the same WINDOW_BG_BOTTOM -> WINDOW_BG_HOVER lightening
    -- runs on the now-hidden moverFrame.tex, re-applied via SetRoundedFillColor (installed by
    -- AddRoundedFill above) so it retints all 7 rounded-fill textures at once. HookScript (not
    -- SetScript) preserves moverFrame's existing OnEnter/OnLeave and OnMouseDown/OnMouseUp
    -- drag handlers.
    local function ShowTitlebarHover()
        window.moverFrame:SetRoundedFillColor(WINDOW_BG_HOVER.r, WINDOW_BG_HOVER.g, WINDOW_BG_HOVER.b, WINDOW_BG_HOVER.a)
    end
    local function HideTitlebarHover()
        window.moverFrame:SetRoundedFillColor(WINDOW_BG_BOTTOM.r, WINDOW_BG_BOTTOM.g, WINDOW_BG_BOTTOM.b, WINDOW_BG_BOTTOM.a)
    end
    window.moverFrame:HookScript("OnEnter", ShowTitlebarHover)
    window.moverFrame:HookScript("OnLeave", HideTitlebarHover)

    -- Titlebar content: Wild Things logo, two-tone title, close IconButton.
    -- All mounted as children of window.moverFrame so dragging the full 48px zone still
    -- works via the unchanged OnMouseDown/OnMouseUp handlers.
    local logo = window.moverFrame:CreateTexture(nil, "ARTWORK")
    logo:SetTexture("Interface\\AddOns\\WildThings\\Media\\Icons\\icon_big")
    logo:SetSize(22, 22)
    logo:SetSnapToPixelGrid(false)
    logo:SetTexelSnappingBias(0)
    logo:SetPoint("LEFT", window.moverFrame, "LEFT", Theme.PAD_WINDOW, 0)

    local titleAccent = window.moverFrame:CreateFontString(nil, "ARTWORK")
    titleAccent:SetFontObject(WildThingsFont13)
    titleAccent:SetText(opts.titleAccent or "")
    titleAccent:SetTextColor(Theme.ACCENT.r, Theme.ACCENT.g, Theme.ACCENT.b, Theme.ACCENT.a)
    titleAccent:SetPoint("LEFT", logo, "RIGHT", Theme.GAP, 0)

    local titleDim = window.moverFrame:CreateFontString(nil, "ARTWORK")
    titleDim:SetFontObject(WildThingsFont13)
    titleDim:SetText(opts.titleDim or "")
    titleDim:SetTextColor(Theme.TEXT_DIM.r, Theme.TEXT_DIM.g, Theme.TEXT_DIM.b, Theme.TEXT_DIM.a)
    titleDim:SetPoint("LEFT", titleAccent, "RIGHT", 4, 0)

    -- Right cluster: close IconButton, built ONLY from CreateIconButton -- the
    -- caller supplies its own close control (exitable=false means Window.lua's legacy
    -- AddButton exit-cross helper is never auto-invoked).
    -- Phase 56 (SUMWIN-02/SUMWIN-06): the titlebar X is the consumer's
    -- responsibility once a secure descendant exists. Per-call-site guards are
    -- forbidden (CR-02 defect class Phase 52 caught twice), so callers route
    -- through a single guarded chokepoint by passing opts.onClose -- a
    -- function that takes no args and returns nothing. CreateShell passes
    -- nothing and keeps today's bare window:Hide() behaviour via the fallback;
    -- SummonScreen.lua passes SafeCloseSummonWindow which gates on
    -- InCombatLockdown() and falls back to pendingClose + ticker pickup.
    local closeBtn = namespace:CreateIconButton(window.moverFrame, "x", opts.onClose or function() window:Hide() end)
    window.closeBtn = closeBtn
    closeBtn:SetPoint("RIGHT", window.moverFrame, "RIGHT", -Theme.GAP, 0)

    -- Keep the titlebar drag-strip hover lit while over the close button -- closeBtn sits
    -- on top of moverFrame, so entering it fires moverFrame's OnLeave and the strip would
    -- otherwise flicker dark right under the cursor.
    closeBtn:HookScript("OnEnter", ShowTitlebarHover)
    closeBtn:HookScript("OnLeave", function()
        if not window.moverFrame:IsMouseOver() then
            HideTitlebarHover()
        end
    end)

    -- window.titlebarButtons is returned in opts.buttons ORDER (visual left-to-right), but
    -- must be walked in REVERSE when anchoring right-to-left, since each button anchors
    -- relative to the previous one's LEFT edge starting from Close.
    window.titlebarButtons = {}
    local anchorTo = closeBtn
    for i = #(opts.buttons or {}), 1, -1 do
        local def = opts.buttons[i]
        local btn = namespace:CreateIconButton(window.moverFrame, def.stem, def.onClick)
        btn:SetPoint("RIGHT", anchorTo, "LEFT", -Theme.GAP, 0)
        if def.tooltip then WTUI:AddTooltip(btn, def.tooltip) end
        btn:HookScript("OnEnter", ShowTitlebarHover)
        btn:HookScript("OnLeave", function()
            if not window.moverFrame:IsMouseOver() then
                HideTitlebarHover()
            end
        end)
        table.insert(window.titlebarButtons, 1, btn)
        anchorTo = btn
    end

    -- Register for global ESC-close + click-to-raise (CreateWindow defines but never calls
    -- this; skipping it silently breaks ESC-close with no error).
    window:RaiseOnClick()

    -- Deliberate CHROME-07 behaviour addition: clamp the window to the screen. Grouped with
    -- RaiseOnClick because both are always-on registrations the caller cannot opt out of.
    -- SetClampedToScreen does not disturb saved positions: SavePosition reads GetPoint(),
    -- which returns set anchors rather than the clamped rendered position.
    window:SetClampedToScreen(true)

    -- Default/restored geometry.
    if not window:RestorePosition() then
        window:SetPoint("CENTER")
    end
    if not window:RestoreSize() then
        window:SetSize(opts.width or 1200, opts.height or 744)
    end

    -- Status bar: fixed-height zone across the bottom of the window.
    window.statusBar = CreateFrame("Frame", nil, window)
    window.statusBar:SetPoint("BOTTOMLEFT", window, "BOTTOMLEFT")
    window.statusBar:SetPoint("BOTTOMRIGHT", window, "BOTTOMRIGHT")
    window.statusBar:SetHeight(Theme.H_STATUSBAR)

    -- Selective 2-corner rounded fill (bottom corners only) so the strip clips
    -- flush inside the window's own rounded bottom corners instead of showing a square
    -- translucent peek over the arc. No hover state on the statusbar, so the one-shot color
    -- argument is sufficient (no SetRoundedFillColor call needed here).
    WTUI:AddRoundedFill(window.statusBar, Theme.RADIUS_LG, Theme.STRIP_BG, {BottomLeft = true, BottomRight = true})

    window.statusBar.leftText = window.statusBar:CreateFontString(nil, "ARTWORK")
    window.statusBar.leftText:SetFontObject(WildThingsFont13)
    window.statusBar.leftText:SetTextColor(Theme.TEXT_SECTION.r, Theme.TEXT_SECTION.g, Theme.TEXT_SECTION.b, Theme.TEXT_SECTION.a)
    window.statusBar.leftText:SetPoint("LEFT", window.statusBar, "LEFT", Theme.PAD_WINDOW, 0)
    window.statusBar.leftText:SetText(opts.statusLeft or "")

    window.statusBar.rightText = window.statusBar:CreateFontString(nil, "ARTWORK")
    window.statusBar.rightText:SetFontObject(WildThingsFont13)
    window.statusBar.rightText:SetTextColor(Theme.TEXT_DIM.r, Theme.TEXT_DIM.g, Theme.TEXT_DIM.b, Theme.TEXT_DIM.a)
    window.statusBar.rightText:SetPoint("RIGHT", window.statusBar, "RIGHT", -Theme.PAD_WINDOW, 0)
    window.statusBar.rightText:SetText(opts.statusRight or "")

    function window:SetStatusLeft(text)
        window.statusBar.leftText:SetText(text or "")
    end
    function window:SetStatusRight(text)
        window.statusBar.rightText:SetText(text or "")
    end

    -- Content host: all four points are window-relative so a chrome-only consumer
    -- does not need to provide a sidebar. A consumer with a sidebar may re-anchor
    -- the left edge after construction; clipping remains the consumer's responsibility.
    window.contentHost = CreateFrame("Frame", nil, window)
    window.contentHost:SetPoint("TOPLEFT", window, "TOPLEFT", 0, -Theme.H_TITLEBAR)
    window.contentHost:SetPoint("TOPRIGHT", window, "TOPRIGHT", 0, -Theme.H_TITLEBAR)
    window.contentHost:SetPoint("BOTTOMLEFT", window, "BOTTOMLEFT", 0, Theme.H_STATUSBAR)
    window.contentHost:SetPoint("BOTTOMRIGHT", window, "BOTTOMRIGHT", 0, Theme.H_STATUSBAR)

    return window
end
