setfenv(1, VoiceOver)
if BonusQuestDetector and BonusQuestDetector.DebugMode then
    DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00BonusZoneDetector module loaded successfully.|r")
end

local bonusZoneCache = {}           -- Cache para almacenar misiones que ya han reproducido sonido
local currentBonusZoneQuestID = nil -- Variable para rastrear la ID de la misión de la zona de bonificación actual

BonusQuestDetector = BonusQuestDetector or {}
BonusQuestDetector.DebugMode = BonusQuestDetector.DebugMode or false

-- Función de depuración
local function BonusQuestDebugPrint(...)
    if BonusQuestDetector.DebugMode then
        local message = table.concat({ ... }, " ")
        DEFAULT_CHAT_FRAME:AddMessage("|cFF00FF00[BonusQuestDetector Debug]|r " .. message)
    end
end

-- Obtener la duración del sonido a partir de los datos
local function GetSoundDuration(questID, eventType)
    local soundData = {
        event = eventType, -- Usar el evento correspondiente
        questID = questID,
    }
    local success = DataModules:PrepareSound(soundData)
    if success then
        return soundData.length
    else
        return 5 -- Duración predeterminada si no se encuentra la longitud
    end
end

-- Mostrar el marco del NPC al aceptar una misión
local function ShowAcceptNPCFrame(questID, questTitle)
    local npcName = "|cffff8c00Objetivo de Bonificación|r" -- Nombre estático del NPC en azul cian

    local duration = GetSoundDuration(questID, Enums.SoundEvent.QuestAccept)

    local soundData = {
        event = Enums.SoundEvent.QuestAccept, -- Evento de aceptación
        questID = questID,
        name = npcName,                       -- Nombre estático del NPC
        title = questTitle,
        text = "",                            -- No se necesita texto de objetivos
        unitGUID = nil,                       -- No se necesita GUID específico
        unitIsObjectOrItem = true,            -- Suponiendo que es un objeto
        addedCallback = QuestSoundDataAdded,
        length = duration
    }

    -- Verificar que SoundQueueUI.frame no sea nil antes de usarlo
    if SoundQueueUI and SoundQueueUI.frame then
        SoundQueueUI.frame.portrait:Configure(soundData)
        SoundQueueUI.frame.container.name:SetText(npcName .. " - " .. questTitle)
        SoundQueueUI.frame.container.name:Show()
        SoundQueueUI.frame.container:Show()

        -- Agregar el sonido a la cola después de mostrar
        local showDuration = 2
        C_Timer.After(showDuration, function()
            SoundQueue:AddSoundToQueue(soundData)
        end)
    else
        BonusQuestDebugPrint("Error: SoundQueueUI.frame no está inicializado.")
    end
end

-- Mostrar el marco del NPC al completar una misión
local function ShowCompleteNPCFrame(questID, questTitle)
    local npcName = "Objetivo Completo" -- Nombre estático del NPC para completar

    local completeDuration = GetSoundDuration(questID, Enums.SoundEvent.QuestComplete)

    local soundData = {
        event = Enums.SoundEvent.QuestComplete, -- Evento de completar
        questID = questID,
        name = npcName,
        title = questTitle,
        text = "", -- No se necesita texto de objetivos
        unitGUID = nil,
        unitIsObjectOrItem = true,
        addedCallback = QuestSoundDataAdded,
        length = completeDuration
    }

    -- Verificar que SoundQueueUI.frame no sea nil antes de usarlo
    if SoundQueueUI and SoundQueueUI.frame then
        SoundQueueUI.frame.portrait:Configure(soundData)
        SoundQueueUI.frame.container.name:SetText(npcName .. " - " .. questTitle)
        SoundQueueUI.frame.container.name:Show()
        SoundQueueUI.frame.container:Show()

        -- Agregar el sonido a la cola después de mostrar
        local showDuration = 2
        C_Timer.After(showDuration, function()
            SoundQueue:AddSoundToQueue(soundData)
        end)
    else
        BonusQuestDebugPrint("Error: SoundQueueUI.frame no está inicializado.")
    end
end

