-- =============================================================================
-- ETB v12.52.0 — Modules/SetBuilder/Export.lua
-- =============================================================================
-- First submodule extracted from the SetBuilder monolith. Owns three
-- conceptually-related responsibilities:
--
-- 1. SET MANIPULATION — AddToSet, RemoveFromSlot, ClearCurrentSet
--    Mutates owner.currentSet. Triggers display refresh callbacks on owner.
--
-- 2. DISPLAY SYNC — UpdateSetDisplay, UpdateExportText, GenerateExportText
--    Reads owner.currentSet and pushes to widgets stored on owner.
--
-- 3. SERIALIZATION — ExportCurrentSet, SendToETB
--                    SaveSet, LoadSet, DeleteSet, ListSavedSets, UpdateSavedSetsList
--    Reads/writes ETB_SetBuilder_Data SavedVariable. SendToETB calls
--    ETB.CustomSets:ImportFromSetBuilder.
--
-- Public API (all take owner = SB singleton as first arg):
--   Export:AddToSet(owner, item)
--   Export:RemoveFromSlot(owner, slot)
--   Export:ClearCurrentSet(owner)
--   Export:UpdateSetDisplay(owner)
--   Export:UpdateExportText(owner)
--   Export:GenerateExportText(owner)
--   Export:ExportCurrentSet(owner)
--   Export:SendToETB(owner)
--   Export:SaveSet(owner, name)
--   Export:LoadSet(owner, name)
--   Export:DeleteSet(owner, name)
--   Export:ListSavedSets(owner)
--   Export:UpdateSavedSetsList(owner)
--
-- Owner contract — fields read/written:
--   owner.currentSet (.name, .armorType, .source, .expansion, .faction, .items)
--   owner.nameBox, .sourceBox, .embedNameBox, .embedSourceBox
--   owner.slotFrames, .embedSlotFrames
--   owner.exportBox, .savedScrollChild, .savedButtons
--   owner.mannequin
--
-- Owner-exposed file-locals:
--   owner.SLOT_NAMES, owner.EXPANSION_NAMES
--
-- Owner methods called:
--   owner:UpdateMannequin()  -- still in main SetBuilder.lua
--
-- Globals/Blizzard:
--   ETBDropdown (NS-stored, accessed via NS.ETBDropdown)
--   _G["SBArmorTypeDropdown"], _G["SBExpansionDropdown"]  (legacy globals from CreateSetPanel)
--   ETB_SetBuilder_Data (SavedVariable)
--   CreateFrame
-- =============================================================================

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

NS.ETB.SetBuilder = NS.ETB.SetBuilder or ETB.SetBuilder or {}
local Export = {}
NS.ETB.SetBuilder.Export = Export

local ETBDropdown = NS.ETBDropdown

-- =============================================================================
-- SET MANIPULATION
-- =============================================================================

function Export:AddToSet(owner, item)
    if not item or not item.slot then return end

    local slot = item.slot
    owner.currentSet.items[slot] = {
        itemID = item.itemID,
        name = item.name,
        icon = item.icon,
    }

    -- Auto-detect armor type from first item
    if not owner.currentSet.armorType and item.armorType then
        owner.currentSet.armorType = item.armorType
        if ETBDropdown and _G["SBArmorTypeDropdown"] then
            ETBDropdown:SetText(_G["SBArmorTypeDropdown"], item.armorType)
        end
    end

    Export:UpdateSetDisplay(owner)
    Export:UpdateExportText(owner)
    if owner.UpdateMannequin then owner:UpdateMannequin() end

    ETB:Print(string.format("|cff00ff00[Set Builder]|r Added %s to %s slot.",
        item.name, owner.SLOT_NAMES[slot]))
end

function Export:RemoveFromSlot(owner, slot)
    owner.currentSet.items[slot] = nil
    Export:UpdateSetDisplay(owner)
    Export:UpdateExportText(owner)
    if owner.UpdateMannequin then owner:UpdateMannequin() end
end

function Export:ClearCurrentSet(owner)
    owner.currentSet = {
        name = "Unnamed Set",
        armorType = nil,
        source = "",
        expansion = 0,
        faction = nil,
        items = {},
    }

    if owner.nameBox then owner.nameBox:SetText("Unnamed Set") end
    if owner.sourceBox then owner.sourceBox:SetText("") end
    if owner.embedNameBox then owner.embedNameBox:SetText("Unnamed Set") end
    if owner.embedSourceBox then owner.embedSourceBox:SetText("") end
    if ETBDropdown then
        if _G["SBArmorTypeDropdown"] then ETBDropdown:SetText(_G["SBArmorTypeDropdown"], "Auto-detect") end
        if _G["SBExpansionDropdown"] then ETBDropdown:SetText(_G["SBExpansionDropdown"], "Classic") end
    end

    Export:UpdateSetDisplay(owner)
    Export:UpdateExportText(owner)
    if owner.mannequin and owner.UpdateMannequin then owner:UpdateMannequin() end
