local _, PUP = ... -- Internal namespace

PUP.SPECIALIZATION_MAP = {
    -- Death Knight
    BLOOD = 250,
    FROST_DK = 251,
    UNHOLY = 252,

    -- Demon Hunter
    HAVOC = 577,
    VENGEANCE = 581,

    -- Druid
    BALANCE = 102,
    FERAL = 103,
    GUARDIAN = 104,
    RESTO_DRUID = 105,

    -- Evoker
    DEVASTATION = 1467,
    PRESERVATION = 1468,
    AUGMENTATION = 1473,

    -- Hunter
    BEAST_MASTERY = 253,
    MARKSMANSHIP = 254,
    SURVIVAL = 255,

    -- Mage
    ARCANE = 62,
    FIRE = 63,
    FROST_MAGE = 64,

    -- Monk
    BREWMASTER = 268,
    MISTWEAVER = 270,
    WINDWALKER = 269,

    -- Paladin
    HOLY_PALADIN = 65,
    PROTECTION_PALADIN = 66,
    RETRIBUTION = 70,

    -- Priest
    DISCIPLINE = 256,
    HOLY_PRIEST = 257,
    SHADOW = 258,

    -- Rogue
    ASSASSINATION = 259,
    OUTLAW = 260,
    SUBTLETY = 261,

    -- Shaman
    ELEMENTAL = 262,
    ENHANCEMENT = 263,
    RESTO_SHAMAN = 264,

    -- Warlock
    AFFLICTION = 265,
    DEMONOLOGY = 266,
    DESTRUCTION = 267,

    -- Warrior
    ARMS = 71,
    FURY = 72,
    PROTECTION_WARRIOR = 73,
}

PUP.CLASS_SPECIALIZATION_MAP = {
    ["Death Knight"] = { 250, 251, 252 },
    ["Demon Hunter"] = { 577, 581 },
    ["Druid"] = { 102, 103, 104, 105 },
    ["Evoker"] = { 1467, 1468, 1473 },
    ["Hunter"] = { 253, 254, 255 },
    ["Mage"] = { 62, 63, 64 },
    ["Monk"] = { 268, 269, 270 },
    ["Paladin"] = { 65, 66, 70 },
    ["Priest"] = { 256, 257, 258 },
    ["Rogue"] = { 259, 260, 261 },
    ["Shaman"] = { 262, 263, 264 },
    ["Warlock"] = { 265, 266, 267 },
    ["Warrior"] = { 71, 72, 73 },
    ["ALL"] = { 1 },
}

function PUP:GetAllSpecializationIDs()
    local ids = {}
    for k, v in pairs(PUP.SPECIALIZATION_MAP) do
        tinsert(ids, v)
    end
    return ids
end

function PUP:InitializeCooldowns()
    for i = 1, C_SpellBook.GetNumSpellBookSkillLines() do
        local skillLineInfo = C_SpellBook.GetSpellBookSkillLineInfo(i)

        if i == 2 then
            for specIndex = 1, GetNumSpecializations() do
                local specId = select(1, GetSpecializationInfo(specIndex))
                if specId then
                    PUP.CooldownList[specId] = {}
                    PUP.CooldownList[specId]["spell"] = {}
                    local offset, numSlots = skillLineInfo.itemIndexOffset, skillLineInfo.numSpellBookItems
                    for j = offset + 1, offset + numSlots do
                        local spellName = C_SpellBook.GetSpellBookItemName(j, Enum.SpellBookSpellBank.Player)
                        if spellName and not C_Spell.IsSpellPassive(spellName) then
                            local _, spellID = C_SpellBook.GetSpellBookItemType(j, Enum.SpellBookSpellBank.Player)
                            PUP.CooldownList[specId]["spell"][spellID] = { offset = 0, name = spellName }
                        end
                    end
                end
            end
        else
            for specIndex = 1, GetNumSpecializations() do
                local specId, specName, _, _, _, _ = GetSpecializationInfo(specIndex)
                if specName == skillLineInfo.name then
                    PUP.CooldownList[specId]["item"] = {}

                    -- === SPELLS ERMITTELN ===
                    local offset, numSlots = skillLineInfo.itemIndexOffset, skillLineInfo.numSpellBookItems
                    for j = offset + 1, offset + numSlots do
                        local spellName, _ = C_SpellBook.GetSpellBookItemName(j, Enum.SpellBookSpellBank.Player)
                        if not C_Spell.IsSpellPassive(spellName) then
                            local spellID = select(2, C_SpellBook.GetSpellBookItemType(j, Enum.SpellBookSpellBank.Player))
                            PUP.CooldownList[specId]["spell"][spellID] = { offset = 0, name = spellName }
                        end
                    end

                    -- === TRINKETS ERMITTELN ===
                    local trinketSlots = { 13, 14 } -- Trinket 1 + Trinket 2
                    for _, slotID in ipairs(trinketSlots) do
                        local itemID = GetInventoryItemID("player", slotID)
                        if itemID then
                            local itemName = GetItemInfo(itemID)
                            PUP.CooldownList[specId]["item"][itemID] = { offset = 0, name = itemName }
                        end
                    end
                end
            end
        end
    end
