-- Nombre del archivo: QuestFrameAudioButton.lua

-- Asegurarse de que VoiceOver esté correctamente definido
VoiceOver = VoiceOver or {}
setfenv(1, VoiceOver)
QuestFrameAudioButton = QuestFrameAudioButton or {}

-- Importar el módulo de depuración principal
local Debug = VoiceOver.Debug

-- Función para imprimir mensajes de depuración
local function DebugPrint(message)
    Debug:Print(message, "QuestFrameAudioButton")
end

-- Función para obtener el questID actual
local function GetCurrentQuestID()
    return QuestFrame.questID or GetQuestID()
end

-- Función para determinar el evento actual
local function GetCurrentEvent()
    if QuestFrameDetailPanel:IsShown() then
        return Enums.SoundEvent.QuestAccept
    elseif QuestFrameProgressPanel:IsShown() then
        return Enums.SoundEvent.QuestProgress
    elseif QuestFrameRewardPanel:IsShown() then
        return Enums.SoundEvent.QuestComplete
    end
    return nil
end

-- Función para obtener el nombre del evento actual
local function GetEventName(event)
    if event == Enums.SoundEvent.QuestAccept then
        return "Accept"
    elseif event == Enums.SoundEvent.QuestProgress then
        return "Progress"
    elseif event == Enums.SoundEvent.QuestComplete then
        return "Complete"
    end
    return "Unknown"
end

-- Función para obtener el NPCID actual
local function GetCurrentNPCID()
    -- Intenta obtener el GUID de la unidad objetivo actual
    local targetGUID = UnitGUID("npc") or UnitGUID("target")
    
    if targetGUID then
        local type, _, _, _, _, npcID = strsplit("-", targetGUID)
        if type == "Creature" or type == "Vehicle" then
            DebugPrint("NPCID actual obtenido directamente: " .. npcID)
            return tonumber(npcID)
        end
    end
    
    -- Si no podemos obtener el NPCID directamente, intentamos con el questID
    local questID = GetCurrentQuestID()
    if questID then
        local type, id = DataModules:GetQuestLogQuestGiverTypeAndID(questID)
        if type and id and Enums.GUID:IsCreature(type) then
            DebugPrint("NPCID obtenido desde questID: " .. id)
            return id
        end
    end
    
    DebugPrint("No se pudo obtener NPCID")
    return nil
end

-- Función para verificar si existe un archivo de audio específico
local function CheckSpecificAudioFile(questID, eventName, npcID)
    local specificFileName = format("%d-%s-%d", questID, string.lower(eventName), npcID)
    DebugPrint("Verificando archivo específico: " .. specificFileName)
    
    for _, module in DataModules:GetModules() do
        local data = module.SoundLengthLookupByFileName
        if data and data[specificFileName] then
            DebugPrint("¡Archivo específico encontrado!: " .. specificFileName)
            return true, specificFileName
        end
    end
    
    -- Verificar formato genérico
    local genericFileName = format("%d-%s", questID, string.lower(eventName))
    DebugPrint("Verificando archivo genérico: " .. genericFileName)
    
    for _, module in DataModules:GetModules() do
        local data = module.SoundLengthLookupByFileName
        if data and data[genericFileName] then
            DebugPrint("¡Archivo genérico encontrado!: " .. genericFileName)
            return true, genericFileName
        end
    end
    
    return false, nil
end

-- Función para detener cualquier reproducción de audio y restablecer el botón
local function StopAudioAndResetButton(playButton)
    if playButton and playButton.soundData and playButton.isPlaying then
        DebugPrint("Deteniendo reproducción de audio al cambiar de evento")
        SoundQueue:RemoveSoundFromQueue(playButton.soundData)
        playButton.isPlaying = false
        
        -- Restablecer el texto del botón
        if playButton.text then
            playButton.text:SetText("Play")
        end
    end
end

