-- =============================================================
-- Specs/PaladinHoly.lua
-- Nem: Healer Alerts — Holy Paladin spec module
--
-- FULLY SELF-CONTAINED. Zero dependencies on other spec modules.
--
-- Alerts:
--   1. Beacon missing        (53563/156910/1244893) — text alert
--   2. Eternal Flame low     (156322) — optional coverage alert
--
-- Glows:
--   • Beacon target glow    (53563/156910/1244893) — icon on frames
--
-- Whitelisted spell IDs (non-secret in Midnight):
--   53563   - Beacon of Light
--   156322  - Eternal Flame
--   156910  - Beacon of Faith
--   1244893 - Beacon of the Savior
-- =============================================================

local NHA = _G.NemHealerAlerts
if not NHA then return end

-- =============================================================
-- TEMPORARILY DISABLED — spec not yet customized or tested.
-- Remove this block when implementation is ready.
-- =============================================================
do return end

local pairs, ipairs       = pairs, ipairs
local GetTime             = GetTime
local UnitExists          = UnitExists
local C_UnitAuras         = C_UnitAuras
local issecretvalue       = NHA.issecretvalue

-- =============================================================
-- Spell IDs
-- =============================================================
local BEACON_OF_LIGHT_ID   = 53563
local BEACON_OF_FAITH_ID   = 156910
local BEACON_OF_SAVIOR_ID  = 1244893
local ETERNAL_FLAME_ID     = 156322

local BEACON_IDS = {
    [53563]   = true,  -- Beacon of Light
    [156910]  = true,  -- Beacon of Faith
    [1244893] = true,  -- Beacon of the Savior
}

-- =============================================================
-- State
-- =============================================================
local state = {
    -- Beacon missing
    beaconActive     = false,
    beaconWasActive  = false,
    -- Eternal Flame low
    efActive         = false,
    efWasActive      = false,
    -- Debounce
    playerAuraPending   = false,
    rosterUpdatePending = false,
}

-- Glow frame tables
local beaconGlowFrames = {}  -- buffFrame → true

-- =============================================================
-- Alert Definitions
-- =============================================================
local BEACON_Y = -30
local EF_Y     = -60

local ALERTS = {
    {
        key          = "beacon",
        label        = "Beacon Missing",
        text         = "* BEACON MISSING *",
        defaultColor = { r = 0.957, g = 0.549, b = 0.729 },  -- Paladin class color
        hasTimer     = false,
        yOffset      = BEACON_Y,
        defaultSound = "Bell",
    },
    {
        key          = "ef",
        label        = "Eternal Flame",
        text         = "* ETERNAL FLAME *",
        defaultColor = { r = 1.000, g = 0.816, b = 0.0 },  -- Gold
        hasTimer     = false,
        yOffset      = EF_Y,
        defaultSound = "Ping",
    },
}

-- =============================================================
-- Defaults
-- =============================================================
local DEFAULTS = {
    beaconEnabled        = true,
    beaconSoundEnabled   = true,
    beaconSoundName      = "Bell",
    efEnabled            = false,  -- off by default (optional)
    efSoundEnabled       = true,
    efSoundName          = "Ping",
    beaconGlowEnabled    = true,
    alertColors          = {
        beacon = { r = 0.957, g = 0.549, b = 0.729 },
        ef     = { r = 1.000, g = 0.816, b = 0.0 },
    },
}

-- =============================================================
-- Beacon Count Scan
-- =============================================================
local function CountActiveBeacons()
    local count = 0
    for _, unit in ipairs(NHA:GetGroupUnits()) do
        if UnitExists(unit) and C_UnitAuras and C_UnitAuras.GetAuraDataBySpellID then
            for spellId in pairs(BEACON_IDS) do
                local aura = C_UnitAuras.GetAuraDataBySpellID(unit, spellId, "HELPFUL")
                if aura and aura.auraInstanceID ~= 0
                   and aura.sourceUnit == "player" then
                    count = count + 1
                end
            end
        end
    end
    return count
end

-- Determine expected beacon count based on which beacon talent is active.
-- Beacon of Faith = expect 2. All others = expect 1.
local function GetExpectedBeaconCount()
    -- Check if any unit has Beacon of Faith specifically
    for _, unit in ipairs(NHA:GetGroupUnits()) do
        if UnitExists(unit) and C_UnitAuras and C_UnitAuras.GetAuraDataBySpellID then
            local aura = C_UnitAuras.GetAuraDataBySpellID(unit, BEACON_OF_FAITH_ID, "HELPFUL")
            if aura and aura.auraInstanceID ~= 0
               and aura.sourceUnit == "player" then
                return 2  -- Beacon of Faith build: expect 2
            end
        end
    end
    return 1  -- All other beacon builds: expect 1
end

-- Check if Eternal Flame exists on beacon targets
local function EternalFlameMissingOnBeaconTarget()
    for _, unit in ipairs(NHA:GetGroupUnits()) do
        if UnitExists(unit) and C_UnitAuras and C_UnitAuras.GetAuraDataBySpellID then
            -- Check if this unit has a beacon
            local hasBeacon = false
            for spellId in pairs(BEACON_IDS) do
                local aura = C_UnitAuras.GetAuraDataBySpellID(unit, spellId, "HELPFUL")
                if aura and aura.auraInstanceID ~= 0
                   and aura.sourceUnit == "player" then
                    hasBeacon = true
                    break
                end
            end
            -- If unit has beacon, check for Eternal Flame
            if hasBeacon then
                local ef = C_UnitAuras.GetAuraDataBySpellID(unit, ETERNAL_FLAME_ID, "HELPFUL")
                if not ef or ef.auraInstanceID == 0
                   or ef.sourceUnit ~= "player" then
                    return true  -- Beacon target missing EF
                end
            end
        end
    end
    return false
