-- ══════════════════════════════════════════════════════════════
-- MODUL: Vows - Gilden-Geluebde (Guild Vows / Pledges)
-- Jedes Mitglied kann EIN oeffentliches Geluebde ablegen ("Stufe 60
-- ohne Tod", "kein Tod in der Klosterruine" ...). Gildenweit sichtbar.
-- Stirbt man mit aktivem Geluebde -> GEBROCHEN (Mahnung an die Gilde).
-- /gdl vow done -> erfuellt. Frei nutzbar (kein Supporter-Gate).
-- Sync nach bewaehrtem Titles-Muster (Full-State, REQUEST + Jitter).
-- ══════════════════════════════════════════════════════════════

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

local function T(de, en) return (GDL.WantEnglish and GDL:WantEnglish()) and en or de end

local PREFIX   = "GDLVow"
local MAX_LEN  = 60            -- Geluebde-Text laengen-kappen (Sync-sicher)
local ICON_VOW    = "Interface\\Icons\\INV_Scroll_03"
local ICON_DONE   = "Interface\\Icons\\Achievement_Quests_Completed_08"
local ICON_BROKE  = "Interface\\Icons\\Ability_CreatureCursed_05"

local guildVows = {}           -- name -> text (Laufzeit-Cache, nicht persistent)
local _lastReq  = 0            -- responder-seitiger Cooldown gegen REQUEST-Salven

-- ── Hilfen ────────────────────────────────────────────────────────────────────
local function myName() return UnitName("player") or "?" end

local function _send(msg)
    if not (C_ChatInfo and C_ChatInfo.SendAddonMessage) then return end
    if IsInGuild() then pcall(C_ChatInfo.SendAddonMessage, PREFIX, msg, "GUILD") end
    if IsInGroup and IsInGroup() then
        pcall(C_ChatInfo.SendAddonMessage, PREFIX, msg, (IsInRaid and IsInRaid()) and "RAID" or "PARTY")
    end
end

local function _toast(name, desc, icon, cat)
    local UI = GDL:GetModule("UI")
    if UI and UI.ShowMilestoneToast then
        UI:ShowMilestoneToast({ name = name, desc = desc, icon = icon, category = cat })
    end
end

-- ── Zustand ───────────────────────────────────────────────────────────────────
function Vows:GetMyVow()
    return GuildDeathLogDB and GuildDeathLogDB.myVow
end

function Vows:BroadcastMine()
    local v = self:GetMyVow()
    _send("VOW|" .. (v and v.text or ""))   -- leer = kein Geluebde (loescht beim Empfaenger)
    if GDL.Debug then GDL:Debug("Vows: -> SENT VOW " .. (v and "'" .. v.text .. "'" or "(leer)")) end
end

function Vows:RequestAll()
    _send("REQ")
    if GDL.Debug then GDL:Debug("Vows: REQUEST sent") end
end

-- ── Aktionen ──────────────────────────────────────────────────────────────────
function Vows:SetVow(text)
    if not text or text:gsub("%s", "") == "" then
        GDL:Print(T("Nutzung: /gdl vow <dein Geluebde>   |   /gdl vow done   |   /gdl vow clear",
                    "Usage: /gdl vow <your pledge>   |   /gdl vow done   |   /gdl vow clear"))
        return
    end
    text = text:gsub("|", "/"):gsub("%s+", " "):sub(1, MAX_LEN)
    GuildDeathLogDB.myVow = { text = text, start = time() }
    self:BroadcastMine()
    _toast(T("Geluebde abgelegt", "Vow Sworn"), text, ICON_VOW, "info")
    GDL:Print("|cffFFD100" .. T("Geluebde abgelegt:", "Vow sworn:") .. "|r |cffE8D8B0" .. text .. "|r")
end

function Vows:FulfillVow()
    local v = self:GetMyVow()
    if not v then
        GDL:Print(T("Du hast kein offenes Geluebde.", "You have no open vow.")); return
    end
    GuildDeathLogDB.myVow = nil
    self:BroadcastMine()                                   -- leeres VOW = Cache leeren
    _send("DONE|" .. v.text)                               -- Gilde benachrichtigen
    _toast(T("Geluebde erfuellt!", "Vow Fulfilled!"), v.text, ICON_DONE, "success")
    GDL:Print("|cff33FF66" .. T("Geluebde erfuellt:", "Vow fulfilled:") .. "|r |cffE8D8B0" .. v.text .. "|r")
end

function Vows:ClearVow(silent)
    GuildDeathLogDB.myVow = nil
    self:BroadcastMine()
    if not silent then GDL:Print(T("Geluebde aufgehoben.", "Vow cancelled.")) end
end

-- ── Tod-Hook (von DNLBridge:_PipelineStep2) ───────────────────────────────────
function Vows:OnDeath(deathData)
    if not (deathData and deathData.isSelf) then return end  -- nur eigener Tod bricht eigenes Geluebde
    local v = self:GetMyVow()
    if not v then return end
    GuildDeathLogDB.myVow = nil
    self:BroadcastMine()
    _send("BROKE|" .. v.text)
    _toast(T("Geluebde gebrochen", "Vow Broken"), v.text, ICON_BROKE, "warning")
    GDL:Print("|cffFF4422" .. T("Geluebde gebrochen:", "Vow broken:") .. "|r |cffE8D8B0" .. v.text .. "|r")
end

-- ── Liste: /gdl vows ──────────────────────────────────────────────────────────
function Vows:ListVows()
    local mine = self:GetMyVow()
    local any = false
    GDL:Print("|cffFFD100" .. T("Gilden-Geluebde:", "Guild Vows:") .. "|r")
    if mine then
        GDL:Print("  |cff33FF66" .. myName() .. " (" .. T("du", "you") .. ")|r: |cffE8D8B0" .. mine.text .. "|r")
        any = true
    end
    -- Nach Name sortiert ausgeben
    local names = {}
    for n in pairs(guildVows) do names[#names + 1] = n end
    table.sort(names)
    for _, n in ipairs(names) do
        if guildVows[n] and guildVows[n] ~= "" then
            GDL:Print("  |cffFFD100" .. n .. "|r: |cffE8D8B0" .. guildVows[n] .. "|r")
            any = true
        end
    end
    if not any then
        GDL:Print("  |cff888888" .. T("Noch keine Geluebde abgelegt. /gdl vow <Text>",
                                       "No vows sworn yet. /gdl vow <text>") .. "|r")
    end
end

-- ── Empfang ───────────────────────────────────────────────────────────────────
function Vows:HandleAddonMessage(msg, sender)
    if not msg or msg == "" then return end
    local name = (strsplit("-", sender))
    if name == myName() then return end                    -- eigenes Echo

    if msg == "REQ" then
        local now = GetTime()
        if (now - _lastReq) < 5 then return end            -- Salven daempfen
        _lastReq = now
        C_Timer.After(math.random() * 2, function() self:BroadcastMine() end)
        return
    end

    local cmd, data = strsplit("|", msg, 2)
    if cmd == "VOW" then
        local txt = data and data ~= "" and data:sub(1, MAX_LEN) or nil
        guildVows[name] = txt                               -- Full-State (nil = geloescht)
        if GDL.Debug then GDL:Debug("Vows: <- RECV VOW " .. name .. (txt and " '" .. txt .. "'" or " (leer)")) end
    elseif cmd == "DONE" then
        GDL:Print("|cff33FF66" .. string.format(
            T("%s hat ein Geluebde erfuellt: ", "%s fulfilled a vow: "), name)
            .. "|r|cffE8D8B0" .. (data or ""):sub(1, MAX_LEN) .. "|r")
    elseif cmd == "BROKE" then
        GDL:Print("|cffFF4422" .. string.format(
            T("%s hat ein Geluebde gebrochen: ", "%s broke a vow: "), name)
            .. "|r|cffE8D8B0" .. (data or ""):sub(1, MAX_LEN) .. "|r")
    end
end

-- ── Roster-Cleanup: Nicht-Mehr-Mitglieder entfernen ──────────────────────────
function Vows:CleanupNonMembers()
    local Guild = GDL:GetModule("Guild")
    if not (Guild and Guild.IsMember) then return end
    for n in pairs(guildVows) do
        if not Guild:IsMember(n) then guildVows[n] = nil end
    end
end

function Vows:Initialize()
    if self._initialized then return end
    self._initialized = true

    if C_ChatInfo and C_ChatInfo.RegisterAddonMessagePrefix then
        pcall(C_ChatInfo.RegisterAddonMessagePrefix, PREFIX)
    end

    local f = CreateFrame("Frame")
    f:RegisterEvent("CHAT_MSG_ADDON")
    f:RegisterEvent("GUILD_ROSTER_UPDATE")
    f:SetScript("OnEvent", function(_, event, ...)
        if event == "CHAT_MSG_ADDON" then
            local prefix, message, channel, sender = ...
            if prefix == PREFIX and (channel == "GUILD" or channel == "PARTY" or channel == "RAID") then
                self:HandleAddonMessage(message, sender)
            end
        elseif event == "GUILD_ROSTER_UPDATE" then
            C_Timer.After(5, function() self:CleanupNonMembers() end)
        end
    end)

    -- Beim Login: andere abfragen + eigenes Geluebde verteilen
    C_Timer.After(10, function() self:RequestAll() end)
    C_Timer.After(14, function() if self:GetMyVow() then self:BroadcastMine() end end)

    if GDL.Debug then GDL:Debug("Vows: initialisiert") end
end

GDL:RegisterModule("Vows", Vows)
