-- ══════════════════════════════════════════════════════════════
-- MODUL: DangerZone - Gefahrenzonen-Warnung (Supporter Feature)
-- Warnt beim Betreten von Zonen, in denen Gildenmitglieder
-- gestorben sind. Zeigt Todeszahl und letzte Gefallene.
-- Gold-Supporter: Zeigt zusaetzlich den toedlichsten Mob.
-- ══════════════════════════════════════════════════════════════

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

local warningFrame = nil
local fadeTimer = nil
local lastZone = nil

-- Konfiguration
local DISPLAY_DURATION = 8
local FADE_DURATION = 1.5
local MAX_NAMES = 5
local MIN_DEATHS = 1
local FRAME_WIDTH = 400

-- Klassenfarben
local CLASS_COLORS = {
    [1] = "ffC69B6D",  -- Krieger
    [2] = "ffF48CBA",  -- Paladin
    [3] = "ffAAD372",  -- Jaeger
    [4] = "ffFFF468",  -- Schurke
    [5] = "ffFFFFFF",  -- Priester
    [7] = "ff0070DD",  -- Schamane
    [8] = "ff3FC7EB",  -- Magier
    [9] = "ff8788EE",  -- Hexenmeister
    [11] = "ffFF7C0A", -- Druide
}

function DangerZone:Initialize()
    self.enabled = true

    if GuildDeathLogDB and GuildDeathLogDB.settings then
        if GuildDeathLogDB.settings.dangerZoneEnabled == false then
            self.enabled = false
        end
    end

    -- ExpansionData Pre-Seed: bekannte Gefahrenzonen vorladen
    -- So warnt DangerZone sofort, ohne dass erst Gildenmitglieder dort sterben müssen
    C_Timer.After(1, function()
        local Exp = GDL:GetModule("ExpansionData")
        if Exp then
            local dangerZones = Exp:GetDangerZones()
            if GuildDeathLogDB and GDL.currentGuildName then
                local guildData = GDL:GetGuildData()
                if guildData then
                    guildData.expansionDangerSeeds = guildData.expansionDangerSeeds or {}
                    for zoneName, level in pairs(dangerZones) do
                        if not guildData.expansionDangerSeeds[zoneName] then
                            guildData.expansionDangerSeeds[zoneName] = level
                        end
                    end
                    GDL:Debug("DangerZone: " .. Exp:CountTable(dangerZones) .. " Expansion-Zonen pre-seeded")
                end
            end
        end
    end)

    self:RegisterEvents()
    GDL:Debug("DangerZone: Modul initialisiert (enabled=" .. tostring(self.enabled) .. ")")
end

function DangerZone:RegisterEvents()
    local frame = CreateFrame("Frame")
    self.eventFrame = frame

    frame:RegisterEvent("ZONE_CHANGED_NEW_AREA")
    frame:RegisterEvent("PLAYER_ENTERING_WORLD")

    frame:SetScript("OnEvent", function(_, event)
        if not self.enabled then return end

        C_Timer.After(1.0, function()
            self:CheckCurrentZone()
        end)
    end)
end

