local addonName, Addon = ...

local eventFrame = CreateFrame("Frame")
local mapRefreshGeneration = 0

local mapChangeEvents = {
    PLAYER_ENTERING_WORLD = true,
    PLAYER_MAP_CHANGED = true,
    NEW_WMO_CHUNK = true,
    ZONE_CHANGED = true,
    ZONE_CHANGED_INDOORS = true,
    ZONE_CHANGED_NEW_AREA = true,
}

local contentEvents = {
    QUEST_LOG_UPDATE = true,
    QUEST_POI_UPDATE = true,
    QUESTLINE_UPDATE = true,
    QUEST_ACCEPTED = true,
    QUEST_REMOVED = true,
    QUEST_WATCH_LIST_CHANGED = true,
    TASK_PROGRESS_UPDATE = true,
    AREA_POIS_UPDATED = true,
    VIGNETTES_UPDATED = true,
    TAXI_NODE_STATUS_CHANGED = true,
    RESEARCH_ARTIFACT_DIG_SITE_UPDATED = true,
    ARCHAEOLOGY_TOGGLE = true,
    BOSS_KILL = true,
    ENCOUNTER_END = true,
    PORTRAITS_UPDATED = true,
}

local focusResetEvents = {
    PLAYER_ENTERING_WORLD = true,
    PLAYER_MAP_CHANGED = true,
    ZONE_CHANGED_NEW_AREA = true,
}

local function ScheduleMapRefresh(resetFocus)
    mapRefreshGeneration = mapRefreshGeneration + 1
    local generation = mapRefreshGeneration

    if resetFocus then
        Addon.MapView:PrepareForMapChange()
    end

    -- Al entrar en una instancia, el mapa y su piso no siempre están listos
    -- en el primer evento. Reintentamos durante unos segundos y descartamos
    -- los temporizadores antiguos si llega un cambio de zona más reciente.
    for _, delay in ipairs({ 0.05, 0.35, 0.90, 1.80, 3.00 }) do
        C_Timer.After(delay, function()
            if generation ~= mapRefreshGeneration or not Addon.UI:IsMapShown() then
                return
            end
            Addon.MapView:Rebuild(false)
        end)
    end
end

local function RegisterRuntimeEvents(frame)
    for event in pairs(mapChangeEvents) do
        frame:RegisterEvent(event)
    end
    for event in pairs(contentEvents) do
        frame:RegisterEvent(event)
    end
    frame:RegisterEvent("GROUP_ROSTER_UPDATE")
    frame:RegisterEvent("MAP_EXPLORATION_UPDATED")
end

local function Initialize(frame)
    Addon:InitializeDatabase()
    Addon.UI:Initialize()
    Addon.Commands:Register()
    RegisterRuntimeEvents(frame)
    frame:UnregisterEvent("ADDON_LOADED")

    C_Timer.After(0.50, function()
        if Addon.db.replaceMinimap then
            Addon.UI:SetReplacementMode(true, false)
        end
    end)

    if not Addon.db.welcomeShown then
        Addon.db.welcomeShown = true
        Addon:Print("instalado. Escribe /mzm help para ver los comandos.")
    end
end

eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:SetScript("OnEvent", function(self, event, loadedAddon)
    if event == "ADDON_LOADED" then
        if loadedAddon == addonName then
            Initialize(self)
        end
        return
    end

    if mapChangeEvents[event] then
        Addon.Coordinates:ClearCache()
        if Addon.UI:IsMapShown() then
            ScheduleMapRefresh(focusResetEvents[event])
        end
    elseif event == "GROUP_ROSTER_UPDATE" and Addon.UI:IsMapShown() then
        Addon.Markers:UpdateMarkers()
    elseif event == "MAP_EXPLORATION_UPDATED" and Addon.UI:IsMapShown() then
        Addon.MapView:BuildExplorationOverlays()
        Addon.MapView:UpdateGeometry()
    elseif contentEvents[event] and Addon.UI:IsMapShown() then
        Addon.Markers:ScheduleContentRefresh()
    end
end)
