local addonName, ns = ...

ns.Stats = {}
local Stats = ns.Stats

local cachedData, cachedTotal

local function CopyEntries(data)
    local copy = {}
    for i, entry in ipairs(data) do
        copy[i] = {
            key = entry.key,
            name = entry.name,
            color = entry.color,
            value = entry.value,
            effect = entry.effect,
        }
    end
    return copy
end

-- Returns the ordered list of stat keys that should be displayed.
-- In auto mode this follows the full spec priority (primary + secondaries).
-- Otherwise it is the user's explicit selection (priority order first).
function Stats:GetActiveKeys()
    local db = ns.db
    local priority = ns.GetCurrentPriority()
    local keys = {}

    if db.useAuto then
        for _, key in ipairs(priority) do
            if ns.STAT_BY_KEY[key] then
                keys[#keys + 1] = key
            end
        end
        if #keys == 0 then
            -- Safe fallback so the chart is never empty in auto mode.
            for _, key in ipairs(ns.PRIORITY_FALLBACK) do
                keys[#keys + 1] = key
            end
        end
    else
        local added = {}
        for _, key in ipairs(priority) do
            if db.shown[key] and not added[key] then
                keys[#keys + 1] = key
                added[key] = true
            end
        end
        for _, def in ipairs(ns.STAT_DEFS) do
            if db.shown[def.key] and not added[def.key] then
                keys[#keys + 1] = def.key
                added[def.key] = true
            end
        end
    end

    return keys
end

-- Collects current values for the active stats.
-- Returns an array of { key, name, color, value } plus the total.
-- Secret combat values (12.0+) cannot be compared; cached data is used as fallback.
function Stats:Collect()
    local keys = self:GetActiveKeys()
    local result = {}
    local total = 0
    local hasSecret = false

    for _, key in ipairs(keys) do
        local def = ns.STAT_BY_KEY[key]
        if def then
            local ok, value = pcall(def.get)
            if not ok then
                value = 0
            elseif value == nil then
                hasSecret = true
                value = 0
            elseif not ns.IsSafeNumber(value) or value < 0 then
                value = 0
            end
            result[#result + 1] = {
                key = key,
                name = def.name,
                color = def.color,
                value = value,
                effect = ns.GetStatEffect(key),
            }
            total = total + value
        end
    end

    if hasSecret then
        if cachedData then
            return CopyEntries(cachedData), cachedTotal
        end
        return {}, 0
    end

    cachedData = CopyEntries(result)
    cachedTotal = total
    return result, total
end
