--[[
============================================================================
ETB - WeaponData.lua
============================================================================
Specialized module for weapon data retrieval (Categories 12 & 13).
Handles Main Hand and Off Hand weapons with weapon-specific logic.

Key Features:
- Trusts Blizzard API completely (no validation)
- Lenient filtering (only filters if CERTAIN weapon is unusable)
- Handles two-handed vs one-handed detection
- Supports all weapon types (Sword, Axe, Mace, Dagger, etc.)
============================================================================
]]--

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

ETB.WeaponData = {
    cache = {
        categories = {},
        sources = {},
    },
    initialized = false,
}

local WD = ETB.WeaponData

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

function WD:Initialize()
    if self.initialized then return true end
    
    ETB:Debug("WeaponData", "Initializing WeaponData module...")
    
    -- Verify APIs
    if not C_TransmogCollection then
        ETB:PrintError("C_TransmogCollection not available!")
        return false
    end
    
    self.initialized = true
    ETB:Debug("WeaponData", "WeaponData module initialized")
    return true
end

-- =============================================================================
-- CORE API METHODS (Delegate to BlizzardData)
-- =============================================================================

function WD:GetCategoryAppearances(categoryID)
    -- Delegate to BlizzardData but add weapon-specific logging
    if not ETB.BlizzardData then return {} end
    
    local appearances = ETB.BlizzardData:GetCategoryAppearances(categoryID)
    
    -- Debug logging for weapons
    if #appearances == 0 then
        ETB:Debug("WeaponData", string.format("⚠️ No appearances found for weapon category %d", categoryID))
        -- Try to get categories from API to see what's available
        if C_TransmogCollection and C_TransmogCollection.GetCategories then
            local success, categories = pcall(C_TransmogCollection.GetCategories)
            if success and categories then
                ETB:Debug("WeaponData", string.format("Available categories: %d total", #categories))
                for _, cat in ipairs(categories) do
                    if cat and cat.categoryID then
                        ETB:Debug("WeaponData", string.format("  Category %d: %s", cat.categoryID, cat.name or "Unknown"))
                    end
                end
            end
        end
    else
        ETB:Debug("WeaponData", string.format("✅ Category %d: Found %d weapon appearances", categoryID, #appearances))
    end
    
    return appearances
end

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

-- =============================================================================
-- WEAPON-SPECIFIC ITEM RETRIEVAL
-- =============================================================================

-- Helper to check if category is a weapon category
function WD:IsWeaponCategory(categoryID)
    if not categoryID then return false end
    -- MoP Classic: Categories 12+ are weapon types
    local catInfo = ETB.CATEGORY_INFO and ETB.CATEGORY_INFO[categoryID]
    if catInfo and catInfo.isWeapon then
        return true
    end
    return categoryID >= 12
end

function WD:GetItemsForCategory(categoryID, options)
    -- Validate category ID - MoP Classic uses 12+ for weapons
    if not self:IsWeaponCategory(categoryID) then
        ETB:Debug("WeaponData", string.format("⚠️ GetItemsForCategory called with non-weapon category %d", categoryID))
        return {}
    end
    
    options = options or {}
    local limit = options.limit or 100000
    local onlyCollected = options.onlyCollected
    local onlyUncollected = options.onlyUncollected
    local onlyUsable = options.onlyUsable
    
    -- Get category info for better logging
    local catInfo = ETB.CATEGORY_INFO and ETB.CATEGORY_INFO[categoryID]
    local catName = catInfo and catInfo.name or ("Category " .. categoryID)
    
    ETB:Debug("WeaponData", string.format("Getting weapons for %s (cat %d, limit=%d, collected=%s, usable=%s)", 
        catName, categoryID, limit, tostring(onlyCollected), tostring(onlyUsable)))
    ETB:Debug("WeaponData", "NOTE: Loading ALL weapons regardless of class. Class filtering done in UI layer.")
    
    local items = {}
    local itemsByVisualID = {}
    local appearances = self:GetCategoryAppearances(categoryID)
    
    if #appearances == 0 then
        ETB:Print("|cffff0000[WeaponData]|r ERROR: No appearances found for weapon category %d!", categoryID)
        ETB:Print("|cffffff00[WeaponData]|r Try: /etbverify categories to see available categories")
        return {}
    end
    
    local totalSourcesProcessed = 0
    local totalSourcesSkipped = 0
    
    for _, appearance in ipairs(appearances) do
        if #items >= limit then break end
        
        -- Pre-filter by collection
        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
            -- For weapons, we're more lenient with isUsable
            -- Some weapons might show isUsable=false but still be usable
            local skipByUsability = false
            if onlyUsable and appearance.isUsable == false then
                -- Still check sources - might have usable variants
                skipByUsability = false  -- Don't skip, check sources instead
            end
            
            if not skipByUsability then
                local sources = self:GetAppearanceSources(appearance.visualID)
                totalSourcesProcessed = totalSourcesProcessed + #sources
                
                if #sources == 0 then
                    ETB:Debug("WeaponData", string.format("Warning: Appearance visualID %d has no sources", appearance.visualID))
                end
                
                for _, source in ipairs(sources) do
                    if #items >= limit then break end
                    
                    if not source.itemID then
                        ETB:Debug("WeaponData", string.format("Warning: Source missing itemID for visualID %d", appearance.visualID))
                        totalSourcesSkipped = totalSourcesSkipped + 1
                    else
                        -- Build item entry using BlizzardData
                        local item = ETB.BlizzardData:BuildItemEntry(source, appearance, categoryID)
                        
                        -- For weapons: NO VALIDATION - trust the API completely
                        -- The API knows which category each weapon belongs to
                        
                        -- IMPORTANT: Load ALL weapons regardless of class
                        -- Class filtering will be done in Filtering:ApplyFilters() as a UI-level filter
                        -- This ensures we have complete weapon data for all classes, then can filter/sort by class
                        local shouldInclude = true
                        
                        -- Only filter by class if explicitly requested AND onlyUsable is true
                        -- But for now, we load all weapons and filter in UI layer
                        -- This allows users to see all weapons and sort/filter by class later
                        if onlyUsable then
                            -- This should rarely be called now since Filtering sets onlyUsable=false for weapons
                            -- But keep the logic here as a fallback
                            if item.weaponType then
                                if not ETB.BlizzardData:CanPlayerUseWeaponType(item.weaponType) then
                                    shouldInclude = false
                                end
                            end
                            if shouldInclude and item.canWear == false and item.weaponType then
                                shouldInclude = false
                            end
                        end
                        
                        if shouldInclude then
                            local visualID = item.visualID or appearance.visualID
                            if not itemsByVisualID[visualID] then
                                itemsByVisualID[visualID] = { items = {}, selectedIndex = 1 }
                            end
                            table.insert(itemsByVisualID[visualID].items, item)
                        else
                            totalSourcesSkipped = totalSourcesSkipped + 1
                        end
                    end
                end
            end
        end
    end
    
    -- Debug logging
    local uniqueVisualCount = 0
    for _ in pairs(itemsByVisualID) do
        uniqueVisualCount = uniqueVisualCount + 1
    end
    ETB:Debug("WeaponData", string.format("Category %d: Processed %d sources, skipped %d, unique visuals: %d", 
        categoryID, totalSourcesProcessed, totalSourcesSkipped, uniqueVisualCount))
    
    -- Create unique items list (one per visualID)
    for visualID, data in pairs(itemsByVisualID) do
        if #items >= limit then break end
        
        -- Select best item (prefer collected, then highest quality, then first)
        local selectedItem = nil
        local bestIndex = 1
        
        -- Prefer collected items
        for i, item in ipairs(data.items) do
            if item.isCollected then
                selectedItem = item
                bestIndex = i
                break
            end
        end
        
        -- If no collected, prefer highest quality
        if not selectedItem then
            local bestQuality = -1
            for i, item in ipairs(data.items) do
                -- Ensure quality is a number (may come as string from API)
                local quality = item.quality
                if quality and type(quality) ~= "number" then
                    quality = tonumber(quality) or 0
                end
                if quality and quality > bestQuality then
                    bestQuality = quality
                    selectedItem = item
                    bestIndex = i
                end
            end
        end
        
        -- Fallback to first item
        if not selectedItem and #data.items > 0 then
            selectedItem = data.items[1]
            bestIndex = 1
        end
        
        if selectedItem then
            -- Store alternatives
            selectedItem.alternatives = data.items
            selectedItem.selectedAlternativeIndex = bestIndex
            selectedItem.hasAlternatives = #data.items > 1
            
            -- Queue for name loading AND weaponType detection
            -- In Classic, GetItemInfoInstant may not work, so we need to cache item info with GetItemInfo
            for _, altItem in ipairs(data.items) do
                if altItem.itemID then
                    -- Request item info to cache it (needed for weaponType detection in Classic)
                    GetItemInfo(altItem.itemID)
                    if not altItem.name or altItem.name == "Loading..." then
                        ETB.BlizzardData.pendingItemInfo[altItem.itemID] = true
                    end
                    -- If weaponType is missing, try to detect it now (GetItemInfo may have cached it)
                    if not altItem.weaponType and ETB.BlizzardData then
                        local detectedType, isTwoHanded = ETB.BlizzardData:GetWeaponType(altItem.itemID)
                        if detectedType then
                            altItem.weaponType = detectedType
                            if isTwoHanded ~= nil then
                                altItem.isTwoHanded = isTwoHanded
                            end
                        end
                    end
                end
            end
            
            items[#items + 1] = selectedItem
        end
    end
    
    ETB:Debug("WeaponData", string.format("✅ Category %d: Returning %d unique weapon items", categoryID, #items))
    
    return items
end

-- =============================================================================
-- WEAPON-SPECIFIC STATISTICS
-- =============================================================================

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

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

function WD:InvalidateCache()
    wipe(self.cache.categories)
    wipe(self.cache.sources)
    ETB:Debug("WeaponData", "Weapon cache invalidated")
end

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