--[[
    KickIcon.lua - TGXG Interrupt
    -----------------------------------------------------------------------
    Own-interrupt cooldown display: a single spell icon (size configurable,
    default 64x64) that is freely movable while the tracker is unlocked.

      READY      → full-color icon + pulsing green glow border
      ON COOLDOWN→ desaturated/darkened icon + cooldown swipe + remaining
                   seconds centered on the icon ("7", below 10s "7,3")

    Data source: C_Spell.GetSpellCooldown for the OWN spell — clean in
    12.x, no secret handling needed. Pet interrupts (Warlock) fall back
    to the addon-tracked cdEnd from TGX.Self when the API yields nothing.
    The GCD (≤2s durations) never counts as "on cooldown".
    -----------------------------------------------------------------------
]]

TGX = TGX or {}
TGX.KickIcon = TGX.KickIcon or {}
local KI = TGX.KickIcon

local BAR_TEXTURE = "Interface\\BUTTONS\\WHITE8X8"
local _f
local _lastCdStart, _lastCdDur = 0, 0

local function db() return TGX.db end

------------------------------------------------------------
-- Cooldown read for the own kick. Returns start, duration, remaining
-- (all clean numbers) or nil when ready. GCD filtered via duration > 2.
------------------------------------------------------------
local function ReadOwnKickCD()
    local spellID = TGX.Self.spellID
    if not spellID then return nil end
    local now = GetTime()

    local ok, info = pcall(C_Spell.GetSpellCooldown, spellID)
    if ok and info then
        local ok2, start, dur = pcall(function()
            return info.startTime, info.duration
        end)
        if ok2 and type(start) == "number" and type(dur) == "number"
           and TGX.Taint.IsClean(start) and TGX.Taint.IsClean(dur)
           and dur > 2 then
            local remaining = (start + dur) - now
            if remaining > 0 then return start, dur, remaining end
        end
    end

    -- Fallback: addon-tracked cooldown (pet kicks / API edge cases)
    local cdEnd = TGX.Self.cdEnd or 0
    if cdEnd > now then
        local base = TGX.Self.baseCd
            or (TGX.ALL_INTERRUPTS[spellID] and TGX.ALL_INTERRUPTS[spellID].cd) or 15
        return cdEnd - base, base, cdEnd - now
    end
    return nil
end

------------------------------------------------------------
-- Frame
------------------------------------------------------------
function KI:Create()
    if _f then return end
    local d = db()

    _f = CreateFrame("Frame", "TGXGKickIcon", UIParent, "BackdropTemplate")
    _f:SetSize(d.kickIconSize, d.kickIconSize)
    _f:SetPoint("CENTER", UIParent, "CENTER", d.kickIconPosX, d.kickIconPosY)
    _f:SetClampedToScreen(true)
    _f:SetMovable(true)

    -- Green "ready" glow border
    _f:SetBackdrop({ edgeFile = BAR_TEXTURE, edgeSize = 2 })
    _f:SetBackdropBorderColor(0, 0, 0, 0)

    _f.icon = _f:CreateTexture(nil, "ARTWORK")
    _f.icon:SetPoint("TOPLEFT", 1, -1)
    _f.icon:SetPoint("BOTTOMRIGHT", -1, 1)
    _f.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)

    -- Dark overlay while on cooldown (on top of desaturation)
    _f.dim = _f:CreateTexture(nil, "OVERLAY", nil, 1)
    _f.dim:SetPoint("TOPLEFT", 1, -1)
    _f.dim:SetPoint("BOTTOMRIGHT", -1, 1)
    _f.dim:SetColorTexture(0, 0, 0, 0.45)
    _f.dim:Hide()

    -- Cooldown swipe (no Blizzard numbers — we draw our own text)
    _f.cd = CreateFrame("Cooldown", nil, _f, "CooldownFrameTemplate")
    _f.cd:SetPoint("TOPLEFT", 1, -1)
    _f.cd:SetPoint("BOTTOMRIGHT", -1, 1)
    _f.cd:SetHideCountdownNumbers(true)
    _f.cd:SetDrawEdge(false)

    -- Remaining-seconds text, centered (own frame so it sits above the swipe)
    _f.textFrame = CreateFrame("Frame", nil, _f)
    _f.textFrame:SetAllPoints()
    _f.textFrame:SetFrameLevel(_f.cd:GetFrameLevel() + 2)
    _f.timer = _f.textFrame:CreateFontString(nil, "OVERLAY")
    _f.timer:SetPoint("CENTER", 0, 0)
    _f.timer:SetTextColor(1, 0.85, 0.1)

    _f.dragTex = _f:CreateTexture(nil, "OVERLAY", nil, 7)
    _f.dragTex:SetAllPoints()
    _f.dragTex:SetColorTexture(0.2, 1.0, 0.6, 0.25)
    _f.dragTex:Hide()

    _f:SetScript("OnMouseDown", function(f, button)
        if button == "LeftButton" and not db().kickIconLocked then f:StartMoving() end
    end)
    _f:SetScript("OnMouseUp", function(f)
        f:StopMovingOrSizing()
        local cx, cy = f:GetCenter()
        local ux, uy = UIParent:GetCenter()
        db().kickIconPosX, db().kickIconPosY = cx - ux, cy - uy
        f:ClearAllPoints()
        f:SetPoint("CENTER", UIParent, "CENTER", db().kickIconPosX, db().kickIconPosY)
    end)

    local acc = 0
    _f:SetScript("OnUpdate", function(_, elapsed)
        acc = acc + elapsed
        if acc >= 0.1 then
            acc = 0
            KI:Tick()
        end
    end)

    self:ApplySettings()
