--[[
    Commander 3.0 - Addons Data Source

    Provides access to loaded addons and their status.
    Commands: addons

    Shows addon name, title, version, memory usage, and enabled status.
]]

local ADDON_NAME, C3 = ...

-- Use shared color utilities
local Colorize = function(...) return C3.Colors.Colorize(...) end

-------------------------------------------------------------------------------
-- Addon Type Registration
-------------------------------------------------------------------------------

C3.Types:Register("Addon", {
    description = "Loaded addon information",
    source = "addons",
    properties = {
        { "name", "Addon folder name" },
        { "title", "Display title" },
        { "notes", "Addon description" },
        { "author", "Author name" },
        { "version", "Version string" },
        { "enabled", "true if enabled" },
        { "loaded", "true if loaded" },
        { "loadable", "true if loadable" },
        { "memory", "Memory usage in KB" },
        { "reason", "Reason if not loadable" },
        { "isLOD", "true if load-on-demand" },
    },
    format = function(self)
        local name = self.title or self.name or "Unknown"
        local status = ""

        if self.loaded then
            status = Colorize("[Loaded]", "accent.success")
        elseif self.enabled then
            status = Colorize("[Enabled]", "accent.warning")
        else
            status = Colorize("[Disabled]", "status.dim")
        end

        -- Memory display
        local memStr = ""
        if self.memory and self.memory > 0 then
            if self.memory >= 1024 then
                memStr = " " .. Colorize(string.format("%.1f MB", self.memory / 1024), "status.dim")
            else
                memStr = " " .. Colorize(string.format("%.0f KB", self.memory), "status.dim")
            end
        end

        -- Version
        local verStr = ""
        if self.version and self.version ~= "" then
            verStr = " " .. Colorize("v" .. self.version, "status.dim")
        end

        return string.format("%s %s%s%s", status, name, verStr, memStr)
    end
})

-- Register formatter
C3.Formatter:Register("Addon", {
    format = function(obj)
        local name = obj.title or obj.name or "Unknown"
        local status = obj.loaded and "[Loaded]" or (obj.enabled and "[Enabled]" or "[Disabled]")

        local memStr = ""
        if obj.memory and obj.memory > 0 then
            if obj.memory >= 1024 then
                memStr = string.format(" (%.1f MB)", obj.memory / 1024)
            else
                memStr = string.format(" (%.0f KB)", obj.memory)
            end
        end

        return string.format("%s %s%s", status, name, memStr)
    end,
    list = function(obj)
        local name = obj.title or obj.name or "?"
        local status = obj.loaded and "+" or (obj.enabled and "o" or "-")
        return string.format("[%s] %s", status, name)
    end,
    compact = function(obj)
        return obj.name or "?"
    end
})

-------------------------------------------------------------------------------
-- addons - List all addons
-------------------------------------------------------------------------------

C3.Command:Define({
    name = "addons",
    description = "List loaded addons",
    category = "data",
    acceptsInput = false,
    flags = {
        all = { short = "a", description = "Include disabled addons" },
        memory = { short = "m", description = "Sort by memory usage (descending)" },
        loaded = { short = "l", description = "Show only loaded addons" },
    },
    execute = function(ctx)
        local showAll = ctx:HasFlag("all") or ctx:HasFlag("a")
        local sortByMemory = ctx:HasFlag("memory") or ctx:HasFlag("m")
        local loadedOnly = ctx:HasFlag("loaded") or ctx:HasFlag("l")

        -- Update memory usage before iterating
        UpdateAddOnMemoryUsage()

        local results = {}
        local processed = 0
        local YIELD_INTERVAL = C3.Constants.YIELD_INTERVAL

        local numAddOns = C_AddOns and C_AddOns.GetNumAddOns() or GetNumAddOns()

        for i = 1, numAddOns do repeat
            -- Yield periodically
            processed = processed + 1
            if processed % YIELD_INTERVAL == 0 then
                coroutine.yield()
            end

            -- Get addon info - handle both old and new API
            local name, title, notes, loadable, reason, security
            if C_AddOns and C_AddOns.GetAddOnInfo then
                local info = C_AddOns.GetAddOnInfo(i)
                if type(info) == "table" then
                    name = info.name
                    title = info.title
                    notes = info.notes
                    loadable = info.loadable
                    reason = info.reason
                    security = info.security
                else
                    name, title, notes, loadable, reason, security = C_AddOns.GetAddOnInfo(i)
                end
            else
                name, title, notes, loadable, reason, security = GetAddOnInfo(i)
            end

            -- Guard: Invalid addon
            if not name then break end

            -- Get enabled state
            local enabled
            if C_AddOns and C_AddOns.GetAddOnEnableState then
                local state = C_AddOns.GetAddOnEnableState(i)
                enabled = state and state > 0
            else
                enabled = GetAddOnEnableState(UnitName("player"), i) > 0
            end

            -- Get loaded state
            local loaded
            if C_AddOns and C_AddOns.IsAddOnLoaded then
                loaded = C_AddOns.IsAddOnLoaded(i)
            else
                loaded = IsAddOnLoaded(i)
            end

            -- Guard: All filter (if not showing all, only show enabled)
            if not showAll and not enabled then break end

            -- Guard: Loaded filter
            if loadedOnly and not loaded then break end

            -- Get memory usage
            local memory = GetAddOnMemoryUsage(i) or 0

            -- Get metadata
            local version = GetAddOnMetadata(i, "Version") or ""
            local author = GetAddOnMetadata(i, "Author") or ""

            -- Check if load-on-demand
            local isLOD
            if C_AddOns and C_AddOns.IsAddOnLoadOnDemand then
                isLOD = C_AddOns.IsAddOnLoadOnDemand(i)
            else
                isLOD = IsAddOnLoadOnDemand(i)
            end

            -- All guards passed - add result
            table.insert(results, C3.Types.Create("Addon", {
                name = name,
                title = title,
                notes = notes,
                author = author,
                version = version,
                enabled = enabled,
                loaded = loaded,
                loadable = loadable,
                memory = memory,
                reason = reason,
                isLOD = isLOD,
            }))
        until true end

        -- Sort by memory if requested
        if sortByMemory then
            table.sort(results, function(a, b)
                return (a.memory or 0) > (b.memory or 0)
            end)
        end

        return results
    end
})

return true
