local addonName, RLMage = ...

-- =========================================================================
-- COMBAT ANNOUNCES  –  Spellsteal / Counterspell / Silence
-- =========================================================================

-- Debug flag: toggle with  /rlmage debug
RLMage.combatDebug = false

-- Returns the appropriate group chat channel, or nil if not in a group.
local function GetGroupChannel()
    if IsInRaid() then
        return "RAID"
    elseif IsInGroup() then
        return "PARTY"
    end
    return nil
end

-- Sends a message to the group channel (or prints locally in debug mode).
local function GroupSay(msg)
    if RLMage.combatDebug then
        print("|cffffff00[RLMage Debug – GroupSay]|r " .. msg)
    end
    local channel = GetGroupChannel()
    if channel then
        SendChatMessage(msg, channel)
    elseif RLMage.combatDebug then
        print("|cffff0000[RLMage Debug]|r Kein Gruppen-/Raid-Kanal verfügbar.")
    end
end

-- -------------------------------------------------------------------------
-- Known silence-inducing debuff spell IDs in TBC Classic
-- -------------------------------------------------------------------------
local SILENCE_SPELL_IDS = {
    [15487] = true, -- Silence (Priest)
    [15503] = true, -- Silence (Priest Rank 2)
    [18498] = true, -- Spell Lock (Felhunter Rank 1)
    [27276] = true, -- Spell Lock (Felhunter Rank 2)
    [24259] = true, -- Spell Lock silence component
    [25046] = true, -- Arcane Torrent (Blood Elf Rank 1)
    [28730] = true, -- Arcane Torrent (Blood Elf Rank 2)
    [50613] = true, -- Arcane Torrent (Blood Elf Rank 3)
    [1330]  = true, -- Garrote – Silence (Rogue)
    [13750] = true, -- Garrote – Silence (Rank 2)
}

local activeSilences        = {}
local lastInterruptAnnounce = {}
local INTERRUPT_DEBOUNCE    = 1.5

-- -------------------------------------------------------------------------
-- Safe CLEU parameter extraction
-- TBC Classic may or may not include hideCaster (pos 3).
-- We detect this by type: if pos 3 is a boolean → modern format with hideCaster.
-- If pos 3 is a string (GUID) → old format without hideCaster, shift by -1.
-- -------------------------------------------------------------------------
local function GetCLEUParams()
    if not CombatLogGetCurrentEventInfo then
        -- Fallback: args are passed directly as event varargs (very old builds)
        return nil
    end

    local p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18
        = CombatLogGetCurrentEventInfo()

    local subevent, sourceGUID, sourceName, destGUID, destName
    local spellID, spellName, spellSchool, param15, param16, param17, param18

    -- p2 = subevent always
    subevent = p2

    if type(p3) == "boolean" then
        -- Modern format: hideCaster at pos 3
        -- p4=sourceGUID, p5=sourceName, p6=sourceFlags, p7=sourceRaidFlags
        -- p8=destGUID,   p9=destName,  p10=destFlags,  p11=destRaidFlags
        -- p12=spellID,  p13=spellName, p14=spellSchool, p15..
        sourceGUID  = p4;  sourceName = p5
        destGUID    = p8;  destName   = p9
        spellID     = p12; spellName  = p13; spellSchool = p14
        param15 = p15; param16 = p16; param17 = p17; param18 = p18
    else
        -- Old format: no hideCaster
        -- p3=sourceGUID, p4=sourceName, p5=sourceFlags
        -- p6=destGUID,   p7=destName,  p8=destFlags
        -- p9=spellID,   p10=spellName, p11=spellSchool, p12..
        sourceGUID  = p3;  sourceName = p4
        destGUID    = p6;  destName   = p7
        spellID     = p9;  spellName  = p10; spellSchool = p11
        param15 = p12; param16 = p13; param17 = p14; param18 = p15
    end

    return subevent, sourceGUID, sourceName, destGUID, destName,
           spellID, spellName, spellSchool, param15, param16, param17, param18
end

-- -------------------------------------------------------------------------
-- Main event frame
-- -------------------------------------------------------------------------
local combatFrame = CreateFrame("Frame")
combatFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
combatFrame:RegisterEvent("PLAYER_ENTERING_WORLD")

