if not select(2, ...).IS_LEGACY_CLIENT then return end -- HET-LEGACY-1207: 12.0.7 only
-------------------------------------------------------------------------------
-- Core.lua
-- AceAddon lifecycle, tracker registry, centralized polling, spec events.
-- Individual trackers register themselves via ns.RegisterTracker().
-- A single C_Timer.NewTicker polls all enabled trackers.
-------------------------------------------------------------------------------
local addonName, ns = ...

local HET = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceEvent-3.0", "AceConsole-3.0")
ns.addon = HET

local pollTicker = nil

-------------------------------------------------------------------------------
-- Build merged defaults from all registered trackers
-------------------------------------------------------------------------------
local function BuildDefaults()
    local profileDefaults = {}
    for i = 1, #ns.trackerOrder do
        local cfg = ns.trackerConfigs[ns.trackerOrder[i]]
        if cfg.defaults then
            for k, v in pairs(cfg.defaults) do
                profileDefaults[cfg.dbPrefix .. k] = v
            end
        end
    end
    return {
        global = {
            minimapIcon    = {},
            optionsPanelW  = 650,
            optionsPanelH  = 450,
        },
        profile = profileDefaults,
    }
end

-------------------------------------------------------------------------------
-- Centralized Polling
-- One ticker, checks all enabled trackers each tick.
-------------------------------------------------------------------------------
-- Recompute the "is this tracker actually doing work right now" flag for
-- every tracker. Combines the user-enabled setting and the spec-applicability
-- predicate so PollAll doesn't have to do GetDBVal (string concat) per tick.
-- Called whenever spec changes or a setting toggles — never per tick.
local function RefreshLiveFlags()
    for i = 1, #ns.trackerOrder do
        local tracker = ns.trackers[ns.trackerOrder[i]]
        if tracker then
            local enabled = tracker:GetDBVal("enabled") and true or false
            local isApplicable = tracker.config.isApplicable
            local applicable = (not isApplicable) or isApplicable(tracker)
            tracker._isLive = enabled and applicable
        end
    end
end
ns.RefreshLiveFlags = RefreshLiveFlags

local function PollAll()
    for i = 1, #ns.trackerOrder do
        local tracker = ns.trackers[ns.trackerOrder[i]]
        if tracker and tracker._isLive and not tracker.previewActive then
            if tracker.timerActive then
                local stillActive = tracker.isActive(tracker)
                if stillActive == false then
                    tracker.falsePollCount = (tracker.falsePollCount or 0) + 1
                    if tracker.falsePollCount >= 2 then
                        tracker:Stop()
                    end
                else
                    tracker.falsePollCount = 0
                end
            else
                if tracker.poll(tracker) then
                    tracker:TriggerTimer()
                end
            end
        end
    end
end

function HET:StartPolling()
    if pollTicker then
        pollTicker:Cancel()
        pollTicker = nil
    end

    -- Recompute every tracker's _isLive based on current settings + spec,
    -- then decide whether to start the ticker at all.
    RefreshLiveFlags()

    local anyLive = false
    for i = 1, #ns.trackerOrder do
        local tracker = ns.trackers[ns.trackerOrder[i]]
        if tracker and tracker._isLive then
            anyLive = true
            break
        end
    end

    if anyLive then
        pollTicker = C_Timer.NewTicker(0.1, PollAll)
    end
end

function HET:StopPolling()
    if pollTicker then
        pollTicker:Cancel()
        pollTicker = nil
    end
end

-------------------------------------------------------------------------------
-- Spec Changed — notify all trackers, restart single poll
-------------------------------------------------------------------------------
local function OnSpecChanged()
    HET:StopPolling()

    for i = 1, #ns.trackerOrder do
        local tracker = ns.trackers[ns.trackerOrder[i]]
        if tracker then
            tracker:Stop()
            if tracker.config.onSpecChanged then
                tracker.config.onSpecChanged(tracker)
            end
            tracker:CacheIcon()
        end
    end

    HET:StartPolling()
end