function DangerZone:CheckCurrentZone()
    local zone = GetRealZoneText() or GetZoneText() or ""
    if zone == "" or zone == lastZone then return end
    lastZone = zone

    local guildData = GDL:GetGuildData()
    if not guildData then return end

    local deathCount = 0
    local recentDeaths = {}
    local killerCounts = {}

    -- Gilden-Tode aus SavedVariables zählen
    for i = #(guildData.deaths or {}), 1, -1 do
        local death = guildData.deaths[i]
        if death and death.zone and death.zone == zone then
            deathCount = deathCount + 1
            if #recentDeaths < MAX_NAMES then
                table.insert(recentDeaths, death)
            end
            -- Killer zaehlen
            local kn = death.killerName
            if kn and kn ~= "" then
                killerCounts[kn] = (killerCounts[kn] or 0) + 1
            end
        end
    end

    -- ExpansionData: bekannte Gefahrenzonen auch ohne Gilden-Tode warnen
    -- (z.B. beim ersten Betreten von Shadowmoon Valley in TBC)
    local Exp = GDL:GetModule("ExpansionData")
    if Exp then
        local seedLevel = Exp:GetZoneDangerLevel(zone)
        if seedLevel >= 2 and deathCount < MIN_DEATHS then
            -- Warnung mit Expansion-Basis, kein echter Tod nötig
            local expColor = Exp:GetExpansionColor()
            local isRaid   = Exp:IsRaid(zone)
            local raidTag  = isRaid and " |cffFF0000[RAID]|r" or ""
            GDL:Print(expColor .. "BEKANNTE GEFAHRENZONE|r |cff69CCF0" .. zone .. "|r" .. raidTag ..
                " |cff888888(Expansion-Warnung, Gefährlichkeit: " .. seedLevel .. "/3)|r")
            if seedLevel >= 3 and GuildDeathLogDB and GuildDeathLogDB.settings and GuildDeathLogDB.settings.sound ~= false then
                PlaySound(8959, "Master")
            end
            return
        end
    end

    if deathCount >= MIN_DEATHS then
        -- Achievement-Flag: "danger_zone" braucht dieses Flag
        if deathCount >= 5 and GuildDeathLogDB then
            GuildDeathLogDB.dangerZoneEntered = true
            local Ach = GDL:GetModule("Achievements")
            if Ach and Ach.CheckAll then Ach:CheckAll() end
        end

        local deadliestMob, deadliestCount = nil, 0
        for mob, count in pairs(killerCounts) do
            if count > deadliestCount then
                deadliestMob = mob
                deadliestCount = count
            end
        end
        local riskLevel = "NIEDRIG"
        local riskColor = "|cff00CC00"
        local playerLevel = UnitLevel("player") or 1
        local sameLevel = 0
        for _, d in ipairs(recentDeaths) do
            if d.level and math.abs(d.level - playerLevel) <= 5 then
                sameLevel = sameLevel + 1
            end
        end
        if deathCount >= 8 or sameLevel >= 3 then
            riskLevel = "SEHR HOCH"
            riskColor = "|cffFF0000"
        elseif deathCount >= 5 or sameLevel >= 2 then
            riskLevel = "HOCH"
            riskColor = "|cffFF4400"
        elseif deathCount >= 3 or sameLevel >= 1 then
            riskLevel = "MITTEL"
            riskColor = "|cffFFAA00"
        end
        self:ShowWarning(zone, deathCount, recentDeaths, deadliestMob, deadliestCount, riskLevel, riskColor)
    end
end

-- ══════════════════════════════════════════════════════════════
-- WARNING FRAME
-- ══════════════════════════════════════════════════════════════