end

-- =============================================================================
-- DISPLAY SYNC
-- =============================================================================

function Export:UpdateSetDisplay(owner)
    for slot = 1, 9 do
        if owner.slotFrames then
            local frame = owner.slotFrames[slot]
            if frame then
                local itemData = owner.currentSet.items[slot]
                if itemData then
                    frame.icon:SetTexture(itemData.icon)
                    frame.itemName:SetText(itemData.name)
                    if frame.removeBtn then frame.removeBtn:Show() end
                else
                    frame.icon:SetTexture("Interface\\PaperDoll\\UI-Backpack-EmptySlot")
                    frame.itemName:SetText("|cff888888(empty)|r")
                    if frame.removeBtn then frame.removeBtn:Hide() end
                end
            end
        end
        -- Embedded panel slot rows
        if owner.embedSlotFrames then
            local embedRow = owner.embedSlotFrames[slot]
            if embedRow then
                local itemData = owner.currentSet.items[slot]
                if itemData then
                    embedRow.icon:SetTexture(itemData.icon)
                    embedRow.itemName:SetText(itemData.name or "?")
                else
                    embedRow.icon:SetTexture("Interface\\PaperDoll\\UI-Backpack-EmptySlot")
                    embedRow.itemName:SetText("|cff666666(empty)|r")
                end
            end
        end
    end
    if owner.embedNameBox then
        owner.embedNameBox:SetText(owner.currentSet.name or "Unnamed Set")
    end
    if owner.embedSourceBox then
        owner.embedSourceBox:SetText(owner.currentSet.source or "")
    end
end

function Export:UpdateExportText(owner)
    if not owner.exportBox then return end

    local text = Export:GenerateExportText(owner)
    owner.exportBox:SetText(text)
end

function Export:GenerateExportText(owner)
    local set = owner.currentSet
    local lines = {}

    table.insert(lines, "-- " .. set.name)
    table.insert(lines, "{")
    table.insert(lines, string.format('    setID = "CUSTOM_%s",',
        set.name:upper():gsub("%s+", "_"):gsub("[^%w_]", "")))
    table.insert(lines, string.format('    name = "%s",', set.name))
    table.insert(lines, string.format('    armorType = "%s",', set.armorType or "UNKNOWN"))
    table.insert(lines, string.format('    source = "%s",', set.source or "Unknown"))
    table.insert(lines, string.format('    expansion = %d,', set.expansion or 0))
    table.insert(lines, '    faction = nil,')
    table.insert(lines, '    items = {')

    for slot = 1, 9 do
        local item = set.items[slot]
        if item then
            table.insert(lines, string.format('        [%d] = %d,     -- %s (%s)',
                slot, item.itemID, item.name, owner.SLOT_NAMES[slot]))
        end
    end

    table.insert(lines, '    },')
    table.insert(lines, '},')

    return table.concat(lines, "\n")
end

-- =============================================================================
-- SERIALIZATION — IPC + chat export
-- =============================================================================

function Export:ExportCurrentSet(owner)
    local text = Export:GenerateExportText(owner)

    -- Print to chat
    ETB:Print("|cff00ffff=== EXPORTED SET ===|r")
    for line in text:gmatch("[^\n]+") do
        ETB:Print(line)
    end
    ETB:Print("|cff00ffff=== END EXPORT ===|r")

    -- Also update the export box
    Export:UpdateExportText(owner)

    ETB:Print("|cff00ff00[Set Builder]|r Export complete! Copy from the Export panel or chat.")
end

function Export:SendToETB(owner)
    if not ETB or not ETB.CustomSets then
        ETB:Print("|cffff0000[Set Builder]|r CustomSets not available.")
        return
    end

    local itemCount = 0
    for slot, item in pairs(owner.currentSet.items) do
        if item then
            itemCount = itemCount + 1
        end
    end

    if itemCount == 0 then
        ETB:Print("|cffff0000[Set Builder]|r Cannot send empty set. Add some items first!")
        return
    end

    if not owner.currentSet.name or owner.currentSet.name == "" or owner.currentSet.name == "Untitled Set" then
        ETB:Print("|cffff0000[Set Builder]|r Please name your set first!")
        return
    end

    local success, setID = ETB.CustomSets:ImportFromSetBuilder(owner.currentSet)

    if success then
        ETB:Print("|cff00ff00[Set Builder]|r Set sent to ETB successfully!")
    else
        ETB:Print("|cffff0000[Set Builder]|r Failed to send set to ETB.")
    end
