--[[
============================================================================
ETB - ArmorData.lua (v12.6.1 Stable)
============================================================================
Armor data retrieval with both grouped and ungrouped modes.
============================================================================
]]--

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

ETB.ArmorData = {
    cache = {
        categories = {},
    },
    initialized = false,
    loadStats = {},
}

local AD = ETB.ArmorData

-- Armor subclass mapping
local ARMOR_SUBCLASS_MAP = {
    [1] = "CLOTH",
    [2] = "LEATHER", 
    [3] = "MAIL",
    [4] = "PLATE",
    [6] = "SHIELD",
}

-- =============================================================================
-- INITIALIZATION
-- =============================================================================

function AD:Initialize()
    if self.initialized then return true end
    
    if not C_TransmogCollection then
        ETB:PrintError("C_TransmogCollection not available!")
        return false
    end
    
    self.initialized = true
    ETB:Debug("ArmorData", "ArmorData module initialized")
    return true
end

-- =============================================================================
-- CORE API METHODS
-- =============================================================================

function AD:GetCategoryAppearances(categoryID)
    if not ETB.BlizzardData then 
        return C_TransmogCollection.GetCategoryAppearances(categoryID) or {}
    end
    return ETB.BlizzardData:GetCategoryAppearances(categoryID)
end

function AD:GetAppearanceSources(visualID)
    if not ETB.BlizzardData then 
        return C_TransmogCollection.GetAppearanceSources(visualID) or {}
    end
    return ETB.BlizzardData:GetAppearanceSources(visualID)
end

-- =============================================================================
-- ITEM RETRIEVAL
-- =============================================================================

