---@diagnostic disable: undefined-field
local _, PUP = ...

local LibSerialize = LibStub("LibSerialize")
local LibDeflate = LibStub("LibDeflate")

local oldAuras = {
    "Prepull -  TWW Season 1 Mythic",
    "Prepull -  TWW Season 2 Mythic"
}

-- Checks if we already have this aura installed (by display name)
-- If so, makes sure that the version of the aura we are importing matches its UID
-- This is called both on importing of auras (from PUP.WeakAuras), as well as on updating an aura
-- The goal is to properly update/recognise installed versions of the auras, even if their UID is different
function PUP:MatchInstalledUID(auraData)
    local displayName = auraData and auraData.id
    local installedAuraData = displayName and WeakAuras.GetData(displayName)
    
    if not installedAuraData then return end

    auraData.uid = installedAuraData.uid
end

-- Table that decides if PrepullUpdater auras are relevant for the current patch
-- We don't want to always delete them from the addon completely, because they may become relevant in the future (fated)
-- This also allows for different auras to show on PTR/beta than on live
-- The before/after fields are interface versions, as returned by GetBuildInfo()
-- before is exclusive, after is inclusive
local auraRelevancy = {
    ["TWW Season 1 Mythic"] = {
        before = 110200
    },
    ["TWW Season 2 Mythic"] = {
        before = 110200
    },
    ["TWW Season 3 Mythic"] = {
        after = 110200
    }
}

local function IsRelevantWeakAura(displayName)
    local relevancyTable = auraRelevancy[displayName]

    if not relevancyTable then return true end

    local interfaceVersion = select(4, GetBuildInfo())
    local beforeOK = true
    local afterOK = true

    if relevancyTable.before then
        beforeOK = interfaceVersion < relevancyTable.before
    end

    if relevancyTable.after then
        afterOK = interfaceVersion >= relevancyTable.after
    end

    return beforeOK and afterOK
end

-- Takes WeakAura strings from PUP.WeakAuras, decodes them, and saves them to PrepullUpdaterSaved.WeakAuras
-- Only decodes new auras (or new versions of auras)
function PUP:InitializeWeakAurasImporter()
    if not PrepullUpdaterSaved.WeakAuras then PrepullUpdaterSaved.WeakAuras = {} end

    for _, auraData in ipairs(PUP.WeakAuras) do
        local displayName = auraData.displayName

        if IsRelevantWeakAura(displayName) then
            local version = auraData.version
            local importedVersion = PrepullUpdaterSaved.WeakAuras[displayName] and PrepullUpdaterSaved.WeakAuras[displayName].d and PrepullUpdaterSaved.WeakAuras[displayName].d.prepullVersion

            if not importedVersion or importedVersion < version then
                local toDecode = auraData.data:match("!WA:2!(.+)")

                if toDecode then
                    local decoded = LibDeflate:DecodeForPrint(toDecode)

                    if decoded then
                        local decompressed = LibDeflate:DecompressDeflate(decoded)

                        if decompressed then
                            local success, data = LibSerialize:Deserialize(decompressed)

                            if success then
                                data.d.prepullVersion = version
                                data.d.url = nil
                                data.d.wagoID = nil
                                                                
                                if data.c then
                                    for _, childData in pairs(data.c) do
                                        childData.url = nil
                                        childData.wagoID = nil
                                    end
                                end

                                PrepullUpdaterSaved.WeakAuras[displayName] = data
                            else
                                PUP:ErrorPrint(string.format("could not deserialize aura data for [%s]", displayName))
                            end
                        else
                            PUP:ErrorPrint(string.format("could not decompress aura data for [%s]", displayName))
                        end
                    else
                        PUP:ErrorPrint(string.format("could not decode aura data for [%s]", displayName))
                    end
                else
                    PUP:ErrorPrint(string.format("aura data for [%s] does not start with a valid prefix", displayName))
                end
            end
        end
    end

    -- Delete irrelevant auras from SavedVariables
    for displayName in pairs(PrepullUpdaterSaved.WeakAuras) do
        if not IsRelevantWeakAura(displayName) then
            PrepullUpdaterSaved.WeakAuras[displayName] = nil
        end
    end

    -- Match imported aura UIDs to installed aura UIDs
    for _, auraData in pairs(PrepullUpdaterSaved.WeakAuras) do
        PUP:MatchInstalledUID(auraData.d)
    end
end

function PUP:DeleteOldWeakAuras()
    if not WeakAurasSaved or not WeakAurasSaved.displays then
        return
    end

    local deleted = {}

    local function deleteAuraRecursively(auraName)
        if deleted[auraName] then return end -- schon gelöscht

        local aura = WeakAurasSaved.displays[auraName]
        if not aura then return end

        -- Childs rekursiv löschen
        if aura.controlledChildren then
            for _, child in ipairs(aura.controlledChildren) do
                deleteAuraRecursively(child)
            end
        end

        WeakAurasSaved.displays[auraName] = nil
        deleted[auraName] = true
    end

    for _, auraName in ipairs(oldAuras) do
        deleteAuraRecursively(auraName)
    end
end
