--[[
============================================================================
ERB/UI/MainFrame/Selection.lua  (added in v15.3.0 — Audit Batch 4 Part 3)
============================================================================

User-interaction routing for the ERB MainFrame orchestrator. Owner-pattern:
each method takes `owner` (the MF orchestrator) as first argument.

Methods owned here (4):
  SelectSlot         — user clicked a slot button on the left sidebar:
                       updates highlighting, fires UpdateDisplay
  UpdateSpecButtons  — rebuilds the spec-selector buttons in the top bar
                       (called on initial show + when spec changes)
  UpdatePhaseTabs    — rebuilds the phase-tab buttons in the top bar
                       (toggle between Tier sources)
  UpdateSlotCounts   — refresh the per-slot collection counts shown on the
                       sidebar buttons

External dependencies pulled from owner (the MF orchestrator):
  owner.frame, owner.slotButtons, owner.specButtons, owner.phaseTabs
  owner.currentSlot — written by SelectSlot, read by Display:UpdateDisplay
  owner:Refresh, owner:UpdateDisplay, owner:UpdateSpecButtons,
  owner:UpdatePhaseTabs, owner:UpdateSlotCounts — internal cross-method calls
  owner.RANK_COLORS — referenced in UpdateSpecButtons styling

Closure / shadowing notes:
  - 1 `function(self,...)` script handler in UpdateSpecButtons (the btn OnEnter
    at line 98). The closure `self` is the button being hovered, NOT the
    orchestrator. Pre-extraction we renamed it to `widget` so the global
    `self → owner` transform stays correct.
============================================================================
]]--
local ADDON_NAME, NS = ...
local ETB = NS.ETB
local ERB = ETB and ETB.ERB
if not ERB then return end

NS.ETB.ERB.MainFrame = NS.ETB.ERB.MainFrame or {}
NS.ETB.ERB.MainFrame.Selection = NS.ETB.ERB.MainFrame.Selection or {}
local Selection = NS.ETB.ERB.MainFrame.Selection

-- =============================================================================
-- METHODS (extracted from ERB/UI/MainFrame.lua in v15.3.0)
-- =============================================================================

function Selection:SelectSlot(owner, slot)
    if not ERB.DataBridge then return end
    ERB.DataBridge.currentSlot = slot

    for s, btn in pairs(owner.slotButtons) do
        if s == slot then
            btn.selected:Show()
            btn.label:SetText("|cff00ff00" .. s .. "|r")
        else
            btn.selected:Hide()
            btn.label:SetText(s)
        end
    end

    -- Pre-cache all items for this slot so names resolve before display
    local phase = ERB.DataBridge:GetCurrentPhase()
    local items = ERB.DataBridge:GetItemsForSlot(slot, phase)
    local uncached = 0
    for _, item in ipairs(items) do
        local name = GetItemInfo(item.itemID)
        if not name then uncached = uncached + 1 end
    end

    -- Reset refresh counter so event-driven refreshes work for this slot
    if owner.frame then
        owner.frame._refreshCount = 0
        owner.frame._refreshPending = false
    end

    owner:UpdateDisplay()
    
    -- If any items were uncached, schedule refreshes as they load
    if uncached > 0 then
        C_Timer.After(0.4, function()
            if owner.frame and owner.frame:IsShown() then
                owner:UpdateDisplay()
            end
        end)
        C_Timer.After(1.0, function()
            if owner.frame and owner.frame:IsShown() then
                owner:UpdateDisplay()
            end
        end)
    end
end

-- ============================================================================
-- SPEC SELECTOR BUTTONS
-- ============================================================================
--
-- Note: owner.specButtons = {} is initialized at file scope in MainFrame.lua
-- (the orchestrator). It is NOT initialized here, since at file-load time
-- of this submodule, `owner` does not yet exist.