end

-- =============================================================
-- Module Table
-- =============================================================
local PaladinHoly = {
    class     = "PALADIN",
    specIndex = 1,  -- Holy is spec index 1
    specID    = 65,  -- fallback: Holy Paladin spec ID for secret-value contexts
    specName  = "Holy",
    alerts    = ALERTS,
    defaults  = DEFAULTS,
    state     = state,

    extraEvents = {
        "UNIT_AURA",
    },
}

-- =============================================================
-- ClearAllGlows
-- =============================================================
function PaladinHoly:ClearAllGlows()
    for buffFrame in pairs(beaconGlowFrames) do
        NHA:HideProcGlow(buffFrame)
    end
    wipe(beaconGlowFrames)
end

-- =============================================================
-- ClearAllState
-- =============================================================
function PaladinHoly:ClearAllState()
    state.beaconActive    = false
    state.beaconWasActive = false
    state.efActive        = false
    state.efWasActive     = false
    self:ClearAllGlows()
end

-- =============================================================
-- NeedsTicker
-- =============================================================
function PaladinHoly:NeedsTicker(db)
    return db.beaconGlowEnabled
end

-- =============================================================
-- RefreshGlows
-- =============================================================
function PaladinHoly:RefreshGlows(db)
    -- Beacon glow is static while buff exists
end

-- =============================================================
-- EvaluateFrameGlow
-- =============================================================
function PaladinHoly:EvaluateFrameGlow(db, buffFrame, aura)
    if not db or not db.glowEnabled or not db.enabled then
        if beaconGlowFrames[buffFrame] then
            NHA:HideProcGlow(buffFrame)
            beaconGlowFrames[buffFrame] = nil
        end
        return
    end

    local tracked = beaconGlowFrames[buffFrame]

    if not aura then
        if tracked then
            NHA:HideProcGlow(buffFrame)
            beaconGlowFrames[buffFrame] = nil
        end
        return
    end

    if issecretvalue(aura.spellId) then
        if tracked then
            NHA:HideProcGlow(buffFrame)
            beaconGlowFrames[buffFrame] = nil
        end
        return
    end

    if aura.sourceUnit ~= "player" then
        if tracked then
            NHA:HideProcGlow(buffFrame)
            beaconGlowFrames[buffFrame] = nil
        end
        return
    end

    -- Beacon glow
    if BEACON_IDS[aura.spellId] and db.beaconGlowEnabled then
        beaconGlowFrames[buffFrame] = true
        local c = db.alertColors and db.alertColors.beacon
                  or { r=0.957, g=0.549, b=0.729 }
        NHA:ShowProcGlow(buffFrame, c.r, c.g, c.b)
        return
    end

    -- Not tracked
    if tracked then
        NHA:HideProcGlow(buffFrame)
        beaconGlowFrames[buffFrame] = nil
    end
end

-- =============================================================
-- Evaluate
-- =============================================================
function PaladinHoly:Evaluate(db)
    -- Beacon missing (combat only)
    local beaconMissing = false
    if db.beaconEnabled and UnitAffectingCombat("player") then
        local count    = CountActiveBeacons()
        local expected = GetExpectedBeaconCount()
        beaconMissing = count < expected
    end
    state.beaconActive = beaconMissing

    -- Eternal Flame low (combat only, optional)
    local efMissing = false
    if db.efEnabled and UnitAffectingCombat("player") then
        efMissing = EternalFlameMissingOnBeaconTarget()
    end
    state.efActive = efMissing

    -- Rising-edge sounds
    if beaconMissing and not state.beaconWasActive then NHA:PlayAlertSound("beacon") end
    if efMissing     and not state.efWasActive      then NHA:PlayAlertSound("ef")     end
    state.beaconWasActive = beaconMissing
    state.efWasActive     = efMissing
end

-- =============================================================
-- OnActivate
-- =============================================================
function PaladinHoly:OnActivate(db)
    -- Nothing spec-specific at login
end

-- =============================================================
-- OnEvent
-- =============================================================
function PaladinHoly:OnEvent(db, event, ...)
    if event == "UNIT_AURA" then
        if not state.playerAuraPending then
            state.playerAuraPending = true
            C_Timer.After(0.1, function()
                state.playerAuraPending = false
                NHA.Evaluate()
            end)
        end
        return true
    end

    if event == "GROUP_ROSTER_UPDATE" then
        if not state.rosterUpdatePending then
            state.rosterUpdatePending = true
            C_Timer.After(0.5, function()
                state.rosterUpdatePending = false
                NHA.Evaluate()
            end)
        end
        return true
    end

    return false
end

-- =============================================================
-- BuildOptions
-- =============================================================
function PaladinHoly:BuildOptions(parent, db, helpers)
    helpers.MakeCheckbox("Beacon Icon Glow", 230, -90,
        function() return db.beaconGlowEnabled end,
        function(v) db.beaconGlowEnabled = v and true or false end)
end

-- =============================================================
-- Register
-- =============================================================
NHA:RegisterSpec("PALADIN_HOLY", PaladinHoly)