function AD:GetItemsForCategory(categoryID, options)
    if not categoryID or categoryID < 1 or categoryID > 11 then
        return {}
    end
    
    options = options or {}
    local limit = options.limit or 100000
    local onlyCollected = options.onlyCollected
    local onlyUncollected = options.onlyUncollected
    local onlyUsable = options.onlyUsable
    
    local groupByAppearance = ETB.Filtering and ETB.Filtering.filters.groupByAppearance or false
    
    -- Cache key (includes onlyUsable to prevent stale filtered results)
    local cacheKey = string.format("v4_%d_%s_%s_%s_%s", categoryID, 
        tostring(onlyCollected), tostring(onlyUncollected), tostring(groupByAppearance), tostring(onlyUsable))
    
    if self.cache.categories[cacheKey] then
        return self.cache.categories[cacheKey]
    end
    
    local appearances = self:GetCategoryAppearances(categoryID)
    if #appearances == 0 then return {} end
    
    -- Track stats
    local stats = {
        appearances = #appearances,
        sources = 0,
        items = 0,
        byArmorType = { CLOTH = 0, LEATHER = 0, MAIL = 0, PLATE = 0, OTHER = 0 },
    }
    
    local items = {}
    local itemsByVisualID = {}
    
    -- Process appearances
    for _, appearance in ipairs(appearances) do
        if #items >= limit then break end
        
        -- Collection filter at appearance level
        local skipAppearance = false
        if onlyCollected and not appearance.isCollected then
            skipAppearance = true
        elseif onlyUncollected and appearance.isCollected then
            skipAppearance = true
        end
        
        if not skipAppearance then
            local sources = self:GetAppearanceSources(appearance.visualID)
            stats.sources = stats.sources + #sources
            
            for _, source in ipairs(sources) do
                if #items >= limit then break end
                
                if source.itemID then
                    local _, _, _, equipLoc, itemIcon, classID, subclassID = GetItemInfoInstant(source.itemID)
                    
                    local armorType = nil
                    if classID == 4 then
                        armorType = ARMOR_SUBCLASS_MAP[subclassID]
                    end
                    
                    -- Filter by class usability (armor type must match player's primary)
                    -- Skip for cosmetic slots: Back(3), Shirt(5), Tabard(6)
                    local skipUsability = false
                    if onlyUsable and armorType then
                        local COSMETIC_CATS = { [3]=true, [5]=true, [6]=true }
                        if not COSMETIC_CATS[categoryID] then
                            if ETB.BlizzardData and not ETB.BlizzardData:CanPlayerWearArmorType(armorType) then
                                skipUsability = true
                            end
                        end
                    end
                    
                    if not skipUsability then
                    
                    -- Track stats
                    if armorType then
                        stats.byArmorType[armorType] = (stats.byArmorType[armorType] or 0) + 1
                    else
                        stats.byArmorType.OTHER = stats.byArmorType.OTHER + 1
                    end
                    
                    -- Build item
                    local itemName, itemLink, quality = GetItemInfo(source.itemID)
                    
                    local item = {
                        itemID = source.itemID,
                        sourceID = source.sourceID,
                        visualID = appearance.visualID,
                        name = itemName or "Loading...",
                        link = itemLink,
                        quality = quality or 2,
                        icon = itemIcon or "Interface\\Icons\\INV_Misc_QuestionMark",
                        isCollected = source.isCollected or appearance.isCollected,
                        categoryID = categoryID,
                        armorType = armorType,
                        invType = equipLoc,
                    }
                    
                    -- Enrich with source data (sourceType, expansion, dropSource)
                    if ETB.SourceData then
                        item.dropSource = ETB.SourceData:GetSourceFormatted(source.itemID)
                    end
                    if ETB.SourceData_ATT and ETB.SourceData_ATT.GetPrimarySource then
                        local srcData = ETB.SourceData_ATT:GetPrimarySource(source.itemID)
                        if srcData then
                            item.sourceType = srcData.type
                            item.expansion = srcData.expansion
                            item.isRaid = srcData.isRaid
                            if not item.dropSource and srcData.name then
                                item.dropSource = srcData.name .. (srcData.location and srcData.location ~= "" and (" - " .. srcData.location) or "")
                            end
                        end
                    end
                    
                    if groupByAppearance then
                        -- Group mode
                        local visualID = appearance.visualID
                        if not itemsByVisualID[visualID] then
                            itemsByVisualID[visualID] = {
                                items = {},
                                armorTypes = {},
                            }
                        end
                        table.insert(itemsByVisualID[visualID].items, item)
                        if armorType then
                            itemsByVisualID[visualID].armorTypes[armorType] = true
                        end
                    else
                        -- Ungrouped mode - add all items
                        items[#items + 1] = item
                        stats.items = stats.items + 1
                    end
                    
                    -- Request name if needed
                    if not itemName then
                        GetItemInfo(source.itemID)
                    end
                    end -- close skipUsability check
                end
            end
        end
    end
    
    -- If grouped mode, create final list
    if groupByAppearance then
        for visualID, data in pairs(itemsByVisualID) do
            if #items >= limit then break end
            
            -- Select best representative
            local selectedItem = nil
            for _, item in ipairs(data.items) do
                if item.isCollected then
                    selectedItem = item
                    break
                end
            end
            
            if not selectedItem then
                local bestQuality = -1
                for _, item in ipairs(data.items) do
                    local q = tonumber(item.quality) or 0
                    if q > bestQuality then
                        bestQuality = q
                        selectedItem = item
                    end
                end
            end
            
            if not selectedItem and #data.items > 0 then
                selectedItem = data.items[1]
            end
            
            if selectedItem then
                selectedItem.alternatives = data.items
                selectedItem.hasAlternatives = #data.items > 1
                selectedItem.alternativeCount = #data.items
                selectedItem.availableArmorTypes = data.armorTypes
                
                items[#items + 1] = selectedItem
                stats.items = stats.items + 1
            end
        end
    end
    
    -- Store stats and cache
    self.loadStats[categoryID] = stats
    self.cache.categories[cacheKey] = items
    
    return items
end

-- =============================================================================
-- STATISTICS
-- =============================================================================

function AD:GetCollectionStats(categoryID)
    if ETB.BlizzardData then
        return ETB.BlizzardData:GetCollectionStats(categoryID)
    end
    return { total = 0, collected = 0, usable = 0, percent = 0 }
end

function AD:GetLoadStats(categoryID)
    return self.loadStats[categoryID]
end

function AD:PrintLoadReport()
    ETB:Print("|cff00ff00=== ARMOR DATA LOAD REPORT ===|r")
    
    local totalAppearances = 0
    local totalItems = 0
    
    local catNames = {
        [1] = "Head", [2] = "Shoulder", [3] = "Back", [4] = "Chest", [5] = "Shirt",
        [6] = "Tabard", [7] = "Wrist", [8] = "Hands", [9] = "Waist", [10] = "Legs", [11] = "Feet"
    }
    
    for catID = 1, 11 do
        local stats = self.loadStats[catID]
        if stats then
            ETB:Print(string.format("  %s: %d appearances → %d items",
                catNames[catID] or catID, stats.appearances, stats.items or stats.sources))
            
            totalAppearances = totalAppearances + stats.appearances
            totalItems = totalItems + (stats.items or stats.sources)
        end
    end
    
    ETB:Print(string.format("|cffffd100TOTALS:|r %d appearances → %d items", totalAppearances, totalItems))
end

-- =============================================================================
-- CACHE MANAGEMENT
-- =============================================================================

function AD:InvalidateCache()
    wipe(self.cache.categories)
    wipe(self.loadStats)
    ETB:Debug("ArmorData", "Armor cache invalidated")
end

ETB:Debug("ArmorData", "ArmorData.lua loaded")
