-- Asegurarse de que VoiceOver y QuestOverlayUI están correctamente definidos
VoiceOver = VoiceOver or {}
setfenv(1, VoiceOver)
QuestOverlayUI = QuestOverlayUI or {}

-- Caché para almacenar resultados de verificación de audio
-- Formato: [questID] = { hasSound = true/false }
QuestOverlayUI.audioCache = {}

-- Función para imprimir mensajes de depuración
local function DebugPrint(...)
    if Addon.db and Addon.db.profile.ObjectiveTrackerDebugEnabled then
        local message = table.concat({...}, " ")
        Debug:Print(message, "VoiceOver Debug")
    end
end

-- Función para imprimir logs sobre la caché (siempre visible)
local function CacheLog(...)
    -- Logs deshabilitados
end

-- Función para mostrar información de las misiones activas en el rastreador
function QuestOverlayUI:ShowTrackedQuestsStatus()
    -- Obtener todas las misiones que se están rastreando actualmente
    local questsInTracker = {}
    local questsWithAudio = 0
    local questsNoAudio = 0
    
    local numEntries = C_QuestLog.GetNumQuestLogEntries()
    
    for i = 1, numEntries do
        local questInfo = C_QuestLog.GetInfo(i)
        if questInfo and not questInfo.isHeader and questInfo.questID and C_QuestLog.GetQuestWatchType(questInfo.questID) then
            local questID = questInfo.questID
            local inCache = QuestOverlayUI.audioCache[questID] ~= nil
            local hasAudio = inCache and QuestOverlayUI.audioCache[questID].hasSound
            
            table.insert(questsInTracker, {
                id = questID,
                title = questInfo.title or "Misión sin título",
                inCache = inCache,
                hasAudio = hasAudio
            })
            
            if hasAudio then
                questsWithAudio = questsWithAudio + 1
            elseif inCache then
                questsNoAudio = questsNoAudio + 1
            end
        end
    end
    
    -- Mensaje simplificado
    CacheLog("Misiones en Tracker: " .. #questsInTracker .. " | En caché: " .. (questsWithAudio + questsNoAudio) .. 
           " (" .. questsWithAudio .. " con audio, " .. questsNoAudio .. " sin audio)")
end

-- Función para actualizar la textura del botón dependiendo del estado de la misión
function QuestOverlayUI:UpdatePlayButtonTexture(playButton, hasSound, isComplete)
    if not hasSound then
        playButton.texture:SetTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
        playButton.texture:SetDesaturated(true)
        playButton:SetNormalFontObject("GameFontDisable")
        playButton.texture:SetVertexColor(0.5, 0.5, 0.5) -- Escala de grises para botones deshabilitados
        playButton.borderTexture:SetVertexColor(0, 0, 0) -- Borde en escala de grises
        playButton:Disable()                             -- Deshabilitar el botón
        if playButton.tooltipButton then
            playButton.tooltipButton:Show()
        end
    elseif isComplete then
        playButton.texture:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") -- Icono de check
        playButton.texture:SetDesaturated(false)
        playButton:SetNormalFontObject("GameFontNormal")
        playButton.texture:SetVertexColor(0, 1, 0)       -- Color verde para icono completo
        playButton.borderTexture:SetVertexColor(0, 1, 0) -- Borde verde
        playButton:Enable()                              -- Habilitar el botón porque la misión está completa
        if playButton.tooltipButton then
            playButton.tooltipButton:Hide()
        end
    else
        playButton.texture:SetTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
        playButton.texture:SetDesaturated(false)
        playButton:SetNormalFontObject("GameFontNormal")
        playButton.texture:SetVertexColor(1, 1, 1)       -- Color normal para botones habilitados
        playButton.borderTexture:SetVertexColor(1, 1, 0) -- Borde amarillo
        playButton:Enable()                              -- Habilitar el botón
        if playButton.tooltipButton then
            playButton.tooltipButton:Hide()
        end
    end
end

