-- This file builds the update list, which shows auras that are out of date,
-- as well as warnings for things like having duplicate auras etc.

---@diagnostic disable: undefined-field, undefined-global
---@class Private
local Private = select(2, ...)

local ELEMENT_HEIGHT = 40
local ELEMENT_SPACING = 4

function Private:CreateMandatoryWAsList(parent, optional)
    local updateElements = {}

    local mandatoryWAsList = CreateFrame("Frame", nil, parent)

    -- Scroll frame
    local scrollFrame = Private:CreateScrollFrame(mandatoryWAsList)

    scrollFrame:SetAllPoints()
    scrollFrame:SetScrollDistance(ELEMENT_HEIGHT + ELEMENT_SPACING)

    scrollFrame.scrollBar:SetPoint("BOTTOMRIGHT", scrollFrame, "BOTTOMRIGHT", -8, 16)
    scrollFrame.scrollFrame:SetPoint("BOTTOMRIGHT", scrollFrame.scrollBar, "BOTTOMLEFT", -10, -15)

    -- All auras up to date text
    mandatoryWAsList.requiresUpdateText = mandatoryWAsList:CreateFontString()

    mandatoryWAsList.requiresUpdateText:SetFontObject(WildThingsFont21)
    mandatoryWAsList.requiresUpdateText:SetAllPoints(scrollFrame.scrollFrame)
    mandatoryWAsList.requiresUpdateText:SetFormattedText("|cff%sAll auras up to date!|r", Private.gs.visual.colorStrings.green)

    local function ReleaseAllUpdateElements()
        for index, cell in pairs(updateElements) do
            cell:Release()

            updateElements[index] = nil
        end
    end

    local function IsOptionalWeakAura(auraName)
        for _, wa in ipairs(Private.WeakAuras) do
            if wa.displayName == auraName then
                return wa.optional
            end
        end
    end

    -- Called any time the player's versions table updates, or when highest seen versions update
    function mandatoryWAsList:Rebuild()
        ReleaseAllUpdateElements()
        local needUpdate = false

        local versionsTable = Private:GetPlayerVersionsTable()

        local installedAddOnVersion = versionsTable.addOn
        local installedAuraVersions = versionsTable.auras

        local highestSeenAddOnVersion = Private:GetHighestSeenAddOnVersion()
        local highestSeenAuraVersions = Private:GetHighestSeenAuraVersions()

        local importedVersions = {}

        for _, wa in ipairs(Private.WeakAuras) do
            if wa.optional == optional then
                local displayName = wa.displayName
                if WildThingsSavedVars.WeakAuras and WildThingsSavedVars.WeakAuras[displayName] then
                    importedVersions[displayName] = WildThingsSavedVars.WeakAuras[displayName].d.customWTVersion or 0
                end
            end
        end

        -- Create update elements for auras
        for displayName, highestSeenVersion in pairs(highestSeenAuraVersions) do
            local installedVersion = installedAuraVersions[displayName]
            local importedVersion = importedVersions[displayName]

            if importedVersion then
                local versionsBehind = highestSeenVersion - installedVersion
                local updateElement = Private:CreateUpdateElement(scrollFrame.contentFrame, displayName)
                local requiresAddOnUpdate = importedVersion < highestSeenVersion

                if not needUpdate and not optional then
                    needUpdate = tonumber(versionsBehind) < 0 or requiresAddOnUpdate
                end
                if versionsBehind > 0 and not IsOptionalWeakAura(displayName) then
                    print("|cff99ff00Wild Things:|r ", "|cfffefe00"..updateElement.auraName.."|r:", "|cffff5555"..versionsBehind.." version(s)|r behind! (/wt update)")
                end

                if installedVersion == 0 then
                    updateElement:SetNotInstalled(optional)
                else
                    updateElement:SetVersionsBehind(versionsBehind)
                end

                updateElement:SetRequiresAddOnUpdate(requiresAddOnUpdate)

                table.insert(updateElements, updateElement)
            end
        end

        -- Sort aura update elements
        table.sort(
            updateElements,
            function(elementA, elementB)
                local versionsBehindA = elementA.versionsBehind
                local versionsBehindB = elementB.versionsBehind

                if versionsBehindA ~= versionsBehindB then
                    return versionsBehindA > versionsBehindB
                else
                    return elementA.auraName < elementB.auraName
                end
            end
        )

        -- Create addon update element
        -- local addOnVersionsBehind = highestSeenAddOnVersion - installedAddOnVersion
        if Private:CompareAddOnVersions(highestSeenAddOnVersion, installedAddOnVersion) < 0 then
            local updateElement = Private:CreateUpdateElement(scrollFrame.contentFrame, "WildThings")

            updateElement:SetVersionsBehind(1)
            updateElement:SetRequiresAddOnUpdate(true)

            needUpdate = true

            table.insert(updateElements, 1, updateElement)
        end

        -- Position elements
        for i, updateElement in ipairs(updateElements) do
            updateElement:SetPoint("BOTTOMLEFT", scrollFrame.contentFrame, "TOPLEFT", ELEMENT_SPACING, -i * (ELEMENT_HEIGHT + ELEMENT_SPACING))
            updateElement:SetPoint("BOTTOMRIGHT", scrollFrame.contentFrame, "TOPRIGHT", -ELEMENT_SPACING, -i * (ELEMENT_HEIGHT + ELEMENT_SPACING))
        end

        -- Show the green "all auras up to date" text if no update elements exist
        mandatoryWAsList.requiresUpdateText:SetShown(#updateElements == 0)

        -- Update scroll frame
        scrollFrame.contentFrame:SetHeight(#updateElements * (ELEMENT_HEIGHT + ELEMENT_SPACING) + ELEMENT_SPACING)

        scrollFrame:FullUpdate()

        -- Might as well run this here, so we don't have to do the above checks anywhere else
        if not optional then
            Private.upToDate = not needUpdate
            Private:UpdateMinimapIcon()

            -- if Private.upToDate then
            --     print("|cff99ff00Wild Things:|r ", string.format("|cff%sEverything up to date!|r", Private.gs.visual.colorStrings.green))
            -- end
        end
    end

    return mandatoryWAsList
end
