-- ══════════════════════════════════════════════════════════════
-- MODUL: MinimapButton — "Der Todesherold" v8.3
-- Totenkopf-Icon · 3 Orbit-Runen · Tod-Zähler-Badge
-- Atemleuchten · Dramatisches Hover-Panel
-- ══════════════════════════════════════════════════════════════

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

local button      = nil
local hoverPanel  = nil
local isDragging  = false
local hideTimer   = nil
local orbitAngle  = 0

local math_cos = math.cos
local math_sin = math.sin
local math_pi  = math.pi

-- ──────────────────────────────────────────────────────────────
-- Hover-Panel (neu: düsteres Todesherold-Design)
-- ──────────────────────────────────────────────────────────────
local function BuildHoverPanel()
    local p = CreateFrame("Frame", "GDLMinimapHoverPanel", UIParent, "BackdropTemplate")
    p:SetSize(252, 230)
    p:SetFrameStrata("TOOLTIP")
    p:SetFrameLevel(120)
    p:SetBackdrop({
        bgFile   = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 14,
        insets   = { left = 4, right = 4, top = 4, bottom = 4 },
    })
    p:SetBackdropColor(0.04, 0.02, 0.01, 0.97)
    p:SetBackdropBorderColor(0.65, 0.12, 0.08, 0.95)
    p:EnableMouse(true)
    p:Hide()

    -- Obere rote Accent-Linie
    local topAccent = p:CreateTexture(nil, "OVERLAY")
    topAccent:SetSize(244, 2)
    topAccent:SetPoint("TOPLEFT", 4, -4)
    topAccent:SetColorTexture(0.80, 0.12, 0.08, 0.88)

    local function Ln(font, size, flags, yOff)
        local fs = p:CreateFontString(nil, "OVERLAY")
        fs:SetFont("Fonts\\" .. font .. ".TTF", size, flags or "")
        fs:SetPoint("TOPLEFT", 14, yOff)
        fs:SetShadowOffset(1, -1)
        fs:SetShadowColor(0, 0, 0, 0.90)
        return fs
    end

    -- ── Header ──────────────────────────────────────────────
    local hdrIcon = p:CreateTexture(nil, "ARTWORK")
    hdrIcon:SetTexture("Interface\\Icons\\Spell_Shadow_DeathPact")
    hdrIcon:SetSize(22, 22)
    hdrIcon:SetPoint("TOPLEFT", 10, -8)

    local hdrTitle = p:CreateFontString(nil, "OVERLAY")
    hdrTitle:SetFont("Fonts\\MORPHEUS.TTF", 13, "")
    hdrTitle:SetPoint("TOPLEFT", 37, -10)
    hdrTitle:SetTextColor(0.95, 0.22, 0.16)
    hdrTitle:SetShadowOffset(1, -1)
    hdrTitle:SetShadowColor(0, 0, 0, 0.95)
    hdrTitle:SetText("Das Buch der Gefallenen")

    local div1 = p:CreateTexture(nil, "ARTWORK")
    div1:SetSize(228, 1)
    div1:SetPoint("TOPLEFT", 10, -35)
    div1:SetColorTexture(0.55, 0.10, 0.06, 0.75)

    -- ── Stats ────────────────────────────────────────────────
    local deathsLn = Ln("FRIZQT__", 10, "OUTLINE", -41)
    p.deathsLn = deathsLn

    local onlineLn = Ln("FRIZQT__", 9, "", -56)
    p.onlineLn = onlineLn

    local addonOnlineLn = Ln("FRIZQT__", 9, "", -68)
    p.addonOnlineLn = addonOnlineLn

    local div2 = p:CreateTexture(nil, "ARTWORK")
    div2:SetSize(228, 1)
    div2:SetPoint("TOPLEFT", 10, -82)
    div2:SetColorTexture(0.32, 0.08, 0.05, 0.55)

    -- ── Gilden-Moral ─────────────────────────────────────────
    local morLbl = Ln("FRIZQT__", 9, "", -88)
    morLbl:SetTextColor(0.65, 0.22, 0.18)
    morLbl:SetText("Gilden-Moral")
    p.morLbl = morLbl

    local morStatus = p:CreateFontString(nil, "OVERLAY")
    morStatus:SetFont("Fonts\\FRIZQT__.TTF", 9, "OUTLINE")
    morStatus:SetPoint("TOPRIGHT", -12, -88)
    morStatus:SetShadowOffset(1, -1)
    morStatus:SetShadowColor(0, 0, 0, 0.75)
    p.morStatus = morStatus

    local barBg = p:CreateTexture(nil, "BACKGROUND")
    barBg:SetSize(228, 10)
    barBg:SetPoint("TOPLEFT", 10, -102)
    barBg:SetColorTexture(0.12, 0.04, 0.02, 0.92)

    local morBar = CreateFrame("StatusBar", nil, p)
    morBar:SetSize(228, 10)
    morBar:SetPoint("TOPLEFT", 10, -102)
    morBar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
    morBar:SetMinMaxValues(0, 500)
    morBar:SetValue(0)
    morBar:SetStatusBarColor(0.80, 0.10, 0.10)
    p.morBar = morBar

    local barSheen = p:CreateTexture(nil, "OVERLAY")
    barSheen:SetSize(228, 4)
    barSheen:SetPoint("TOPLEFT", 10, -102)
    barSheen:SetColorTexture(1, 1, 1, 0.06)

    local morScore = Ln("FRIZQT__", 8, "", -116)
    morScore:SetTextColor(0.40, 0.16, 0.12)
    p.morScore = morScore

    local div3 = p:CreateTexture(nil, "ARTWORK")
    div3:SetSize(228, 1)
    div3:SetPoint("TOPLEFT", 10, -128)
    div3:SetColorTexture(0.32, 0.08, 0.05, 0.55)

    -- ── Aktionen ─────────────────────────────────────────────
    local function ActionRow(yOff, keyText, descText)
        local keyBg = p:CreateTexture(nil, "BACKGROUND")
        keyBg:SetSize(74, 13)
        keyBg:SetPoint("TOPLEFT", 10, yOff + 1)
        keyBg:SetColorTexture(0.18, 0.06, 0.04, 0.68)

        local kw = p:CreateFontString(nil, "OVERLAY")
        kw:SetFont("Fonts\\FRIZQT__.TTF", 8, "OUTLINE")
        kw:SetPoint("TOPLEFT", 12, yOff)
        kw:SetShadowOffset(1, -1)
        kw:SetShadowColor(0, 0, 0, 0.75)
        kw:SetText("|cffFF6655" .. keyText .. "|r")

        local dsc = p:CreateFontString(nil, "OVERLAY")
        dsc:SetFont("Fonts\\FRIZQT__.TTF", 8, "")
        dsc:SetPoint("TOPLEFT", 90, yOff)
        dsc:SetTextColor(0.68, 0.50, 0.38)
        dsc:SetText(descText)
    end
    ActionRow(-134, "Klick",        "Buch oeffnen / schliessen")
    ActionRow(-147, "Shift+Klick",  "Gilde synchronisieren")
    ActionRow(-160, "Rechtsklick",  "Einstellungen")
    ActionRow(-173, "Ziehen",       "Button verschieben")

    local div4 = p:CreateTexture(nil, "ARTWORK")
    div4:SetSize(228, 1)
    div4:SetPoint("TOPLEFT", 10, -188)
    div4:SetColorTexture(0.32, 0.08, 0.05, 0.55)

    -- ── Supporter ────────────────────────────────────────────
    local supLine = p:CreateFontString(nil, "OVERLAY")
    supLine:SetFont("Fonts\\FRIZQT__.TTF", 9, "OUTLINE")
    supLine:SetPoint("BOTTOMLEFT", 12, 9)
    supLine:SetShadowOffset(1, -1)
    supLine:SetShadowColor(0, 0, 0, 0.85)
    p.supLine = supLine

    p:SetScript("OnLeave", function(self) self:Hide() end)
    return p