-- Función para crear el botón de reproducción
local function CreatePlayButton()
    if not QuestFrame then
        DebugPrint("QuestFrame not found!")
        return
    end

    -- Crear un frame personalizado
    local playButton = CreateFrame("Button", "VoiceOverQuestFramePlayButton", QuestFrame, "BackdropTemplate")
    playButton:SetSize(55, 62)
    playButton:SetPoint("TOPRIGHT", QuestFrame, "TOPRIGHT", 51, -20)
    
    -- Establecer el backdrop con un fondo negro y un borde gris
    playButton:SetBackdrop({
        bgFile = "Interface\\FrameGeneral\\UI-Background-Marble",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
        tile = true,
        tileSize = 32,
        edgeSize = 16,
        insets = { left = 4, right = 4, top = 4, bottom = 4 }
    })
    playButton:SetBackdropColor(0.1, 0.1, 0.1, 0.9)
    playButton:SetBackdropBorderColor(0.5, 0.5, 0.5, 1) -- Color gris para el borde
    
    -- Crear el icono en la parte superior
    local icon = playButton:CreateTexture(nil, "ARTWORK")
    icon:SetSize(32, 32)
    icon:SetPoint("TOP", 0, -8)
    icon:SetTexture("Interface\\AddOns\\AI_VoiceOver\\Textures\\UI-ChatIcon-Share.tga")
    
    -- Crear el texto principal
    local text = playButton:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    text:SetPoint("BOTTOM", 0, 8)
    text:SetText("Play")
    text:SetFont("Fonts\\FRIZQT__.TTF", 12)
    
    -- Personalizar el resplandor (highlight) del botón
    local highlightTexture = playButton:CreateTexture(nil, "HIGHLIGHT")
    highlightTexture:SetTexture("Interface\\Buttons\\ButtonHilight-Square")
    highlightTexture:SetBlendMode("ADD")
    highlightTexture:SetAlpha(0.3)
    highlightTexture:SetAllPoints()
    playButton:SetHighlightTexture(highlightTexture)
    
    -- Crear un botón invisible para manejar los tooltips
    local tooltipButton = CreateFrame("Button", "VoiceOverQuestFrameTooltipButton", QuestFrame)
    tooltipButton:SetAllPoints(playButton) -- Mismo tamaño y posición que el botón principal
    tooltipButton:EnableMouse(true)
    tooltipButton:SetFrameLevel(playButton:GetFrameLevel() + 1) -- Asegurarse de que esté por encima del botón principal
    
    -- Configurar los scripts para el tooltip
    tooltipButton:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        
        local questID = GetCurrentQuestID()
        local currentEvent = GetCurrentEvent()
        local eventName = GetEventName(currentEvent)
        
        if questID then
            local hasAudio = playButton:IsEnabled() and not playButton.icon:IsDesaturated()
            
            if hasAudio then
                GameTooltip:AddLine("Play Audio", 1, 0.82, 0) -- Amarillo dorado
                GameTooltip:AddLine("Event: " .. eventName, 1, 1, 1)
                GameTooltip:AddLine("QuestID: " .. questID, 1, 1, 1)
            else
                GameTooltip:AddLine("No Audio", 0.5, 0.5, 0.5) -- Escala de grises
                GameTooltip:AddLine("Event: " .. eventName, 0.7, 0.7, 0.7) -- Escala de grises más clara
                GameTooltip:AddLine("QuestID: " .. questID, 0.7, 0.7, 0.7) -- Escala de grises más clara
                
                -- Añadir nota solo para eventos Progress
                if currentEvent == Enums.SoundEvent.QuestProgress then
                    GameTooltip:AddLine("Progress audio will be implemented in the future", 0.3, 0.7, 1) -- Azul claro
                end
            end
        end
        
        GameTooltip:Show()
    end)
    
    tooltipButton:SetScript("OnLeave", function(self)
        GameTooltip:Hide()
    end)
    
    -- El botón de tooltip pasa los clics al botón principal
    tooltipButton:SetScript("OnClick", function(self)
        if playButton:IsEnabled() then
            playButton:Click()
        end
    end)
    
    -- Guardar referencias para poder actualizar más tarde
    playButton.icon = icon
    playButton.text = text
    playButton.tooltipButton = tooltipButton
    playButton.lastEvent = GetCurrentEvent() -- Guardar el evento actual
    
    -- Ya no necesitamos estos scripts en el botón principal
    playButton:SetScript("OnEnter", nil)
    playButton:SetScript("OnLeave", nil)
    
    playButton:SetScript("OnClick", function(self)
        local questID = GetCurrentQuestID()
        local currentEvent = GetCurrentEvent()
        local eventName = GetEventName(currentEvent)
        local npcID = GetCurrentNPCID()
        
        DebugPrint(string.format("Botón de reproducción clickeado para questID %s, evento %s, npcID %s", 
            questID, tostring(currentEvent), tostring(npcID)))

        if not self.soundData then
            -- Obtenemos el tipo y el ID del NPC
            local type = npcID and Enums.GUID.Creature or nil
            local npcName = npcID and DataModules:GetObjectName(type, npcID) or "Unknown Name"

            self.soundData = {
                event = currentEvent,
                questID = questID,
                name = npcName,
                title = C_QuestLog.GetTitleForQuestID(questID),
                unitGUID = npcID and Utils:MakeGUID(Enums.GUID.Creature, npcID) or nil
            }
            
            -- Verificar si existe un archivo específico
            if npcID then
                local hasSpecificFile, fileName = CheckSpecificAudioFile(questID, eventName, npcID)
                if hasSpecificFile then
                    self.soundData.fileName = fileName
                    DebugPrint("Usando archivo específico: " .. fileName)
                end
            end
        end

        -- Si ya está reproduciendo, detener
        if self.isPlaying then
            SoundQueue:RemoveSoundFromQueue(self.soundData)
            self.text:SetText("Play")
            self.isPlaying = false
        else
            -- Reproducir el sonido
            local isPlaying = SoundQueue:Contains(self.soundData)

            if not isPlaying then
                SoundQueue:AddSoundToQueue(self.soundData)
                self.text:SetText("Stop")
                self.isPlaying = true
            else
                SoundQueue:RemoveSoundFromQueue(self.soundData)
                self.text:SetText("Play")
            end
        end
    end)

    DebugPrint("Botón de reproducción creado")
    return playButton