-- Manejar la entrada a una zona de bonificación
local function OnBonusZoneEnter(questID)
    -- Verificar si el sonido ya ha sido reproducido
    if bonusZoneCache[questID] then
        BonusQuestDebugPrint("El archivo de esta zona ya fue reproducido.")
        return
    end

    local questTitle = C_QuestLog.GetTitleForQuestID(questID) or "Unknown Quest"
    local soundPath = string.format(
    "Interface\\AddOns\\AI_VoiceOverData_WarWithin\\generated\\sounds\\quests\\%d-accept.mp3", questID)

    BonusQuestDebugPrint("Entering Bonus Zone:", questTitle, "(QuestID:", questID, ")")

    -- Intentar cargar y reproducir el sonido de aceptación
    if soundPath then
        PlaySoundFile(soundPath)
        BonusQuestDebugPrint("Reproduciendo misión:", questTitle)

        -- Mostrar el marco de aceptación del NPC
        ShowAcceptNPCFrame(questID, questTitle)

        -- Marcar la misión como manejada
        bonusZoneCache[questID] = true
        currentBonusZoneQuestID = questID
    else
        BonusQuestDebugPrint("Sound file not found for quest:", questTitle)
    end
end

-- Manejar la finalización de una misión, independientemente del cache
local function OnBonusQuestComplete(questID)
    local questTitle = C_QuestLog.GetTitleForQuestID(questID) or "Unknown Quest"
    local completeSoundPath = string.format(
    "Interface\\AddOns\\AI_VoiceOverData_WarWithin\\generated\\sounds\\quests\\%d-complete.mp3", questID)

    BonusQuestDebugPrint("Completing Bonus Quest:", questTitle, "(QuestID:", questID, ")")

    -- Intentar cargar y reproducir el sonido de finalización
    if completeSoundPath then
        PlaySoundFile(completeSoundPath)
        BonusQuestDebugPrint("Misión completada:", questTitle)

        -- Mostrar el marco de finalización del NPC
        ShowCompleteNPCFrame(questID, questTitle)
    else
        BonusQuestDebugPrint("Completion sound file not found for quest:", questTitle)
    end
end

-- Manejar la salida de una zona de bonificación
local function OnBonusZoneLeave()
    if currentBonusZoneQuestID then
        BonusQuestDebugPrint("Leaving Bonus Zone:", currentBonusZoneQuestID)
        BonusQuestDebugPrint("Saliendo de la zona de bonificación:", currentBonusZoneQuestID)
        -- Restablecer el cache para permitir la reproducción si se vuelve a entrar en la zona
        bonusZoneCache[currentBonusZoneQuestID] = nil
        currentBonusZoneQuestID = nil
    end
end

-- Función para comprobar zonas de bonificación
local function CheckForBonusZones()
    if not Addon.db.profile.BonusQuestDetectorEnabled then
        return
    end

    -- Comprobar si el jugador es nivel 80
    if UnitLevel("player") == 80 then
        BonusQuestDebugPrint("El jugador es nivel 80. El detector de misiones de bonificación no se ejecutará.")
        return
    end

    local numEntries = C_QuestLog.GetNumQuestLogEntries()
    local foundBonusQuest = false

    BonusQuestDebugPrint("Checking for bonus quests...")

    for i = 1, numEntries do
        local questInfo = C_QuestLog.GetInfo(i)
        if questInfo and not questInfo.isHeader and questInfo.isTask then
            local questID = questInfo.questID

            -- Si se encuentra una misión de bonificación, manejar la entrada
            foundBonusQuest = true
            if questID ~= currentBonusZoneQuestID then
                OnBonusZoneEnter(questID)
            elseif bonusZoneCache[questID] then
                -- Imprimir mensaje cian si el audio ya fue reproducido
                -- BonusQuestDebugPrint("El archivo de esta zona ya fue reproducido.")
            end

            -- Verificar si la misión está completa y manejarlo
            if C_QuestLog.IsComplete(questID) then
                OnBonusQuestComplete(questID)
            end
        end
    end

    -- Si no se encuentra ninguna misión de bonificación actual, manejar la salida
    if not foundBonusQuest and currentBonusZoneQuestID then
        OnBonusZoneLeave()
    end

    BonusQuestDebugPrint("Finished checking for bonus quests.")
end

-- Frame y eventos
local frame = CreateFrame("Frame")
frame:RegisterEvent("QUEST_LOG_UPDATE")
frame:RegisterEvent("ZONE_CHANGED_NEW_AREA") -- Detectar cuando se entra en nuevas zonas
frame:RegisterEvent("PLAYER_ENTERING_WORLD") -- Detectar cuando el jugador entra al mundo
frame:SetScript("OnEvent", function(self, event, ...)
    if not Addon.db.profile.BonusQuestDetectorEnabled then
        return
    end

    if event == "PLAYER_ENTERING_WORLD" then
        -- Esperar 2 segundos para asegurarse de que todo esté cargado
        C_Timer.After(2, CheckForBonusZones)
    else
        CheckForBonusZones()
    end
end)

-- Inicializar comprobando las zonas de bonificación con un retraso
C_Timer.After(2, function()
    if Addon.db.profile.BonusQuestDetectorEnabled then
        CheckForBonusZones()
    end
end)