end

-- ──────────────────────────────────────────────────────────────
-- Panel-Daten + Badge aktualisieren
-- ──────────────────────────────────────────────────────────────
local function RefreshPanel(p)
    local guildData = GDL:GetGuildData()
    local dc = guildData and guildData.deaths and #guildData.deaths or 0

    if dc > 0 then
        p.deathsLn:SetText("|TInterface\\Icons\\Spell_Shadow_SoulLeech_3:14:14|t  |cffFF4444" .. dc .. "|r |cff7A3030Tode verzeichnet|r")
    else
        p.deathsLn:SetText("|cff3A2020Noch keine Tode verzeichnet|r")
    end

    local Guild = GDL:GetModule("Guild")
    if Guild and Guild.GetOnlineCount then
        local online, total = Guild:GetOnlineCount()
        p.onlineLn:SetText("|TInterface\\Icons\\INV_Misc_GroupNeedMore:12:12|t  |cff66AAFF" .. (online or "?") .. "|r |cff4A3030von|r |cff8888CC" .. (total or "?") .. "|r |cff4A3030online|r")
    else
        local total = GetNumGuildMembers and GetNumGuildMembers() or 0
        if total > 0 then
            p.onlineLn:SetText("|TInterface\\Icons\\INV_Misc_GroupNeedMore:12:12|t  |cff4A3030" .. total .. " Mitglieder|r")
        else
            p.onlineLn:SetText("|cff3A2020Keine Gildendaten verfuegbar|r")
        end
    end

    local Sync = GDL:GetModule("Sync")
    if Sync then
        local addonUsers = Sync:GetOnlineUsers()
        local count = #addonUsers
        if count > 0 then
            p.addonOnlineLn:SetText("|TInterface\\Icons\\Spell_Shadow_DeathPact:12:12|t  |cffFF8844" .. count .. "|r |cff5A3030mit Addon online|r")
        else
            p.addonOnlineLn:SetText("|TInterface\\Icons\\Spell_Shadow_DeathPact:12:12|t  |cff3A2020Kein Addon-Nutzer online|r")
        end
    else
        p.addonOnlineLn:SetText("|cff3A2020Addon-Sync inaktiv|r")
    end

    local Ach = GDL:GetModule("Achievements")
    if Ach then
        local score, label = Ach:GetGuildMoraleScore()
        score = score or 0
        p.morBar:SetValue(math.min(score, 500))
        if score >= 500 then
            p.morBar:SetStatusBarColor(0.00, 0.88, 0.35)
            p.morStatus:SetText("|cff00FF66" .. (label or "Legendaer") .. "|r")
        elseif score >= 250 then
            p.morBar:SetStatusBarColor(0.30, 0.75, 0.15)
            p.morStatus:SetText("|cff66DD44" .. (label or "Stark") .. "|r")
        elseif score >= 100 then
            p.morBar:SetStatusBarColor(1.00, 0.75, 0.00)
            p.morStatus:SetText("|cffFFD100" .. (label or "Stabil") .. "|r")
        elseif score >= 40 then
            p.morBar:SetStatusBarColor(1.00, 0.48, 0.00)
            p.morStatus:SetText("|cffFF7700" .. (label or "Angespannt") .. "|r")
        else
            p.morBar:SetStatusBarColor(0.88, 0.08, 0.08)
            p.morStatus:SetText("|cffFF2222" .. (label or "Erschoepft") .. "|r")
        end
        p.morScore:SetText("Moral-Score: " .. score .. " / 500")
    else
        p.morBar:SetValue(0)
        p.morStatus:SetText("|cff444444-|r")
        p.morScore:SetText("")
    end

    if GuildDeathLogDB and GuildDeathLogDB.supporterActive and GuildDeathLogDB.supporterTier then
        local tier    = GuildDeathLogDB.supporterTier
        local tNames  = { B = "Bronze", S = "Silber", G = "Gold" }
        local tColors = { B = "|cffCD7F32", S = "|cffC0C0C0", G = "|cffFFD700" }
        p.supLine:SetText("|TInterface\\Icons\\INV_ValentinesCard01:14:14|t  " .. (tColors[tier] or "|cffFFFFFF") .. "Supporter: " .. (tNames[tier] or tier) .. "|r")
    else
        p.supLine:SetText("|cff3A2020Supporter: Inaktiv|r")
    end

    -- Badge am Button aktualisieren
    if button and button.badge then
        if dc > 0 then
            button.badgeText:SetText(dc > 99 and "99+" or tostring(dc))
            button.badge:SetAlpha(1)
        else
            button.badge:SetAlpha(0)
        end
    end