end

-- Función para actualizar el botón de reproducción
local function UpdatePlayButton()
    local playButton = QuestFrameAudioButton.playButton
    if not playButton then
        DebugPrint("PlayButton not found!")
        return
    end

    local questID = GetCurrentQuestID()
    local currentEvent = GetCurrentEvent()
    local eventName = GetEventName(currentEvent)
    local npcID = GetCurrentNPCID()

    -- Verificar si el evento ha cambiado
    if playButton.lastEvent ~= currentEvent then
        DebugPrint("El evento ha cambiado de " .. GetEventName(playButton.lastEvent) .. " a " .. eventName)
        StopAudioAndResetButton(playButton)
        playButton.lastEvent = currentEvent
        playButton.soundData = nil -- Limpiar los datos de sonido anteriores
    end

    if questID and currentEvent then
        -- Crear los datos de sonido
        local type = npcID and Enums.GUID.Creature or nil
        local npcName = npcID and DataModules:GetObjectName(type, npcID) or "Unknown Name"

        local soundData = {
            event = currentEvent,
            questID = questID,
            name = npcName,
            title = C_QuestLog.GetTitleForQuestID(questID),
            unitGUID = npcID and Utils:MakeGUID(Enums.GUID.Creature, npcID) or nil
        }

        -- Verificar si hay sonido disponible para la misión
        local hasSound = false
        local audioFileName = nil
        
        if npcID then
            -- Verificar si existe un archivo específico
            local hasSpecificFile, fileName = CheckSpecificAudioFile(questID, eventName, npcID)
            if hasSpecificFile then
                audioFileName = fileName
                soundData.fileName = fileName
                hasSound = DataModules:PrepareSound(soundData)
                DebugPrint("Verificando sonido con formato específico: " .. fileName .. " - Resultado: " .. tostring(hasSound))
            else
                -- Si no hay archivo específico, usar el formato genérico
                DebugPrint("No se encontró archivo específico, usando formato genérico")
                hasSound = DataModules:PrepareSound({ event = currentEvent, questID = questID })
            end
        else
            -- Si no podemos obtener el ID del NPC, usar el formato genérico
            DebugPrint("No se pudo obtener ID de NPC para questID: " .. questID .. " - Usando formato genérico")
            hasSound = DataModules:PrepareSound({ event = currentEvent, questID = questID })
        end

        if hasSound then
            playButton.soundData = soundData
            playButton:Enable()
            playButton.text:SetText("Play")
            playButton.text:SetFont("Fonts\\FRIZQT__.TTF", 12)
            playButton.icon:SetDesaturated(false)
            
            DebugPrint("Audio preparado para misión " .. questID .. " (Evento: " .. eventName .. ")")
        else
            -- Siempre deshabilitamos el botón cuando no hay audio
            playButton:Disable()
            playButton.text:SetText("No Audio")
            playButton.text:SetFont("Fonts\\FRIZQT__.TTF", 8)
            playButton.icon:SetDesaturated(true)
            playButton.text:SetTextColor(0.5, 0.5, 0.5) -- Color gris para el texto
            DebugPrint("No se encontró audio para misión " .. questID .. " (Evento: " .. eventName .. ")")
        end

        playButton:Show()
    else
        playButton:Hide()
    end