combatFrame:SetScript("OnEvent", function(self, event)
    if event == "PLAYER_ENTERING_WORLD" then
        wipe(activeSilences)
        wipe(lastInterruptAnnounce)
        return
    end

    if event ~= "COMBAT_LOG_EVENT_UNFILTERED" then return end
    if not RLMageDB then return end

    local subevent, sourceGUID, sourceName, destGUID, destName,
          spellID, spellName, spellSchool, param15, param16, param17, param18
        = GetCLEUParams()

    if not subevent then return end

    local playerGUID = UnitGUID("player")
    local L = RLMage.L

    -- Debug: print every event where the player is source or dest
    if RLMage.combatDebug then
        if sourceGUID == playerGUID or destGUID == playerGUID then
            print(string.format(
                "|cffffff00[CLEU]|r %s  src=%s  dst=%s  spell=%s(%s)  p15=%s  p16=%s",
                tostring(subevent),
                tostring(sourceName),
                tostring(destName),
                tostring(spellName),
                tostring(spellID),
                tostring(param15),
                tostring(param16)
            ))
        end
    end

    -- -----------------------------------------------------------------------
    -- SPELLSTEAL
    -- SPELL_STOLEN  = Spellsteal (buff moved from enemy TO player)
    -- SPELL_DISPEL  = Fluch entfernen / Dispel Magic (buff just removed) → NOT this
    -- -----------------------------------------------------------------------
    if RLMageDB.announceSpellsteal then
        if subevent == "SPELL_STOLEN" and sourceGUID == playerGUID then
            local stolenBuff = param16
            local victimName = destName
            if stolenBuff and victimName then
                -- Hardcoded English format as requested
                GroupSay("Spellsteal [" .. stolenBuff .. "] from " .. victimName)
            end
        end
    end

    -- -----------------------------------------------------------------------
    -- SPELL_INTERRUPT: either player interrupts enemy OR player is interrupted
    -- -----------------------------------------------------------------------
    if subevent == "SPELL_INTERRUPT" then
        -- Case 1: Player interrupts an enemy (Counterspell)
        if RLMageDB.announceCounterspell and sourceGUID == playerGUID then
            local interruptedSpell = param16
            local victimName = destName
            if interruptedSpell and victimName then
                -- Hardcoded English format as requested
                GroupSay("Interrupted [" .. interruptedSpell .. "] from " .. victimName)
            end

        -- Case 2: Player is interrupted by an enemy (Silence / School lockout)
        elseif RLMageDB.announceSilence and destGUID == playerGUID then
            local now = GetTime()
            local key = tostring(sourceGUID) .. ":" .. tostring(spellID)
            if not lastInterruptAnnounce[key]
               or (now - lastInterruptAnnounce[key]) > INTERRUPT_DEBOUNCE then
                lastInterruptAnnounce[key] = now
                GroupSay(string.format(L.COMBAT_MSG_INTERRUPTED_BY,
                    sourceName or "?"))
            end
        end
    end

    -- -----------------------------------------------------------------------
    -- SILENCE: Silence aura applied to player (separate from SPELL_INTERRUPT)
    -- -----------------------------------------------------------------------
    if RLMageDB.announceSilence then

        -- Silence aura applied to player (Priest Silence, Felhunter Spell Lock, etc.)
        if subevent == "SPELL_AURA_APPLIED" and destGUID == playerGUID
           and param15 == "DEBUFF" and SILENCE_SPELL_IDS[spellID] then
            if not activeSilences[spellID] then
                activeSilences[spellID] = true
                GroupSay(string.format(L.COMBAT_MSG_SILENCE,
                    spellName or "?", sourceName or "?"))
            end
        end

        if subevent == "SPELL_AURA_REMOVED" and destGUID == playerGUID
           and SILENCE_SPELL_IDS[spellID] then
            activeSilences[spellID] = nil
        end
    end
end)

-- -------------------------------------------------------------------------
-- Public helpers (called from slash command)
-- -------------------------------------------------------------------------

-- Send a test message to verify channel detection
function RLMage.TestCombatAnnounce()
    local ch = GetGroupChannel()
    print("|cff00ff00RLMage:|r IsInRaid=" .. tostring(IsInRaid())
        .. "  IsInGroup=" .. tostring(IsInGroup())
        .. "  Channel=" .. tostring(ch))
    if ch then
        SendChatMessage("RLMage Combat-Announce Test [" .. ch .. "]", ch)
        print("|cff00ff00RLMage:|r Test gesendet an: " .. ch)
    else
        print("|cffff0000RLMage:|r Nicht in Gruppe/Raid – kein Kanal.")
    end
end

-- Toggle debug mode
function RLMage.ToggleCombatDebug()
    RLMage.combatDebug = not RLMage.combatDebug
    if RLMage.combatDebug then
        print("|cff00ff00RLMage:|r Combat-Debug AN – alle dich betreffenden CLEU-Events werden angezeigt.")
    else
        print("|cffff8000RLMage:|r Combat-Debug AUS.")
    end
end