end

function PUP:CheckCooldowns()
    local spec = GetSpecializationInfo(GetSpecialization())
    local pullTimer = 10
    if PUP.CooldownList then
        local now = GetTime()
        local highest = { text = "", time = 0 }
        if PUP.CooldownList[spec] and PUP.CooldownList[spec]["spell"] then
            for k, v in pairs(PUP.CooldownList[spec]["spell"]) do
                local cooldown = C_Spell.GetSpellCooldown(k)
                local timeRemaining = cooldown and cooldown.duration ~= 0 and
                cooldown.duration + cooldown.startTime - now
                if timeRemaining and timeRemaining + v.offset > pullTimer then
                    if timeRemaining + v.offset > highest.time then
                        highest = {
                            text = "[Prepull Updater] Mein " ..
                            v.name .. " ist noch für " .. Round(timeRemaining + v.offset) .. " Sekunden auf Cooldown.",
                            time = timeRemaining + v.offset
                        }
                    end
                end
            end
        end

        if PUP.CooldownList[spec] and PUP.CooldownList[spec]["item"] then
            for k, v in pairs(PUP.CooldownList[spec]["item"]) do
                local startTime, duration = C_Item.GetItemCooldown(k)
                local timeRemaining = duration and duration ~= 0 and duration + startTime - now
                if timeRemaining and timeRemaining + v.offset > pullTimer then
                    if timeRemaining + v.offset > highest.time then
                        highest = {
                            text = "[Prepull Updater] Mein " ..
                            v.name .. " ist noch für " .. Round(timeRemaining + v.offset) .. " Sekunden auf Cooldown.",
                            time = timeRemaining + v.offset
                        }
                    end
                end
            end
        end
        if PUP.CooldownList[1] and PUP.CooldownList[1]["spell"] then
            for k, v in pairs(PUP.CooldownList[1]["spell"]) do
                local cooldown = C_Spell.GetSpellCooldown(k)
                local timeRemaining = cooldown and cooldown.duration ~= 0 and
                cooldown.duration + cooldown.startTime - now
                if timeRemaining and timeRemaining + v.offset > pullTimer then
                    if timeRemaining + v.offset > highest.time then
                        highest = {
                            text = "[Prepull Updater] Mein " ..
                            v.name .. " ist noch für " .. Round(timeRemaining + v.offset) .. " Sekunden auf Cooldown.",
                            time = timeRemaining + v.offset
                        }
                    end
                end
            end
        end
        if PUP.CooldownList[1] and PUP.CooldownList[1]["item"] then
            for k, v in pairs(PUP.CooldownList[1]["item"]) do
                local startTime, duration = C_Item.GetItemCooldown(k)
                local timeRemaining = duration and duration ~= 0 and duration + startTime - now
                if timeRemaining and timeRemaining + v.offset > pullTimer then
                    if timeRemaining + v.offset > highest.time then
                        highest = {
                            text = "[Prepull Updater] Mein " ..
                            v.name .. " ist noch für " .. Round(timeRemaining + v.offset) .. " Sekunden auf Cooldown.",
                            time = timeRemaining + v.offset
                        }
                    end
                end
            end
        end
        if highest.time > 0 then
            C_ChatInfo.SendChatMessage(highest.text, "RAID")
        end
    end
end