end

-- ──────────────────────────────────────────────────────────────
-- Button erstellen
-- ──────────────────────────────────────────────────────────────
function MinimapButton:Initialize()
    self:CreateButton()
end

function MinimapButton:CreateButton()
    local btn = CreateFrame("Button", "GDLMinimapButton", Minimap)
    btn:SetSize(31, 31)
    btn:SetFrameStrata("MEDIUM")
    btn:SetFrameLevel(8)
    btn:EnableMouse(true)
    btn:SetMovable(true)
    btn:RegisterForClicks("LeftButtonUp", "RightButtonUp")
    btn:RegisterForDrag("LeftButton")
    btn:SetClampedToScreen(true)

    -- ── Totenkopf-Icon ──────────────────────────────────────
    local icon = btn:CreateTexture(nil, "BACKGROUND")
    icon:SetSize(22, 22)
    icon:SetPoint("CENTER", 0, 0)
    icon:SetTexture("Interface\\Icons\\Spell_Shadow_DeathPact")
    btn.icon = icon

    -- ── Runder Border (rot getönt) ──────────────────────────
    local border = btn:CreateTexture(nil, "OVERLAY")
    border:SetSize(52, 52)
    border:SetPoint("TOPLEFT", 0, 0)
    border:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
    border:SetVertexColor(0.88, 0.45, 0.42, 1)
    btn.border = border

    -- ── Hover-Highlight ─────────────────────────────────────
    local highlight = btn:CreateTexture(nil, "HIGHLIGHT")
    highlight:SetSize(24, 24)
    highlight:SetPoint("CENTER", 0, 0)
    highlight:SetTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
    highlight:SetBlendMode("ADD")
    highlight:SetAlpha(0.35)

    -- ── Push-Effekt ─────────────────────────────────────────
    btn:SetScript("OnMouseDown", function(self) if not isDragging then icon:SetPoint("CENTER", 1, -1) end end)
    btn:SetScript("OnMouseUp",   function(self) icon:SetPoint("CENTER", 0, 0) end)

    -- ── 3 Orbiting Runen ────────────────────────────────────
    local ORBIT_R    = 19
    local RUNE_COUNT = 3
    local orbitRunes = {}
    for i = 1, RUNE_COUNT do
        local rf = CreateFrame("Frame", nil, btn)
        rf:SetSize(6, 6)
        rf:SetFrameLevel(btn:GetFrameLevel() + 5)
        local rt = rf:CreateTexture(nil, "OVERLAY")
        rt:SetAllPoints()
        rt:SetBlendMode("ADD")
        rt:SetTexture("Interface\\Cooldown\\ping4")
        rt:SetVertexColor(0.92, 0.65, 0.18, 1)
        rf:SetAlpha(0.65)
        rf:SetPoint("CENTER", btn, "CENTER", 0, 0)
        rf:Show()
        orbitRunes[i] = { f = rf, baseAngle = (i - 1) * (math_pi * 2 / RUNE_COUNT) }
    end
    local orbitTicker = CreateFrame("Frame", nil, btn)
    orbitTicker:SetScript("OnUpdate", function(self, dt)
        orbitAngle = orbitAngle + 0.85 * dt
        for i = 1, RUNE_COUNT do
            local rn  = orbitRunes[i]
            local ang = rn.baseAngle + orbitAngle
            rn.f:ClearAllPoints()
            rn.f:SetPoint("CENTER", btn, "CENTER", math_cos(ang) * ORBIT_R, math_sin(ang) * ORBIT_R)
        end
    end)
    orbitTicker:Show()
    btn.orbitTicker = orbitTicker
    btn.orbitRunes  = orbitRunes

    -- ── Todes-Zähler-Badge (oben rechts) ───────────────────
    local badge = CreateFrame("Frame", nil, btn)
    badge:SetSize(15, 15)
    badge:SetPoint("TOPRIGHT", btn, "TOPRIGHT", 5, 5)
    badge:SetFrameLevel(btn:GetFrameLevel() + 10)
    local badgeBg = badge:CreateTexture(nil, "BACKGROUND")
    badgeBg:SetAllPoints()
    badgeBg:SetTexture("Interface\\Buttons\\WHITE8x8")
    badgeBg:SetVertexColor(0.78, 0.05, 0.05, 1)
    local badgeBorder = badge:CreateTexture(nil, "OVERLAY")
    badgeBorder:SetSize(17, 17)
    badgeBorder:SetPoint("CENTER")
    badgeBorder:SetTexture("Interface\\Buttons\\WHITE8x8")
    badgeBorder:SetVertexColor(0, 0, 0, 0.65)
    local badgeInner = badge:CreateTexture(nil, "ARTWORK")
    badgeInner:SetSize(13, 13)
    badgeInner:SetPoint("CENTER")
    badgeInner:SetTexture("Interface\\Buttons\\WHITE8x8")
    badgeInner:SetVertexColor(0.82, 0.08, 0.06, 1)
    local badgeText = badge:CreateFontString(nil, "OVERLAY")
    badgeText:SetFont("Fonts\\FRIZQT__.TTF", 7, "OUTLINE")
    badgeText:SetAllPoints()
    badgeText:SetJustifyH("CENTER")
    badgeText:SetJustifyV("MIDDLE")
    badgeText:SetText("0")
    badgeText:SetTextColor(1, 1, 1)
    badge:SetAlpha(0)
    badge:Show()
    btn.badge     = badge
    btn.badgeText = badgeText

    -- ── Persistentes Atem-Leuchten ──────────────────────────
    local breathGlow = CreateFrame("Frame", nil, btn)
    breathGlow:SetSize(50, 50)
    breathGlow:SetPoint("CENTER", 0, 0)
    breathGlow:SetFrameLevel(btn:GetFrameLevel() - 1)
    local breathTex = breathGlow:CreateTexture(nil, "ARTWORK")
    breathTex:SetAllPoints()
    breathTex:SetTexture("Interface\\Cooldown\\starburst")
    breathTex:SetBlendMode("ADD")
    breathTex:SetVertexColor(0.80, 0.14, 0.08, 1)
    breathGlow:SetAlpha(0.15)
    breathGlow:Show()
    local breathAG = breathGlow:CreateAnimationGroup()
    breathAG:SetLooping("BOUNCE")
    local breathFade = breathAG:CreateAnimation("Alpha")
    breathFade:SetFromAlpha(0.10)
    breathFade:SetToAlpha(0.45)
    breathFade:SetDuration(2.2)
    breathFade:SetSmoothing("IN_OUT")
    breathFade:SetOrder(1)
    breathAG:Play()
    btn.breathAG = breathAG

    -- ── Hover-Panel ─────────────────────────────────────────
    hoverPanel = BuildHoverPanel()

    btn:SetScript("OnEnter", function(self)
        if isDragging then return end
        if hideTimer then hideTimer:Cancel(); hideTimer = nil end
        RefreshPanel(hoverPanel)
        hoverPanel:ClearAllPoints()
        hoverPanel:SetPoint("TOPRIGHT", self, "TOPLEFT", -4, 8)
        hoverPanel:Show()
    end)
    btn:SetScript("OnLeave", function(self)
        hideTimer = C_Timer.NewTimer(0.12, function()
            if not hoverPanel:IsMouseOver() then hoverPanel:Hide() end
            hideTimer = nil
        end)
    end)

    -- ── Klick-Handler ───────────────────────────────────────
    btn:SetScript("OnClick", function(self, mouseBtn)
        if isDragging then return end
        hoverPanel:Hide()
        if mouseBtn == "LeftButton" then
            if IsShiftKeyDown() then
                local Sync = GDL:GetModule("Sync")
                if Sync then Sync:RequestFullSync() end
            else
                local UI = GDL:GetModule("UI")
                if UI then
                    if UI.mainFrame and UI.mainFrame:IsShown() then
                        UI:HideBook()
                    else
                        UI:ShowBook()
                    end
                end
            end
        elseif mouseBtn == "RightButton" then
            local UI = GDL:GetModule("UI")
            if UI then UI:ShowSettings() end
        end
    end)

    -- ── Drag ────────────────────────────────────────────────
    btn:SetScript("OnDragStart", function(self)
        isDragging = true; hoverPanel:Hide(); self:StartMoving()
    end)
    btn:SetScript("OnDragStop", function(self)
        self:StopMovingOrSizing(); isDragging = false
        local mx, my = Minimap:GetCenter()
        local bx, by = self:GetCenter()
        if GuildDeathLogDB and GuildDeathLogDB.settings then
            GuildDeathLogDB.settings.minimapBtnX = bx - mx
            GuildDeathLogDB.settings.minimapBtnY = by - my
        end
    end)

    -- ── Glow-Ring bei neuem Tod ─────────────────────────────
    local glowRing = CreateFrame("Frame", nil, btn)
    glowRing:SetSize(50, 50); glowRing:SetPoint("CENTER", 0, 0); glowRing:SetAlpha(0)
    local glowTex = glowRing:CreateTexture(nil, "OVERLAY")
    glowTex:SetAllPoints()
    glowTex:SetTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
    glowTex:SetBlendMode("ADD"); glowTex:SetVertexColor(1, 0.10, 0.06, 1)
    local pulseAG = glowRing:CreateAnimationGroup(); pulseAG:SetLooping("NONE")
    local p1 = pulseAG:CreateAnimation("Alpha"); p1:SetFromAlpha(0); p1:SetToAlpha(0.95); p1:SetDuration(0.18); p1:SetSmoothing("OUT"); p1:SetOrder(1)
    local p2 = pulseAG:CreateAnimation("Alpha"); p2:SetFromAlpha(0.95); p2:SetToAlpha(0); p2:SetDuration(0.20); p2:SetSmoothing("IN"); p2:SetOrder(2)
    local p3 = pulseAG:CreateAnimation("Alpha"); p3:SetFromAlpha(0); p3:SetToAlpha(0.95); p3:SetDuration(0.16); p3:SetSmoothing("OUT"); p3:SetOrder(3)
    local p4 = pulseAG:CreateAnimation("Alpha"); p4:SetFromAlpha(0.95); p4:SetToAlpha(0); p4:SetDuration(0.42); p4:SetSmoothing("IN"); p4:SetOrder(4)
    pulseAG:SetScript("OnFinished", function() glowRing:SetAlpha(0) end)
    btn.pulseAG  = pulseAG
    btn.glowRing = glowRing

    button = btn

    -- Position laden
    local relX, relY = 65, 65
    if GuildDeathLogDB and GuildDeathLogDB.settings then
        relX = GuildDeathLogDB.settings.minimapBtnX or relX
        relY = GuildDeathLogDB.settings.minimapBtnY or relY
    end
    btn:ClearAllPoints()
    btn:SetPoint("CENTER", Minimap, "CENTER", relX, relY)

    GDL:Debug("MinimapButton: Todesherold-Button erstellt (v8.3)")
end

-- ──────────────────────────────────────────────────────────────
-- Public API
-- ──────────────────────────────────────────────────────────────
function MinimapButton:Pulse()
    if button and button.pulseAG then
        button.pulseAG:Stop()
        button.pulseAG:Play()
    end
    -- Badge-Zähler aktualisieren
    if button and button.badge then
        local gd     = GDL:GetGuildData()
        local dcount = gd and gd.deaths and #gd.deaths or 0
        if dcount > 0 then
            button.badgeText:SetText(dcount > 99 and "99+" or tostring(dcount))
            button.badge:SetAlpha(1)
        end
    end
    -- Orbit-Runen kurz aufleuchten
    if button and button.orbitRunes then
        for _, rn in ipairs(button.orbitRunes) do
            rn.f:SetAlpha(1.0)
            C_Timer.After(0.9, function() if rn and rn.f then rn.f:SetAlpha(0.65) end end)
        end
    end
end

function MinimapButton:Show()
    if button then button:Show() end
end

function MinimapButton:Hide()
    if button then button:Hide() end
end

function MinimapButton:IsShown()
    return button and button:IsShown()
end

GDL:RegisterModule("MinimapButton", MinimapButton)