-- Función para crear el botón de reproducción en la posición indicada
local function CreatePlayButton(parentFrame, questID)
    if not parentFrame then
        DebugPrint("Parent frame not found!")
        return
    end

    DebugPrint("Creando botón para", parentFrame:GetName(), "con questID", questID)

    -- Crear el botón de reproducción
    local playButton = CreateFrame("Button", nil, parentFrame, "UIPanelButtonTemplate")
    playButton:SetSize(20, 20)
    playButton:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", -50, 5)

    -- Agregar una textura de borde (Background layer)
    local borderTexture = playButton:CreateTexture(nil, "BACKGROUND")
    playButton.borderTexture = borderTexture
    borderTexture:SetPoint("TOPLEFT", playButton, "TOPLEFT", -7.5, 7.5)         -- Ajusta estos valores para alejar más el borde
    borderTexture:SetPoint("BOTTOMRIGHT", playButton, "BOTTOMRIGHT", 7.5, -7.5) -- Ajusta estos valores para alejar más el borde
    borderTexture:SetTexture("Interface\\Buttons\\UI-ActionButton-Border")      -- Utilizar una textura de borde predeterminada de Blizzard
    borderTexture:SetVertexColor(1, 1, 0)                                       -- Color amarillo brillante
    borderTexture:SetBlendMode("ADD")

    -- Agregar una textura de fondo (Artwork layer)
    local playButtonTexture = playButton:CreateTexture(nil, "ARTWORK")
    playButton.texture = playButtonTexture
    playButtonTexture:SetAllPoints(playButton)
    playButtonTexture:SetTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
    playButtonTexture:SetVertexColor(1, 1, 1) -- Color blanco normal

    -- Agregar una textura de resaltado (Overlay layer)
    local highlightTexture = playButton:CreateTexture(nil, "OVERLAY")
    highlightTexture:SetBlendMode("ADD")
    highlightTexture:SetAllPoints(playButton)
    highlightTexture:SetTexture("Interface\\Buttons\\CheckButtonHilight") -- Cambia la textura de resaltado para más iluminación

    playButton:SetHighlightTexture(highlightTexture)

    -- Crear el botón invisible para el tooltip cuando está deshabilitado
    local tooltipButton = CreateFrame("Button", nil, playButton)
    tooltipButton:SetAllPoints(playButton)
    tooltipButton:EnableMouse(true)
    tooltipButton:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        GameTooltip:SetText("No Audio Available")
        GameTooltip:AddLine("This quest has no voice over audio", 1, 0, 0)
        GameTooltip:AddLine("QuestID: " .. questID, 1, 1, 1)
        GameTooltip:Show()
    end)
    tooltipButton:SetScript("OnLeave", function(self)
        GameTooltip:Hide()
    end)
    playButton.tooltipButton = tooltipButton
    tooltipButton:Hide()

    playButton:SetScript("OnEnter", function(self)
        if self:IsEnabled() then
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            GameTooltip:SetText("Play Audio")
            GameTooltip:AddLine("QuestID: " .. questID, 1, 1, 1)
            GameTooltip:Show()
        end
    end)

    playButton:SetScript("OnLeave", function(self)
        GameTooltip:Hide()
    end)

    playButton:SetScript("OnClick", function()
        DebugPrint("Botón de reproducción clickeado para", parentFrame:GetName(), "con questID", questID)
        local soundData
        if not playButton.soundData then
            -- Obtenemos el tipo y el ID del NPC que inicia la misión
            local type, id = DataModules:GetQuestLogQuestGiverTypeAndID(questID)
            local npcName = id and DataModules:GetObjectName(type, id) or "Unknown Name"

            soundData = {
                event = Enums.SoundEvent.QuestAccept,
                questID = questID,
                name = npcName, -- Mostrar el nombre del NPC que inicia la misión
                title = C_QuestLog.GetTitleForQuestID(questID),
                unitGUID = id and Enums.GUID:CanHaveID(type) and Utils:MakeGUID(type, id) or nil
            }
            playButton.soundData = soundData
        else
            soundData = playButton.soundData
        end

        local isPlaying = SoundQueue:Contains(soundData)

        if not isPlaying then
            SoundQueue:AddSoundToQueue(soundData)
            QuestOverlayUI:UpdatePlayButtonTexture(playButton, true, false)

            soundData.stopCallback = function()
                QuestOverlayUI:UpdatePlayButtonTexture(playButton, true, false) -- Mantener habilitado después de detener el sonido
                playButton.soundData = nil
            end
        else
            SoundQueue:RemoveSoundFromQueue(soundData)
            QuestOverlayUI:UpdatePlayButtonTexture(playButton, true, false) -- Mantener habilitado después de detener el sonido
        end
    end)

    -- Verificar si hay sonido disponible para la misión y si la misión está completa
    local hasSound = false
    local isComplete = C_QuestLog.IsComplete(questID)
    
    -- Usar la caché si está disponible
    if QuestOverlayUI.audioCache[questID] then
        DebugPrint("Usando datos de caché para questID: " .. questID)
        hasSound = QuestOverlayUI.audioCache[questID].hasSound
    else
        -- Si no está en caché, verificar si hay sonido disponible
    -- Obtenemos el tipo y el ID del NPC que inicia la misión
    local type, id = DataModules:GetQuestLogQuestGiverTypeAndID(questID)
    
    if id and Enums.GUID:CanHaveID(type) then
        -- Crear un soundData con el formato específico que incluye el ID del NPC
        local soundData = {
            event = Enums.SoundEvent.QuestAccept,
            questID = questID,
            unitGUID = Utils:MakeGUID(type, id)
        }
        
        -- Intentar preparar el sonido con el formato específico
        hasSound = DataModules:PrepareSound(soundData)
    else
        -- Si no podemos obtener el ID del NPC, usamos el formato genérico
        hasSound = DataModules:PrepareSound({ event = Enums.SoundEvent.QuestAccept, questID = questID })
    end
    
        -- Guardar en caché para futuras consultas
        QuestOverlayUI.audioCache[questID] = {
            hasSound = hasSound,
            checkedAt = time() -- Para referencia, por si queremos implementar expiración
        }
    end
    
    QuestOverlayUI:UpdatePlayButtonTexture(playButton, hasSound, isComplete)

    playButton:Show()
    parentFrame.playButton = playButton -- Almacenar referencia al botón en el frame padre
    DebugPrint("Botón creado y mostrado para", parentFrame:GetName(), "con questID", questID)