function DangerZone:CreateWarningFrame()
    local f = CreateFrame("Frame", "GDLDangerZone", UIParent, "BackdropTemplate")
    f:SetSize(FRAME_WIDTH, 120)
    f:SetPoint("TOP", UIParent, "TOP", 0, -100)
    f:SetFrameStrata("DIALOG")
    f:SetFrameLevel(200)
    f:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8X8",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
        edgeSize = 16,
        insets = { left = 4, right = 4, top = 4, bottom = 4 },
    })
    f:SetBackdropColor(0.12, 0.02, 0.02, 0.95)
    f:SetBackdropBorderColor(0.7, 0.25, 0.1, 1)

    -- ── Totenkopf links ──
    local skullL = f:CreateTexture(nil, "ARTWORK")
    skullL:SetSize(24, 24)
    skullL:SetPoint("TOPLEFT", 14, -12)
    skullL:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcon_8")

    -- ── Totenkopf rechts ──
    local skullR = f:CreateTexture(nil, "ARTWORK")
    skullR:SetSize(24, 24)
    skullR:SetPoint("TOPRIGHT", -36, -12)
    skullR:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcon_8")

    -- ── Close-Button (X) ──
    local close = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    close:SetSize(22, 22)
    close:SetPoint("TOPRIGHT", -2, -2)
    close:SetScript("OnClick", function()
        DangerZone:HideWarning(true)
    end)

    -- ── Titel: "GEFAHRENZONE" ──
    local title = f:CreateFontString(nil, "OVERLAY")
    title:SetFont("Fonts\\MORPHEUS.TTF", 16, "OUTLINE")
    title:SetPoint("TOP", 0, -14)
    title:SetTextColor(1, 0.3, 0.15, 1)
    f.title = title

    -- ── Trennlinie ──
    local line = f:CreateTexture(nil, "ARTWORK")
    line:SetHeight(1)
    line:SetPoint("TOPLEFT", 16, -34)
    line:SetPoint("TOPRIGHT", -16, -34)
    line:SetColorTexture(0.6, 0.15, 0.1, 0.5)

    -- ── Warntext: "X Gefallene in dieser Zone!" ──
    local warning = f:CreateFontString(nil, "OVERLAY")
    warning:SetFont("Fonts\\FRIZQT__.TTF", 12, "")
    warning:SetPoint("TOP", 0, -40)
    warning:SetTextColor(1, 0.82, 0.3, 1)
    f.warning = warning

    -- ── Gefallene Namen (mehrzeilig) ──
    local names = f:CreateFontString(nil, "OVERLAY")
    names:SetFont("Fonts\\FRIZQT__.TTF", 10, "")
    names:SetPoint("TOP", warning, "BOTTOM", 0, -6)
    names:SetPoint("LEFT", 24, 0)
    names:SetPoint("RIGHT", -24, 0)
    names:SetJustifyH("CENTER")
    names:SetTextColor(0.75, 0.75, 0.75, 1)
    names:SetWordWrap(true)
    names:SetSpacing(2)
    f.names = names

    -- ── Deadliest Mob (Gold Feature, initial hidden) ──
    local mobLine = f:CreateFontString(nil, "OVERLAY")
    mobLine:SetFont("Fonts\\FRIZQT__.TTF", 10, "")
    mobLine:SetPoint("TOP", names, "BOTTOM", 0, -6)
    mobLine:SetJustifyH("CENTER")
    mobLine:SetTextColor(1, 0.4, 0.3, 1)
    mobLine:Hide()
    f.mobLine = mobLine

    -- ── Toggle-Checkbox unten links ──
    local toggle = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate")
    toggle:SetSize(20, 20)
    toggle:SetPoint("BOTTOMLEFT", 10, 6)
    toggle:SetChecked(self.enabled)
    toggle:SetScript("OnClick", function(self)
        DangerZone.enabled = self:GetChecked()
        if GuildDeathLogDB and GuildDeathLogDB.settings then
            GuildDeathLogDB.settings.dangerZoneEnabled = DangerZone.enabled
        end
    end)

    local toggleText = f:CreateFontString(nil, "OVERLAY")
    toggleText:SetFont("Fonts\\FRIZQT__.TTF", 9, "")
    toggleText:SetPoint("LEFT", toggle, "RIGHT", 2, 0)
    toggleText:SetTextColor(0.5, 0.5, 0.5, 0.8)
    toggleText:SetText(GDL:T("Warnung aktiv"))
    f.toggle = toggle

    -- ── Supporter Badge ──
    local badge = f:CreateFontString(nil, "OVERLAY")
    badge:SetFont("Fonts\\FRIZQT__.TTF", 8, "")
    badge:SetPoint("BOTTOMRIGHT", -10, 8)
    badge:SetTextColor(0.45, 0.35, 0.2, 0.5)
    badge:SetText("Supporter Feature")
    f.badge = badge

    f:Hide()
    warningFrame = f
end