end

-- Función para inicializar el módulo
function QuestFrameAudioButton:Initialize()
    if not Addon.db.profile.ShowQuestFrameButton then
        DebugPrint("ShowQuestFrameButton está desactivado, no se inicializa el botón")
        return
    end

    DebugPrint("Inicializando QuestFrameAudioButton")

    -- Crear el botón cuando se cargue el addon
    self.playButton = CreatePlayButton()

    -- Hook para cuando se muestran los detalles de la misión
    hooksecurefunc("QuestFrameDetailPanel_OnShow", function()
        DebugPrint("QuestFrameDetailPanel_OnShow - Evento: Accept")
        UpdatePlayButton()
    end)

    -- Hook para cuando se muestra el progreso de la misión
    hooksecurefunc("QuestFrameProgressPanel_OnShow", function()
        DebugPrint("QuestFrameProgressPanel_OnShow - Evento: Progress")
        UpdatePlayButton()
    end)

    -- Hook para cuando se muestra el panel de recompensa de la misión
    hooksecurefunc("QuestFrameRewardPanel_OnShow", function()
        DebugPrint("QuestFrameRewardPanel_OnShow - Evento: Complete")
        UpdatePlayButton()
    end)

    -- **Añadido**: Hook para el evento OnShow del QuestFrame para actualizar el botón automáticamente 2 segundos después
    QuestFrame:HookScript("OnShow", function()
        DebugPrint("QuestFrame OnShow evento capturado, iniciando actualización del botón después de 2 segundos")
        C_Timer.After(2, UpdatePlayButton)
    end)

    -- Hook para el evento OnHide del QuestFrame para detener cualquier reproducción
    QuestFrame:HookScript("OnHide", function()
        DebugPrint("QuestFrame OnHide evento capturado, deteniendo cualquier reproducción")
        StopAudioAndResetButton(self.playButton)
    end)

    DebugPrint("QuestFrameAudioButton inicializado")
end

-- Función para actualizar la visibilidad de todos los botones
function QuestFrameAudioButton:UpdateButtonVisibility()
    if not self.playButton then
        DebugPrint("playButton no existe, no se puede actualizar la visibilidad")
        return
    end

    if Addon.db.profile.ShowQuestFrameButton then
        UpdatePlayButton()
    else
        self.playButton:Hide()
    end

    DebugPrint("Visibilidad del botón actualizada")
end
