-- ══════════════════════════════════════════════════════════════
-- MODUL: SafeDays - "Tage ohne Verlust" (Guild Safety Streak)
-- Gildenweite Serie: wie lange ist der letzte Gildentod her + Rekord.
-- Voll aus den BEREITS gesyncten Todesdaten abgeleitet -> KEIN neuer
-- Sync, KEIN DNLBridge-Hook (poll-basiert: erkennt neue Tode selbst).
-- Das "X Tage ohne Unfall"-Schild fuer Hardcore-Gilden.
-- ══════════════════════════════════════════════════════════════

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

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

local DAY        = 86400
local THRESHOLDS = { 1, 3, 7, 14, 30, 60, 100, 180, 365 }
local ICON_SAFE  = "Interface\\Icons\\INV_Shield_06"
local ICON_END   = "Interface\\Icons\\Spell_Shadow_DeathCoil"

SafeDays._lastSeenDeathTs   = nil   -- zuletzt gesehener letzter-Tod-Timestamp (Poll)
SafeDays._announcedThreshold = 0    -- hoechste schon angekuendigte Schwelle DIESER Serie

-- ── Letzter Gildentod (aus gesyncter DB) ──────────────────────────────────────
function SafeDays:GetLastDeath()
    local gd = GDL.GetGuildData and GDL:GetGuildData()
    if not (gd and gd.deaths and #gd.deaths > 0) then return nil end
    local latest, name
    for _, d in ipairs(gd.deaths) do
        local ts = d.timestamp or 0
        if not latest or ts > latest then latest = ts; name = d.name end
    end
    return latest, name
end

function SafeDays:GetDays()
    local ts = self:GetLastDeath()
    if not ts then return nil end
    local secs = time() - ts
    if secs < 0 then secs = 0 end
    return math.floor(secs / DAY), ts
end

-- ── Rekord: groesste Luecke zwischen Toden + laufende Serie, persistiert ───────
function SafeDays:GetRecord()
    local best = (GuildDeathLogDB and GuildDeathLogDB.safeDaysRecord) or 0
    local gd = GDL.GetGuildData and GDL:GetGuildData()
    if gd and gd.deaths and #gd.deaths > 1 then
        local ts = {}
        for _, d in ipairs(gd.deaths) do ts[#ts + 1] = d.timestamp or 0 end
        table.sort(ts)
        for i = 2, #ts do
            local gap = math.floor((ts[i] - ts[i - 1]) / DAY)
            if gap > best then best = gap end
        end
    end
    local cur = self:GetDays()
    if cur and cur > best then best = cur end
    if GuildDeathLogDB then GuildDeathLogDB.safeDaysRecord = best end
    return best
end

-- Kurzform fuer Tooltips/Anzeige (z.B. Minimap)
function SafeDays:GetShortLine()
    local days = self:GetDays()
    if not days then return nil end
    return string.format(T("%d Tage ohne Verlust", "%d days without a loss"), days)
end

-- ── /gdl safedays ─────────────────────────────────────────────────────────────
function SafeDays:Print()
    local days = self:GetDays()
    if not days then
        GDL:Print(T("Noch keine Gildentode verzeichnet — moege es so bleiben.",
                    "No guild deaths recorded yet — may it stay that way."))
        return
    end
    local rec = self:GetRecord()
    local _, name = self:GetLastDeath()
    GDL:Print("|cff66DD66" .. string.format(
        T("Die Gilde: |cffFFD100%d|r|cff66DD66 Tag(e) ohne Verlust.",
          "The guild: |cffFFD100%d|r|cff66DD66 day(s) without a loss."), days) .. "|r")
    GDL:Print("|cff888888" .. string.format(T("Rekord: %d Tage", "Record: %d days"), rec)
        .. (name and ("   |   " .. T("Zuletzt gefallen: ", "Last fallen: ") .. name) or "") .. "|r")
end

-- ── Schwellen-Ankuendigung ────────────────────────────────────────────────────
function SafeDays:CheckThreshold()
    local days = self:GetDays()
    if not days then return end
    local hit = 0
    for _, th in ipairs(THRESHOLDS) do if days >= th then hit = th end end
    if hit > (self._announcedThreshold or 0) then
        self._announcedThreshold = hit
        local msg = string.format(
            T("Die Gilde steht seit %d Tagen ohne Verlust. Bleibt wachsam!",
              "The guild has stood %d days without a loss. Stay sharp!"), hit)
        local UI = GDL:GetModule("UI")
        if UI and UI.ShowMilestoneToast then
            UI:ShowMilestoneToast({
                name = T("Tage ohne Verlust", "Days Without a Loss"),
                desc = msg, icon = ICON_SAFE, category = "success",
            })
        end
        GDL:Print("|cff66DD66" .. msg .. "|r")
    end
end

-- ── Poll: erkennt neuen Tod selbst (kein DNLBridge-Hook noetig) ────────────────
function SafeDays:Poll()
    local ts = self:GetLastDeath()
    if not ts then return end
    if self._lastSeenDeathTs == nil then
        self._lastSeenDeathTs = ts
        self:CheckThreshold()
        return
    end
    if ts > self._lastSeenDeathTs then
        -- Neuer Tod -> die laufende Serie endet
        local endedDays = math.floor((ts - self._lastSeenDeathTs) / DAY)
        self._lastSeenDeathTs = ts
        self:GetRecord()                 -- Rekord ggf. aktualisieren
        if endedDays >= 1 then
            local msg = string.format(
                T("Eine %d-taegige Serie ohne Verlust ist zu Ende.",
                  "A %d-day streak without a loss has ended."), endedDays)
            local UI = GDL:GetModule("UI")
            if UI and UI.ShowMilestoneToast then
                UI:ShowMilestoneToast({
                    name = T("Serie beendet", "Streak Ended"),
                    desc = msg, icon = ICON_END, category = "warning",
                })
            end
            GDL:Print("|cffCC8844" .. msg .. "|r")
        end
        self._announcedThreshold = 0     -- neue Serie beginnt
    else
        self:CheckThreshold()
    end
end

function SafeDays:Initialize()
    if self._initialized then return end
    self._initialized = true
    C_Timer.After(12, function() self:Poll() end)
    C_Timer.NewTicker(120, function() self:Poll() end)   -- alle 2 Min
    if GDL.Debug then GDL:Debug("SafeDays: initialisiert") end
end

GDL:RegisterModule("SafeDays", SafeDays)