function Selection:UpdateSpecButtons(owner)
    -- v15.7.5: pool/reuse pattern. Previously this function created brand-new
    -- buttons every call without releasing the old ones. Old buttons were
    -- hidden but the parent-child relationship kept them in memory anyway —
    -- WoW frames cannot be destroyed once created. Across a session with many
    -- spec switches (or many ERB browser open/closes), this leaked buttons
    -- linearly. Pool the buttons; only CreateFrame when we need MORE than
    -- the existing pool, otherwise reuse and re-style.

    if not ERB.DataBridge then
        -- Hide all pool buttons defensively (no specs available)
        for _, btn in ipairs(owner.specButtons) do btn:Hide() end
        return
    end
    local specs = ERB.DataBridge:GetAvailableSpecs()
    if #specs <= 1 then
        for _, btn in ipairs(owner.specButtons) do btn:Hide() end
        return  -- no point showing selector for single-spec
    end

    local container = owner.frame.specButtonContainer
    local xOff = 0

    for i, spec in ipairs(specs) do
        local btn = owner.specButtons[i]
        if not btn then
            -- Pool-miss: create a new button and append to pool
            btn = CreateFrame("Button", nil, container)

            local bg = btn:CreateTexture(nil, "BACKGROUND")
            bg:SetAllPoints()
            btn.bg = bg

            local txt = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            txt:SetPoint("CENTER")
            btn.txt = txt

            btn:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square", "ADD")
            owner.specButtons[i] = btn
        end

        -- Re-style for the current spec (always — pool may be reused across specs)
        btn:SetSize(math.max(70, #spec.name * 7 + 16), 20)
        btn:ClearAllPoints()
        btn:SetPoint("LEFT", xOff, 0)
        if spec.isActive then
            btn.bg:SetColorTexture(0.2, 0.5, 0.2, 0.8)
            btn.txt:SetText("|cffffffff" .. spec.name .. "|r")
        else
            btn.bg:SetColorTexture(0.15, 0.15, 0.15, 0.5)
            btn.txt:SetText("|cff888888" .. spec.name .. "|r")
        end

        local specIdx = spec.idx
        btn:SetScript("OnClick", function()
            if ERB.DataBridge:SwitchSpec(specIdx) then
                ERB.equipped = ERB:ScanEquipment()
                owner:Refresh()
                owner:SelectSlot(ERB.DataBridge.currentSlot or "Head")
            end
        end)

        btn:SetScript("OnEnter", function(widget)
            GameTooltip:SetOwner(widget, "ANCHOR_BOTTOM")
            GameTooltip:AddLine(spec.name)
            if spec.isActive then
                GameTooltip:AddLine("|cff00ff00Currently viewing|r", 1, 1, 1)
            else
                GameTooltip:AddLine("Click to view BiS for this spec", 1, 1, 1)
            end
            GameTooltip:Show()
        end)
        btn:SetScript("OnLeave", function() GameTooltip:Hide() end)

        btn:Show()
        xOff = xOff + btn:GetWidth() + 4
    end

    -- Hide any leftover pool buttons beyond the active spec count (e.g. if
    -- the player switched from a class with 4 specs to one with 3)
    for i = #specs + 1, #owner.specButtons do
        owner.specButtons[i]:Hide()
    end
end

-- ============================================================================
-- UPDATE PHASE TABS
-- ============================================================================

function Selection:UpdatePhaseTabs(owner)
    -- v15.7.5: pool/reuse pattern. Same memory-leak fix as UpdateSpecButtons.
    -- Previously created a new tab per phase per call; pool grew unbounded.

    if not ERB.DataBridge then
        for _, tab in ipairs(owner.phaseTabs) do tab:Hide() end
        return
    end

    local phases = ERB.DataBridge:GetPhases()
    local container = owner.frame.phaseContainer
    local xOff = 0

    for i, phase in ipairs(phases) do
        local name = ERB.DataBridge:GetPhaseName(phase)
        local active = (phase == ERB.DataBridge:GetCurrentPhase())

        local tab = owner.phaseTabs[i]
        if not tab then
            tab = CreateFrame("Button", nil, container)

            local bg = tab:CreateTexture(nil, "BACKGROUND")
            bg:SetAllPoints()
            tab.bg = bg

            local txt = tab:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            txt:SetPoint("CENTER")
            tab.txt = txt

            owner.phaseTabs[i] = tab
        end

        -- Re-style every call: active state and phase identity can change
        tab:SetSize(math.max(80, #name * 7 + 24), 20)
        tab:ClearAllPoints()
        tab:SetPoint("LEFT", xOff, 0)
        tab.bg:SetColorTexture(active and 0.2 or 0.1, active and 0.4 or 0.1, active and 0.7 or 0.1, active and 0.9 or 0.4)
        tab.txt:SetText(active and ("|cffffffff" .. name .. "|r") or ("|cff888888" .. name .. "|r"))

        tab:SetScript("OnClick", function()
            ERB.DataBridge:SetPhase(phase)
            owner:Refresh()
            owner:SelectSlot(ERB.DataBridge.currentSlot or "Head")
        end)
        -- The active flag is captured at SetScript time; rebind it every call
        tab:SetScript("OnEnter", function(s) if not active then s.bg:SetColorTexture(0.2, 0.2, 0.3, 0.6) end end)
        tab:SetScript("OnLeave", function(s) if not active then s.bg:SetColorTexture(0.1, 0.1, 0.1, 0.4) end end)

        tab:Show()
        xOff = xOff + tab:GetWidth() + 4
    end

    -- Hide leftover pool tabs (in case the phase list ever shrinks)
    for i = #phases + 1, #owner.phaseTabs do
        owner.phaseTabs[i]:Hide()
    end
end

-- ============================================================================
-- UPDATE SIDEBAR COUNTS
-- ============================================================================

function Selection:UpdateSlotCounts(owner)
    if not ERB.DataBridge then return end
    local counts = ERB.DataBridge:GetAllSlotCounts()
    for slot, btn in pairs(owner.slotButtons) do
        local count = counts[slot] or 0
        btn.countLabel:SetText(count > 0 and ("|cff888888" .. count .. "|r") or "")
    end
end

