--[[
============================================================================
ETB SourceLookup — Resolve item sources from JournalEncounter DB2 data
Chain: ETB.JLoot[itemID] → encounterID → ETB.JEncounters → ETB.JInstances
============================================================================
]]--

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

ETB.SourceLookup = {}
local SL = ETB.SourceLookup

local DIFF_LABELS = {
    [1]  = "|cff00ff00Normal|r",
    [2]  = "|cffff8800Heroic|r",
    [4]  = "|cff00ccffLFR|r",
    [8]  = "|cffff00ffThunderforged|r",
    [15] = "|cffffffffAll Difficulties|r",
}

local EXP_NAMES = {
    [0] = "Classic", [1] = "TBC", [2] = "Wrath", [3] = "Cata", [4] = "MoP",
}

-- Result cache (cleared on frame close to save memory)
SL._cache = {}
SL._cacheSize = 0

function SL:Resolve(encID, diffMask, facMask)
    local enc = ETB.JEncounters and ETB.JEncounters[encID]
    if not enc then return nil end
    
    local bossName = enc[1]
    local instanceID = enc[2]
    local inst = ETB.JInstances and ETB.JInstances[instanceID]
    if not inst then return nil end
    
    -- Build difficulty string
    local diffText
    if diffMask == 15 or diffMask == 0 then
        diffText = nil  -- All difficulties, don't show
    else
        local parts = {}
        if bit.band(diffMask, 1) > 0 then parts[#parts + 1] = "Normal" end
        if bit.band(diffMask, 2) > 0 then parts[#parts + 1] = "Heroic" end
        if bit.band(diffMask, 4) > 0 then parts[#parts + 1] = "LFR" end
        if bit.band(diffMask, 8) > 0 then parts[#parts + 1] = "Thunderforged" end
        diffText = #parts > 0 and table.concat(parts, "/") or nil
    end
    
    return {
        bossName = bossName,
        instanceName = inst[1],
        expansionID = inst[2],
        expansion = EXP_NAMES[inst[2]] or ("Exp" .. inst[2]),
        isRaid = inst[3] == 1,
        difficulty = diffText,
        diffMask = diffMask,
        faction = facMask == 1 and "Horde" or (facMask == 2 and "Alliance" or nil),
    }
end

function SL:GetItemSources(itemID)
    if not itemID or not ETB.JLoot then return nil end
    
    -- Cache hit
    if self._cache[itemID] then return self._cache[itemID] end
    
    local lootData = ETB.JLoot[itemID]
    if not lootData then
        -- Compact data fallback
        if ETB.SourceData_ATT and ETB.SourceData_ATT.GetPrimarySource then
            local attSrc = ETB.SourceData_ATT:GetPrimarySource(itemID)
            if attSrc then
                local result = {{
                    bossName = attSrc.name,
                    instanceName = attSrc.location,
                    expansion = attSrc.expansion,
                    isRaid = attSrc.isRaid,
                    difficulty = nil,
                }}
                self._cache[itemID] = result
                self._cacheSize = self._cacheSize + 1
                return result
            end
        end
        return nil
    end
    
    local results = {}
    
    -- Single source: {encID, diff[, fac]}
    -- Multiple: {{encID,diff},{encID,diff}}
    if type(lootData[1]) == "table" then
        for _, entry in ipairs(lootData) do
            local r = self:Resolve(entry[1], entry[2] or 15, entry[3] or 0)
            if r then results[#results + 1] = r end
        end
    else
        local r = self:Resolve(lootData[1], lootData[2] or 15, lootData[3] or 0)
        if r then results[#results + 1] = r end
    end
    
    if #results > 0 then
        self._cache[itemID] = results
        self._cacheSize = self._cacheSize + 1
        -- Keep cache bounded
        if self._cacheSize > 2000 then
            wipe(self._cache)
            self._cacheSize = 0
        end
        return results
    end
    return nil
end

-- Quick single-line source text
function SL:GetSourceText(itemID)
    local sources = self:GetItemSources(itemID)
    if not sources or #sources == 0 then return nil end
    local s = sources[1]
    local text = s.bossName or ""
    if s.instanceName then
        text = text .. (text ~= "" and " - " or "") .. s.instanceName
    end
    if s.difficulty then
        text = text .. " [" .. s.difficulty .. "]"
    end
    return text
end

-- Colored source text for UI display
function SL:GetSourceTextColored(itemID)
    local sources = self:GetItemSources(itemID)
    if not sources or #sources == 0 then return nil end
    local s = sources[1]
    local text = ""
    if s.instanceName then
        text = "|cffffcc00" .. s.instanceName .. "|r"
        if s.isRaid then text = text .. " |cffff8800(Raid)|r" end
    end
    if s.bossName then
        text = text .. (text ~= "" and " - " or "") .. "|cffffffff" .. s.bossName .. "|r"
    end
    if s.difficulty then
        text = text .. " |cff888888[" .. s.difficulty .. "]|r"
    end
    return text
end

function SL:ClearCache()
    wipe(self._cache)
    self._cacheSize = 0
end

ETB:Debug("SourceLookup", "SourceLookup loaded")
