-- =============================================================================
-- ETB v12.55.0 — UI/Windows/SetsUI/Sources.lua
-- =============================================================================
-- First SetsUI submodule. Owns the Sources Modal: a popup that shows which
-- items satisfy each slot of the currently-selected set, including
-- alternatives, and which are already collected.
--
-- This is the most self-contained cluster in SetsUI.lua (only 3 methods,
-- ~215 lines, no shared state with other SetsUI clusters except
-- selectedSetID and the sourcesModal handle on the owner). Good first
-- extraction to validate the submodule pattern works for SetsUI.
--
-- Public API (all take owner = SetsUI singleton as first arg):
--   Sources:ShowSetSources(owner)
--   Sources:CreateSourcesModal(owner)
--   Sources:PopulateSourcesModal(owner, setID, setInfo)
--
-- Owner contract — fields read/written:
--   owner.selectedSetID  (read-only)
--   owner.sourcesModal   (read/write — created on first ShowSetSources)
--
-- Globals/Blizzard:
--   CreateFrame, UIParent
--   GetItemInfoInstant
--   ETB.SetsData (GetSetInfo, GetSetCompletion, GetSlotCompletionDetails)
-- =============================================================================

local ADDON_NAME, NS = ...
local ETB = NS.ETB

NS.ETB.SetsUI = NS.ETB.SetsUI or ETB.SetsUI or {}
local Sources = {}
NS.ETB.SetsUI.Sources = Sources

function Sources:ShowSetSources(owner)
    if not owner.selectedSetID then return end

    local setID = owner.selectedSetID
    local setInfo = ETB.SetsData:GetSetInfo(setID)
    if not setInfo then return end

    -- Create modal if it doesn't exist
    if not owner.sourcesModal then
        Sources:CreateSourcesModal(owner)
    end

    -- Populate with set sources
    Sources:PopulateSourcesModal(owner, setID, setInfo)
    owner.sourcesModal:Show()
end

function Sources:CreateSourcesModal(owner)
    local modal = CreateFrame("Frame", "ETBSetSourcesModal", UIParent, "BackdropTemplate")
    modal:SetSize(450, 500)
    modal:SetPoint("CENTER")
    modal:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
        tile = true, tileSize = 32, edgeSize = 32,
        insets = { left = 8, right = 8, top = 8, bottom = 8 }
    })
    modal:SetMovable(true)
    modal:EnableMouse(true)
    modal:RegisterForDrag("LeftButton")
    modal:SetScript("OnDragStart", modal.StartMoving)
    modal:SetScript("OnDragStop", modal.StopMovingOrSizing)
    modal:SetFrameStrata("DIALOG")
    modal:Hide()

    -- Title
    modal.title = modal:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    modal.title:SetPoint("TOP", 0, -15)
    modal.title:SetText("Set Sources")

    -- Close button
    modal.closeBtn = CreateFrame("Button", nil, modal, "UIPanelCloseButton")
    modal.closeBtn:SetPoint("TOPRIGHT", -5, -5)

    -- Scroll frame for sources
    modal.scrollFrame = CreateFrame("ScrollFrame", nil, modal, "UIPanelScrollFrameTemplate")
    modal.scrollFrame:SetPoint("TOPLEFT", 15, -45)
    modal.scrollFrame:SetPoint("BOTTOMRIGHT", -35, 15)

    modal.scrollChild = CreateFrame("Frame", nil, modal.scrollFrame)
    modal.scrollChild:SetSize(400, 1)
    modal.scrollFrame:SetScrollChild(modal.scrollChild)

    modal.slotFrames = {}

    owner.sourcesModal = modal
end