end

-- Función para limpiar los botones existentes
local function CleanQuestButtons(frame)
    if frame.playButton then
        frame.playButton:Hide()
        frame.playButton:SetParent(nil)
        frame.playButton = nil
    end
    for _, child in pairs({ frame:GetChildren() }) do
        CleanQuestButtons(child)
    end
end

-- Función para actualizar los botones en todas las misiones
local function UpdateQuestButtons()
    DebugPrint("Iniciando actualización de botones")

    if not ObjectiveTrackerFrame then
        DebugPrint("ObjectiveTrackerFrame no encontrado")
        return
    end

    -- Verificar si los botones deben mostrarse
    if not Addon.db.profile.ShowObjectiveTrackerButtons then
        CleanQuestButtons(ObjectiveTrackerFrame)
        return
    end

    CleanQuestButtons(ObjectiveTrackerFrame) -- Limpiar los botones existentes antes de actualizar

    local function ProcessFrame(frame)
        if frame.id then
            local questID = tonumber(frame.id)
            if questID then
                CreatePlayButton(frame, questID)
            end
        end
        for _, child in pairs({ frame:GetChildren() }) do
            ProcessFrame(child)
        end
    end

    ProcessFrame(ObjectiveTrackerFrame)
    
    -- Mostrar información de caché después de actualizar los botones
    QuestOverlayUI:ShowTrackedQuestsStatus()
    
    DebugPrint("Actualización de botones completada")
end

-- Frame para manejar eventos
local eventFrame = CreateFrame("Frame")

-- Función para inicializar el addon
local function Init()
    DebugPrint("Inicializando addon")
    CacheLog("Sistema de caché inicializado")

    eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
    eventFrame:RegisterEvent("QUEST_LOG_UPDATE")
    eventFrame:RegisterEvent("QUEST_WATCH_LIST_CHANGED")
    eventFrame:RegisterEvent("QUEST_ACCEPTED")
    eventFrame:RegisterEvent("QUEST_REMOVED")
    eventFrame:RegisterEvent("ADDON_LOADED")

    eventFrame:SetScript("OnEvent", function(self, event, ...)
        DebugPrint("Evento recibido:", event)
        if event == "ADDON_LOADED" and ... == "AI_VoiceOver" then
            C_Timer.After(2, function()
                UpdateQuestButtons()
                -- Asegurar que se muestre la información de caché al cargar el addon
                QuestOverlayUI:ShowTrackedQuestsStatus()
            end)
        elseif event == "PLAYER_ENTERING_WORLD" then
            C_Timer.After(5, function()
                UpdateQuestButtons()
                -- Asegurar que se muestre la información de caché al entrar al mundo
                QuestOverlayUI:ShowTrackedQuestsStatus()
            end)
        else
            C_Timer.After(0.5, UpdateQuestButtons)
        end
    end)

    DebugPrint("Addon de audio para misiones inicializado")
    
    -- Asegurar que se muestre la información de caché inicial
    C_Timer.After(1, QuestOverlayUI.ShowTrackedQuestsStatus)
end

-- Función para actualizar la visibilidad de todos los botones
function QuestOverlayUI:UpdateAllButtonsVisibility()
    if Addon.db.profile.ShowObjectiveTrackerButtons then
        local cacheCount = 0
        for _ in pairs(QuestOverlayUI.audioCache) do
            cacheCount = cacheCount + 1
        end
        
        CacheLog("Misiones en caché: " .. cacheCount)
        UpdateQuestButtons()
    else
        CleanQuestButtons(ObjectiveTrackerFrame)
    end
end

-- Comando para mostrar estadísticas de caché
SLASH_VOICECACHE1 = "/voicecache"
SlashCmdList["VOICECACHE"] = function(msg)
    QuestOverlayUI:ShowTrackedQuestsStatus()
end

-- Inicializar el addon
Init()
