if not select(2, ...).IS_LEGACY_CLIENT then return end -- HET-LEGACY-1207: 12.0.7 only
-------------------------------------------------------------------------------
-- Innervate.lua
-- Detects Innervate via mana cost polling (C_Spell.GetSpellPowerCost).
-- Uses the same spells tracked by Spatial Paradox (with a 2nd spell for
-- Holy Priest and Preservation Evoker). When all checked spells cost 0 mana
-- for 2 consecutive polls, Innervate is detected. The double-confirm
-- suppresses false positives on instance entry / zone transitions where
-- the cost API briefly reports 0 before settling.
-------------------------------------------------------------------------------
local addonName, ns = ...

local INNERVATE_ID = 29166
-- Nominal buff duration is 8s, but the poll-based detection has a small
-- activation delay (one or two ticks before AllZero confirms). 7.8s gives
-- a more accurate visual countdown that lines up with when the buff
-- actually ends.
local INNERVATE_DURATION = 7.8

local C_Spell_GetSpellPowerCost = C_Spell.GetSpellPowerCost
local GetSpecialization = GetSpecialization
local GetSpecializationInfo = GetSpecializationInfo

-- Per-instance state
local innCheckSpells = nil  -- list of spellIDs to check mana cost
local innZeroCount = 0
local ZERO_CONFIRM = 2
local lastTriggerTime = 0
-- Grace period must cover the buff duration plus a small margin. After the
-- icon timer ends, the buff aura may linger for a tick or two and report
-- 0 cost, which would otherwise re-fire the TTS. 9s = 8s buff + 1s slack.
local GRACE_PERIOD = 9

-- Inlined to avoid per-tick helper-call overhead and ipairs iterator state.
-- C_Spell.GetSpellPowerCost always returns its primary entry at index [1];
-- the previous ipairs walk was a defensive pattern that wasn't needed.
local function AllZero()
    if not innCheckSpells then return false end
    for i = 1, #innCheckSpells do
        local costs = C_Spell_GetSpellPowerCost(innCheckSpells[i])
        local first = costs and costs[1]
        if not first or first.cost ~= 0 then
            return false
        end
    end
    return true
end

ns.RegisterTracker("innervate", {
    dbPrefix         = "inn_",
    displaySpell     = INNERVATE_ID,
    frameSuffix      = "Innervate",
    label            = "Innervate Tracker",
    defaultPos       = { "CENTER", "CENTER", 0, 0 },

    ttsPhrase = "Innervate",

    defaults = {
        enabled        = true,
        iconSize       = 40,
        trackerStyle   = "icon",
        cooldownSwipe  = true,
        barCircleColor = { 0.2, 0.5, 1.0, 1.0 },
        barOrientation = "horizontal",
        barWidth       = 200,
        barHeight      = 20,
        circleRadius   = 80,
        ringTexture    = "Ring_20px",
        position       = nil,
        alertMode      = "none",
        soundName      = "None",
        soundChannel   = "Master",
        ttsVoice       = 0,
        ttsVolume      = 100,
    },

    hasConfigurableDuration = false,

    getTimerDuration = function(tracker)
        return INNERVATE_DURATION
    end,

    onSpecChanged = function(tracker)
        innCheckSpells = nil
        innZeroCount = 0

        local specIndex = GetSpecialization()
        if not specIndex then return end

        local specID = GetSpecializationInfo(specIndex)
        if specID and ns.INNERVATE_CHECK_SPELLS and ns.INNERVATE_CHECK_SPELLS[specID] then
            innCheckSpells = ns.INNERVATE_CHECK_SPELLS[specID]
        end
    end,

    onStop = function(tracker)
        innZeroCount = 0
    end,

    -- True when the current spec has Innervate check spells mapped.
    -- Used by Core to skip the poll ticker entirely on non-healer alts.
    isApplicable = function(tracker)
        return innCheckSpells ~= nil
    end,

    isActive = function(tracker)
        return AllZero()
    end,

    poll = function(tracker)
        if not innCheckSpells then return false end
        local now = GetTime()
        if now - lastTriggerTime < GRACE_PERIOD then return false end
        if AllZero() then
            innZeroCount = innZeroCount + 1
            if innZeroCount >= ZERO_CONFIRM then
                innZeroCount = 0
                lastTriggerTime = now
                return true
            end
        else
            innZeroCount = 0
        end
        return false
    end,
})

ns.INNERVATE_ID = INNERVATE_ID
ns.INNERVATE_DURATION = INNERVATE_DURATION
