-- ══════════════════════════════════════════════════════════════
-- MODUL: DeathBell - Klangliche & visuelle Todesbenachrichtigung
-- Queue-System verhindert Stapeln bei simultanen Toden (Raid-Wipe)
-- ══════════════════════════════════════════════════════════════

local addonName, addon = ...
local GDL = _G["GuildDeathLog"]
local DeathBell = {}

local flashFrame     = nil
local FLASH_DURATION = 1.2
local QUEUE_COOLDOWN = 1.8

local deathQueue  = {}
local isPlaying   = false

local PlaySoundFile = PlaySoundFile
local C_Timer       = C_Timer

local CLASS_SOUNDS = {
    [1]  = { "Sound\\Doodad\\G_GongTroll01.ogg",         "Sound\\Doodad\\G_GongTroll01.ogg" },
    [2]  = { "Sound\\Spells\\HolyLight.ogg",              "Sound\\Doodad\\BellTollAlliance.ogg" },
    [3]  = { "Sound\\Creature\\Wolf\\WolfHowl1.ogg",      "Sound\\Creature\\Wolf\\WolfHowl1.ogg" },
    [4]  = { "Sound\\Doodad\\G_GongTroll01.ogg",          "Sound\\Doodad\\G_GongTroll01.ogg" },
    [5]  = { "Sound\\Spells\\HolyLight.ogg",              "Sound\\Doodad\\BellTollAlliance.ogg" },
    [7]  = { "Sound\\Spells\\LightningBolt.ogg",          "Sound\\Spells\\ThunderClap.ogg" },
    [8]  = { "Sound\\Spells\\Fizzle.ogg",                 "Sound\\Spells\\Fizzle.ogg" },
    [9]  = { "Sound\\Spells\\ShadowWordPain.ogg",         "Sound\\Spells\\ShadowWordPain.ogg" },
    [11] = { "Sound\\Creature\\Bear\\BearDeath.ogg",      "Sound\\Creature\\Bear\\BearDeath.ogg" },
}

local CLASS_ICONS = {
    [1]  = "Interface\\Icons\\ClassIcon_Warrior",
    [2]  = "Interface\\Icons\\ClassIcon_Paladin",
    [3]  = "Interface\\Icons\\ClassIcon_Hunter",
    [4]  = "Interface\\Icons\\ClassIcon_Rogue",
    [5]  = "Interface\\Icons\\ClassIcon_Priest",
    [7]  = "Interface\\Icons\\ClassIcon_Shaman",
    [8]  = "Interface\\Icons\\ClassIcon_Mage",
    [9]  = "Interface\\Icons\\ClassIcon_Warlock",
    [11] = "Interface\\Icons\\ClassIcon_Druid",
}

function DeathBell:Initialize()
    self.enabled = true
    if GuildDeathLogDB and GuildDeathLogDB.settings then
        if GuildDeathLogDB.settings.deathBellEnabled == false then
            self.enabled = false
        end
    end
    self:CreateFlashFrame()
end

function DeathBell:CreateFlashFrame()
    local f = CreateFrame("Frame", "GDLDeathFlash", UIParent)
    f:SetAllPoints(UIParent)
    f:SetFrameStrata("FULLSCREEN_DIALOG")
    f:SetFrameLevel(999)
    f:EnableMouse(false)

    local overlay = f:CreateTexture(nil, "BACKGROUND")
    overlay:SetAllPoints()
    overlay:SetColorTexture(0.4, 0, 0, 0)
    f.overlay = overlay

    local skull = f:CreateTexture(nil, "OVERLAY")
    skull:SetSize(64, 64)
    skull:SetPoint("TOP", 0, -60)
    skull:SetAlpha(0)
    f.skull = skull

    local nameText = f:CreateFontString(nil, "OVERLAY")
    nameText:SetFont("Fonts\\MORPHEUS.TTF", 22, "OUTLINE")
    nameText:SetPoint("TOP", skull, "BOTTOM", 0, -10)
    nameText:SetTextColor(0.8, 0.1, 0.1)
    nameText:SetAlpha(0)
    f.nameText = nameText

    local subText = f:CreateFontString(nil, "OVERLAY")
    subText:SetFont("Fonts\\FRIZQT__.TTF", 12, "OUTLINE")
    subText:SetPoint("TOP", nameText, "BOTTOM", 0, -4)
    subText:SetTextColor(0.7, 0.7, 0.7)
    subText:SetAlpha(0)
    f.subText = subText

    local lastWordsText = f:CreateFontString(nil, "OVERLAY")
    lastWordsText:SetFont("Fonts\\MORPHEUS.TTF", 11, "OUTLINE")
    lastWordsText:SetPoint("TOP", subText, "BOTTOM", 0, -6)
    lastWordsText:SetTextColor(0.85, 0.75, 0.45)
    lastWordsText:SetAlpha(0)
    lastWordsText:Hide()
    f.lastWordsText = lastWordsText

    f:Hide()
    flashFrame = f