function DangerZone:ShowWarning(zone, deathCount, recentDeaths, deadliestMob, deadliestCount, riskLevel, riskColor)
    if not warningFrame then
        self:CreateWarningFrame()
    end

    if fadeTimer then
        fadeTimer:Cancel()
        fadeTimer = nil
    end

    warningFrame.title:SetText((riskColor or "|cffFF4400") .. "RISIKO: " .. (riskLevel or "UNBEKANNT") .. "|r")

    warningFrame.warning:SetText(string.format(GDL:L("DZ_WARNING"), deathCount))

    -- Gefallene Namen aufbauen (jeder auf eigener Zeile)
    local nameEntries = {}
    for _, death in ipairs(recentDeaths) do
        local cc = CLASS_COLORS[death.classId] or "ffAAAAAA"
        local lvl = death.level or "?"
        local className = GDL:GetClassName(death.classId) or ""
        table.insert(nameEntries,
            "|c" .. cc .. (death.name or "?") .. "|r"
            .. "  |cff666666Lvl " .. lvl .. " " .. className .. "|r"
        )
    end

    local nameText = ""
    if #nameEntries > 0 then
        nameText = GDL:L("DZ_RECENT") .. "\n" .. table.concat(nameEntries, "\n")
    end
    warningFrame.names:SetText(nameText)

    -- Gold-Feature: Toedlichster Mob
    local showMob = false
    if deadliestMob and deadliestCount >= 2 then
        -- Gold-Check: Nur fuer Gold-Supporter
        local tier = GuildDeathLogDB and GuildDeathLogDB.supporterTier
        if tier == "G" then
            warningFrame.mobLine:SetText(
                "|cffFF4444Toedlichster Mob:|r |cffFFAAAA" .. deadliestMob
                .. "|r |cff888888(" .. deadliestCount .. " Kills)|r"
            )
            warningFrame.mobLine:Show()
            showMob = true
        end
    end
    if not showMob then
        warningFrame.mobLine:SetText("")
        warningFrame.mobLine:Hide()
    end

    -- Dynamische Hoehe berechnen
    local h = 54 -- Header + Warning
    h = h + (warningFrame.names:GetStringHeight() or 0) + 8
    if showMob then
        h = h + (warningFrame.mobLine:GetStringHeight() or 0) + 6
    end
    h = h + 28 -- Toggle-Checkbox + Padding unten
    if h < 90 then h = 90 end
    warningFrame:SetHeight(h)

    -- Checkbox-State aktualisieren
    warningFrame.toggle:SetChecked(self.enabled)

    -- Einblenden
    warningFrame:SetAlpha(0)
    warningFrame:Show()

    -- Fade In
    local elapsed = 0
    local fadeInFrame = CreateFrame("Frame")
    fadeInFrame:SetScript("OnUpdate", function(self, dt)
        elapsed = elapsed + dt
        local progress = math.min(elapsed / 0.3, 1)
        warningFrame:SetAlpha(progress)
        if progress >= 1 then
            self:SetScript("OnUpdate", nil)
        end
    end)

    -- Sound: SOUNDKIT-sicher
    if PlaySound then
        PlaySound(8959)
    end

    -- Auto-Hide Timer
    fadeTimer = C_Timer.NewTimer(DISPLAY_DURATION, function()
        self:HideWarning()
    end)

    GDL:Debug("DangerZone: " .. zone .. " - " .. deathCount .. " Tode")
end

function DangerZone:HideWarning(instant)
    if not warningFrame or not warningFrame:IsShown() then return end

    if fadeTimer then
        fadeTimer:Cancel()
        fadeTimer = nil
    end

    if instant then
        warningFrame:Hide()
        warningFrame:SetAlpha(1)
        return
    end

    -- Fade Out
    local startAlpha = warningFrame:GetAlpha()
    local elapsed = 0
    local fadeOutFrame = CreateFrame("Frame")
    fadeOutFrame:SetScript("OnUpdate", function(self, dt)
        elapsed = elapsed + dt
        local progress = math.min(elapsed / FADE_DURATION, 1)
        warningFrame:SetAlpha(startAlpha * (1 - progress))
        if progress >= 1 then
            warningFrame:Hide()
            warningFrame:SetAlpha(1)
            self:SetScript("OnUpdate", nil)
        end
    end)
end

-- ══════════════════════════════════════════════════════════════
-- TOGGLE / API
-- ══════════════════════════════════════════════════════════════

function DangerZone:Toggle()
    self.enabled = not self.enabled
    if GuildDeathLogDB and GuildDeathLogDB.settings then
        GuildDeathLogDB.settings.dangerZoneEnabled = self.enabled
    end
    if self.enabled then
        GDL:Print("|cff00FF00" .. GDL:L("DZ_ENABLED") .. "|r")
    else
        GDL:Print("|cffFF4444" .. GDL:L("DZ_DISABLED") .. "|r")
    end
end

function DangerZone:IsEnabled()
    return self.enabled
end

function DangerZone:Reset()
    lastZone = nil
    GDL:Print("|cffFFD100DangerZone: Reset|r")
end

GDL:RegisterModule("DangerZone", DangerZone)