end

-- =============================================================================
-- SAVE/LOAD/DELETE/LIST SETS
-- =============================================================================

function Export:SaveSet(owner, name)
    local setCopy = {
        name = name,
        armorType = owner.currentSet.armorType,
        source = owner.currentSet.source,
        expansion = owner.currentSet.expansion,
        faction = owner.currentSet.faction,
        items = {},
    }

    for slot, item in pairs(owner.currentSet.items) do
        setCopy.items[slot] = {
            itemID = item.itemID,
            name = item.name,
            icon = item.icon,
        }
    end

    ETB_SetBuilder_Data.savedSets[name] = setCopy

    ETB:Print(string.format("|cff00ff00[Set Builder]|r Saved set '%s'.", name))
    Export:UpdateSavedSetsList(owner)
end

function Export:LoadSet(owner, name)
    local savedSet = ETB_SetBuilder_Data.savedSets[name]
    if not savedSet then
        ETB:Print(string.format("|cffff0000[Set Builder]|r Set '%s' not found.", name))
        return
    end

    owner.currentSet = {
        name = savedSet.name,
        armorType = savedSet.armorType,
        source = savedSet.source,
        expansion = savedSet.expansion,
        faction = savedSet.faction,
        items = {},
    }

    for slot, item in pairs(savedSet.items) do
        owner.currentSet.items[slot] = {
            itemID = item.itemID,
            name = item.name,
            icon = item.icon,
        }
    end

    -- Update UI
    if owner.nameBox then owner.nameBox:SetText(savedSet.name) end
    if owner.sourceBox then owner.sourceBox:SetText(savedSet.source or "") end
    if ETBDropdown then
        if _G["SBArmorTypeDropdown"] then
            ETBDropdown:SetText(_G["SBArmorTypeDropdown"], savedSet.armorType or "Auto-detect")
        end
        if _G["SBExpansionDropdown"] then
            ETBDropdown:SetText(_G["SBExpansionDropdown"], owner.EXPANSION_NAMES[savedSet.expansion] or "Classic")
        end
    end

    Export:UpdateSetDisplay(owner)
    Export:UpdateExportText(owner)

    ETB:Print(string.format("|cff00ff00[Set Builder]|r Loaded set '%s'.", name))
end

function Export:DeleteSet(owner, name)
    if ETB_SetBuilder_Data.savedSets[name] then
        ETB_SetBuilder_Data.savedSets[name] = nil
        ETB:Print(string.format("|cff00ff00[Set Builder]|r Deleted set '%s'.", name))
        Export:UpdateSavedSetsList(owner)
    else
        ETB:Print(string.format("|cffff0000[Set Builder]|r Set '%s' not found.", name))
    end
end

function Export:ListSavedSets(owner)
    ETB:Print("|cff00ffff=== Saved Sets ===|r")
    local count = 0
    for name, set in pairs(ETB_SetBuilder_Data.savedSets) do
        local pieceCount = 0
        for _ in pairs(set.items) do pieceCount = pieceCount + 1 end
        ETB:Print(string.format("  %s (%d pieces)", name, pieceCount))
        count = count + 1
    end
    if count == 0 then
        ETB:Print("  (no saved sets)")
    end
end

function Export:UpdateSavedSetsList(owner)
    if not owner.savedScrollChild then return end

    -- Clear existing buttons
    if owner.savedButtons then
        for _, btn in ipairs(owner.savedButtons) do
            btn:Hide()
        end
    end

    owner.savedButtons = owner.savedButtons or {}

    local yOffset = 0
    local btnIdx = 0

    for name, set in pairs(ETB_SetBuilder_Data.savedSets) do
        btnIdx = btnIdx + 1

        local btn = owner.savedButtons[btnIdx]
        if not btn then
            btn = CreateFrame("Button", nil, owner.savedScrollChild)
            btn:SetSize(190, 20)
            btn:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")

            local text = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            text:SetPoint("LEFT", 5, 0)
            text:SetWidth(150)
            text:SetJustifyH("LEFT")
            btn.text = text

            owner.savedButtons[btnIdx] = btn
        end

        btn:SetPoint("TOPLEFT", 0, -yOffset)
        btn.text:SetText(name)
        btn.setName = name
        -- Closure-capture the name + owner so OnClick can dispatch back
        btn:SetScript("OnClick", function()
            Export:LoadSet(owner, name)
        end)
        btn:Show()

        yOffset = yOffset + 22
    end

    owner.savedScrollChild:SetHeight(math.max(yOffset, 1))
end