function Sources:PopulateSourcesModal(owner, setID, setInfo)
    local modal = owner.sourcesModal
    if not modal then return end

    -- Get completion info
    local collected, total = ETB.SetsData:GetSetCompletion(setID)
    local remaining = total - collected

    -- Update title with completion info
    if remaining == 0 then
        modal.title:SetText("|cff00ff00" .. setInfo.name .. " - COMPLETE!|r")
    else
        modal.title:SetText(setInfo.name .. " |cffffd100(" .. remaining .. " slots needed)|r")
    end

    -- Clear existing content
    for _, frame in ipairs(modal.slotFrames) do
        frame:Hide()
        if frame.items then
            for _, item in ipairs(frame.items) do
                item:Hide()
            end
        end
    end

    -- Get detailed slot info
    local slotDetails = ETB.SetsData:GetSlotCompletionDetails(setID)

    local yOffset = 0
    local slotIndex = 0

    for _, slot in ipairs(slotDetails) do
        slotIndex = slotIndex + 1

        -- Create slot frame if needed
        local slotFrame = modal.slotFrames[slotIndex]
        if not slotFrame then
            slotFrame = CreateFrame("Frame", nil, modal.scrollChild, "BackdropTemplate")
            slotFrame:SetSize(390, 20)
            modal.slotFrames[slotIndex] = slotFrame

            -- Background for incomplete slots
            slotFrame.bg = slotFrame:CreateTexture(nil, "BACKGROUND")
            slotFrame.bg:SetAllPoints()

            -- Slot header
            slotFrame.header = slotFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
            slotFrame.header:SetPoint("TOPLEFT", 5, -3)

            -- Items container
            slotFrame.items = {}
        end

        slotFrame:SetPoint("TOPLEFT", 5, -yOffset)

        -- Set background based on completion
        if slot.isComplete then
            slotFrame.bg:SetColorTexture(0.1, 0.3, 0.1, 0.3)  -- Green tint
        else
            slotFrame.bg:SetColorTexture(0.3, 0.1, 0.1, 0.3)  -- Red tint - needs attention!
        end

        -- Slot header with clear status
        local statusIcon = slot.isComplete and "|cff00ff00✓|r" or "|cffff4444✗ NEED:|r"
        local optionsText = ""
        if not slot.isComplete and slot.totalOptions > 1 then
            optionsText = " |cff888888(any of " .. slot.totalOptions .. " items)|r"
        end
        slotFrame.header:SetText(statusIcon .. " |cffffd100" .. slot.slotName .. "|r" .. optionsText)

        yOffset = yOffset + 22

        -- Show items for this slot
        local allItems = {slot.primary}
        if slot.alternatives then
            for _, alt in ipairs(slot.alternatives) do
                table.insert(allItems, alt)
            end
        end

        local itemIndex = 0
        for _, item in ipairs(allItems) do
            itemIndex = itemIndex + 1

            local itemFrame = slotFrame.items[itemIndex]
            if not itemFrame then
                itemFrame = CreateFrame("Frame", nil, modal.scrollChild)
                itemFrame:SetSize(380, 22)
                slotFrame.items[itemIndex] = itemFrame

                -- Icon
                itemFrame.icon = itemFrame:CreateTexture(nil, "ARTWORK")
                itemFrame.icon:SetSize(20, 20)
                itemFrame.icon:SetPoint("LEFT", 25, 0)

                -- Name
                itemFrame.name = itemFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
                itemFrame.name:SetPoint("LEFT", itemFrame.icon, "RIGHT", 5, 0)
                itemFrame.name:SetWidth(240)
                itemFrame.name:SetJustifyH("LEFT")

                -- Status
                itemFrame.status = itemFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
                itemFrame.status:SetPoint("RIGHT", -10, 0)
            end

            itemFrame:SetPoint("TOPLEFT", 0, -yOffset)

            -- Set icon
            if item.icon then
                itemFrame.icon:SetTexture(item.icon)
            elseif item.itemID then
                local _, _, _, _, iconPath = GetItemInfoInstant(item.itemID)
                itemFrame.icon:SetTexture(iconPath or "Interface\\Icons\\INV_Misc_QuestionMark")
            end

            -- Set name with quality color and collection status
            local nameColor
            if item.collected then
                nameColor = "|cff00ff00"  -- Green for collected
            elseif not slot.isComplete then
                nameColor = "|cffff8800"  -- Orange for NEEDED items
            else
                nameColor = "|cff888888"  -- Gray for not needed (slot already filled)
            end
            itemFrame.name:SetText(nameColor .. (item.name or "Unknown") .. "|r")

            -- Status text
            if item.collected then
                itemFrame.status:SetText("|cff00ff00✓ Collected|r")
            elseif not slot.isComplete then
                itemFrame.status:SetText("|cffff6600← Get this!|r")
            else
                itemFrame.status:SetText("|cff666666(not needed)|r")
            end

            itemFrame:Show()
            yOffset = yOffset + 22
        end

        -- Hide unused item frames
        for i = itemIndex + 1, #slotFrame.items do
            slotFrame.items[i]:Hide()
        end

        slotFrame:Show()
        yOffset = yOffset + 8  -- Gap between slots
    end

    -- Update scroll child height
    modal.scrollChild:SetHeight(yOffset + 20)
end