end

------------------------------------------------------------
-- Per-tick state update
------------------------------------------------------------
function KI:Tick()
    if not _f or not _f:IsShown() then return end
    local now = GetTime()
    local spellID = TGX.Self.spellID

    -- Icon texture (spec/registry driven; refreshes on spec change).
    -- Sentinel 0 = "no interrupt" so the placeholder is set exactly once.
    local sid = spellID or 0
    if sid ~= _f.shownSpell then
        _f.shownSpell = sid
        local tex = spellID and TGX.ALL_INTERRUPTS[spellID] and TGX.ALL_INTERRUPTS[spellID].icon
        if not tex and spellID then
            local ok, t = pcall(C_Spell.GetSpellTexture, spellID)
            if ok then tex = t end
        end
        _f.icon:SetTexture(tex or 134400)
    end

    local start, dur, remaining
    if spellID then
        start, dur, remaining = ReadOwnKickCD()
    end

    if remaining and remaining > 0 then
        -- ON COOLDOWN: gray + swipe + countdown
        _f.icon:SetDesaturated(true)
        _f.dim:Show()
        if start ~= _lastCdStart or dur ~= _lastCdDur then
            _lastCdStart, _lastCdDur = start, dur
            pcall(_f.cd.SetCooldown, _f.cd, start, dur)
        end
        local txt
        if remaining >= 10 then
            txt = tostring(math.ceil(remaining))
        else
            txt = string.format("%.1f", remaining)
            if TGX.isDE then txt = txt:gsub("%.", ",") end
        end
        _f.timer:SetText(txt)
        _f:SetBackdropBorderColor(0, 0, 0, 0)
    else
        -- READY: full color + pulsing green glow
        _f.icon:SetDesaturated(false)
        _f.dim:Hide()
        if _lastCdStart ~= 0 then
            _lastCdStart, _lastCdDur = 0, 0
            pcall(_f.cd.Clear, _f.cd)
        end
        _f.timer:SetText("")
        local a = 0.55 + 0.45 * math.sin(now * 5)
        _f:SetBackdropBorderColor(0.2, 1.0, 0.4, a)
    end
end

------------------------------------------------------------
-- Settings / lock / visibility
------------------------------------------------------------
function KI:ApplySettings()
    if not _f then return end
    local d = db()
    _f:SetSize(d.kickIconSize, d.kickIconSize)
    _f.timer:SetFont(STANDARD_TEXT_FONT, math.max(10, math.floor(d.kickIconSize * 0.32)), "OUTLINE")
    self:UpdateVisibility()
    self:ApplyLock()
end

function KI:ApplyLock()
    if not _f then return end
    local unlocked = not db().kickIconLocked
    _f:EnableMouse(unlocked and db().kickIconEnabled ~= false)
    _f.dragTex:SetShown(unlocked and db().kickIconEnabled ~= false)
end

function KI:UpdateVisibility()
    if not _f then return end
    if db().kickIconEnabled == false then _f:Hide() return end
    -- While UNLOCKED the icon always shows (placement preview) — the
    -- gates below only apply to the locked, day-to-day state.
    if db().kickIconLocked then
        -- No interrupt on this spec (e.g. Holy Priest)
        if not TGX.Self.spellID then _f:Hide() return end
        -- "Nur im Kampf anzeigen"
        if db().kickIconCombatOnly and not UnitAffectingCombat("player") then
            _f:Hide()
            return
        end
    end
    _f:Show()
    self:Tick()
end

-- Combat visibility events (only relevant for the combat-only mode)
local _combatFrame = CreateFrame("Frame")
_combatFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
_combatFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
_combatFrame:SetScript("OnEvent", function()
    KI:UpdateVisibility()
end)