-------------------------------------------------------------------------------
-- Lifecycle
-------------------------------------------------------------------------------
function HET:OnInitialize()
    local defaults = BuildDefaults()

    -- One-time SavedVariables rename migration (HealerExternalTracker -> BuzzardAuras).
    -- See main Core.lua for rationale; duplicated here for the 12.0.7 client path.
    -- While the old DB is present it is the source of truth: adopt it wholesale
    -- and discard whatever is in the new global (heals a prior failed migration
    -- that left a defaults-only BuzzardAurasDB). Nil the old global so this fires
    -- exactly once.
    local old = _G.HealerExternalTrackerDB
    if old and next(old) ~= nil then
        _G.BuzzardAurasDB = old
        _G.HealerExternalTrackerDB = nil
    end

    self.db = LibStub("AceDB-3.0"):New("BuzzardAurasDB", defaults, true)

    -- Instantiate all registered trackers
    for i = 1, #ns.trackerOrder do
        local key = ns.trackerOrder[i]
        ns.trackers[key] = ns.Tracker.Create(ns.trackerConfigs[key], self)
    end

    -- Cache ns.cachedIconTexture for UI.lua minimap button
    local spatialTracker = ns.trackers["spatial"]
    if spatialTracker then
        ns.cachedIconTexture = spatialTracker.cachedIcon
    end

    self:RegisterOptions()
    self:SetupUI()
end

-- One-time rename notice (HET -> Buzzard Auras). Shown once ever per account,
-- gated by db.global.renameNoticeShown (shared with the 12.1 path — the flag is
-- account-wide, so the notice shows once regardless of which client sees it
-- first). Duplicated from Core.lua for the 12.0.7 path.
local function ShowRenameNoticeOnce(self)
    if not (self.db and self.db.global) then return end
    if self.db.global.renameNoticeShown then return end
    self.db.global.renameNoticeShown = true
    if not StaticPopupDialogs["BUZZARDAURAS_RENAME_NOTICE"] then
        StaticPopupDialogs["BUZZARDAURAS_RENAME_NOTICE"] = {
            text = "|cff11ace9Healer External Tracker|r is now |cff11ace9Buzzard Auras|r.\n\n"
                .. "The old HET Innervate and Spatial tracking functionality is still "
                .. "available in Buzzard Auras on 12.0.7, but the addon has been fully "
                .. "rebuilt for 12.1 to allow any buff on yourself to be tracked by spell ID.",
            button1 = OKAY,
            timeout = 0,
            whileDead = 1,
            hideOnEscape = 1,
            preferredIndex = 3,
        }
    end
    StaticPopup_Show("BUZZARDAURAS_RENAME_NOTICE")
end

function HET:OnEnable()
    self:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED", OnSpecChanged)
    self:RegisterEvent("PLAYER_LOGIN", OnSpecChanged)

    if IsLoggedIn() then
        OnSpecChanged()
    end

    ShowRenameNoticeOnce(self)
end

-- Public hook for Options.lua to re-run the full spec-init pipeline
-- (re-evaluates trackedSpellID / innCheckSpells, then restarts polling
-- with a fresh isApplicable check). Used when a setting changes that
-- affects which specs the trackers apply to.
function HET:RefreshSpec()
    OnSpecChanged()
end

function HET:OnDisable()
    self:StopPolling()
    for i = 1, #ns.trackerOrder do
        local tracker = ns.trackers[ns.trackerOrder[i]]
        if tracker then
            tracker:Stop()
        end
    end
end

-------------------------------------------------------------------------------
-- Preview helpers (called from Options.lua)
-- ShowPreview stops polling, HidePreview restarts it.
-------------------------------------------------------------------------------
function HET:ShowPreview()
    local t = ns.trackers["spatial"]
    if t then
        self:StopPolling()
        t:ShowPreview()
    end
end
function HET:HidePreview()
    local t = ns.trackers["spatial"]
    if t then
        t:HidePreview()
        if t.config.onSpecChanged then t.config.onSpecChanged(t) end
        t:CacheIcon()
        self:StartPolling()
    end
end
function HET:IsPreviewActive()
    local t = ns.trackers["spatial"]
    return t and t:IsPreviewActive() or false
end
function HET:RefreshPreview()
    local t = ns.trackers["spatial"]
    if t then t:RefreshPreview() end
end

function HET:ShowInnPreview()
    local t = ns.trackers["innervate"]
    if t then
        self:StopPolling()
        t:ShowPreview()
    end
end
function HET:HideInnPreview()
    local t = ns.trackers["innervate"]
    if t then
        t:HidePreview()
        if t.config.onSpecChanged then t.config.onSpecChanged(t) end
        t:CacheIcon()
        self:StartPolling()
    end
end
function HET:IsInnPreviewActive()
    local t = ns.trackers["innervate"]
    return t and t:IsPreviewActive() or false
end
function HET:RefreshInnPreview()
    local t = ns.trackers["innervate"]
    if t then t:RefreshPreview() end
end