end

-- ── Queue: Tode einreihen, nicht direkt abspielen ─────────────
function DeathBell:QueueDeath(death)
    if not self.enabled then return end
    if not death or not death.name then return end
    table.insert(deathQueue, death)
    GDL:Debug("DeathBell: Queue +" .. death.name .. " (size=" .. #deathQueue .. ")")
    if not isPlaying then self:PlayNext() end
end

function DeathBell:PlayNext()
    if #deathQueue == 0 then
        isPlaying = false
        return
    end
    isPlaying = true
    local death = table.remove(deathQueue, 1)
    self:PlayDeathBell(death)
    C_Timer.After(FLASH_DURATION + QUEUE_COOLDOWN, function()
        self:PlayNext()
    end)
end

function DeathBell:PlayDeathBell(death)
    if not self.enabled then return end
    if not death or not death.name then return end

    local classId = death.classId or death.class
    local sounds  = CLASS_SOUNDS[classId]
    if sounds then
        PlaySoundFile(sounds[1], "Master")
        C_Timer.After(0.6, function() PlaySoundFile(sounds[2], "Master") end)
    else
        PlaySoundFile("Sound\\Doodad\\BellTollNightElf.ogg", "Master")
        C_Timer.After(0.6, function() PlaySoundFile("Sound\\Doodad\\BellTollNightElf.ogg", "Master") end)
    end

    if not flashFrame then return end

    local name  = death.name or "Unbekannt"
    local level = death.level or "?"
    local zone  = death.zone or ""
    local icon  = CLASS_ICONS[classId] or "Interface\\Icons\\Spell_Shadow_DeathPact"

    flashFrame.skull:SetTexture(icon)
    flashFrame.nameText:SetText(name .. " ist gefallen")
    flashFrame.subText:SetText("Level " .. level .. (zone ~= "" and (" - " .. zone) or ""))

    local LW = GDL:GetModule("LastWords")
    local lastWords = LW and LW:GetEffectiveLastWords(name)
    if lastWords and lastWords ~= "" then
        flashFrame.lastWordsText:SetText("\"" .. lastWords .. "\"")
        flashFrame.lastWordsText:Show()
    else
        flashFrame.lastWordsText:SetText("")
        flashFrame.lastWordsText:Hide()
    end

    flashFrame.overlay:SetAlpha(0)
    flashFrame.skull:SetAlpha(0)
    flashFrame.nameText:SetAlpha(0)
    flashFrame.subText:SetAlpha(0)
    flashFrame.lastWordsText:SetAlpha(0)
    flashFrame:SetScript("OnUpdate", nil)
    flashFrame:Show()

    local elapsed = 0
    flashFrame:SetScript("OnUpdate", function(self, dt)
        elapsed = elapsed + dt
        local progress = math.min(elapsed / FLASH_DURATION, 1)

        local flashAlpha
        if progress < 0.15 then
            flashAlpha = progress / 0.15 * 0.35
        elseif progress < 0.4 then
            flashAlpha = 0.35
        else
            flashAlpha = 0.35 * (1 - (progress - 0.4) / 0.6)
        end
        flashFrame.overlay:SetAlpha(flashAlpha)

        local textAlpha
        if progress < 0.1 then
            textAlpha = progress / 0.1
        elseif progress < 0.7 then
            textAlpha = 1
        else
            textAlpha = 1 - (progress - 0.7) / 0.3
        end
        flashFrame.skull:SetAlpha(textAlpha * 0.8)
        flashFrame.nameText:SetAlpha(textAlpha)
        flashFrame.subText:SetAlpha(textAlpha * 0.8)
        if flashFrame.lastWordsText:GetText() ~= "" then
            flashFrame.lastWordsText:SetAlpha(textAlpha * 0.9)
        end

        if progress >= 1 then
            flashFrame:Hide()
            flashFrame:SetScript("OnUpdate", nil)
        end
    end)
end

-- Externer Aufruf-Alias (Rückwärtskompatibilität)
function DeathBell:Play(death)
    self:QueueDeath(death)
end

function DeathBell:SetEnabled(enabled)
    self.enabled = enabled
    GuildDeathLogDB = GuildDeathLogDB or {}
    GuildDeathLogDB.settings = GuildDeathLogDB.settings or {}
    GuildDeathLogDB.settings.deathBellEnabled = enabled
end

function DeathBell:IsEnabled()
    return self.enabled
end

function DeathBell:GetQueueSize()
    return #deathQueue
end

GDL:RegisterModule("DeathBell", DeathBell)
