setfenv(1, VoiceOver)
Options = {}

local AceGUI = LibStub("AceGUI-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local AceDBOptions = LibStub("AceDBOptions-3.0")

------------------------------------------------------------
-- Construction of the options table for AceConfigDialog --

local function SortAceConfigOptions(a, b)
    return (a.order or 100) < (b.order or 100)
end

-- Needed to preserve order (modern AceGUI has support for custom sorting of dropdown items, but old versions don't)
local FRAME_STRATAS =
{
    "BACKGROUND",
    "LOW",
    "MEDIUM",
    "HIGH",
    "DIALOG",
}

local slashCommandsHandler = {}
function slashCommandsHandler:values(info)
    if not self.indexToName then
        self.indexToName = { "Nothing" }
        self.indexToCommand = { "" }
        self.commandToIndex = { [""] = 1 }
        for command, handler in Utils:Ordered(Options.table.args.SlashCommands.args, SortAceConfigOptions) do
            if not handler.dropdownHidden then
                table.insert(self.indexToName, handler.name)
                table.insert(self.indexToCommand, command)
                self.commandToIndex[command] = getn(self.indexToCommand)
            end
        end
    end
    return self.indexToName
end

function slashCommandsHandler:get(info)
    local config, key = info.arg()
    return self.commandToIndex[config[key]]
end

function slashCommandsHandler:set(info, value)
    local config, key = info.arg()
    config[key] = self.indexToCommand[value]
end

-- General Tab
---@type AceConfigOptionsTable
local GeneralTab =
{
    name = "General",
    type = "group",
    order = 10,
    args = {
        MinimapButton = {
            type = "group",
            order = 2,
            inline = true,
            name = "Minimap Button",
            args = {
                MinimapButtonShow = {
                    type = "toggle",
                    order = 1,
                    name = "Show Minimap Button",
                    get = function(info) return not Addon.db.profile.MinimapButton.LibDBIcon.hide end,
                    set = function(info, value)
                        Addon.db.profile.MinimapButton.LibDBIcon.hide = not value
                        if value then
                            LibStub("LibDBIcon-1.0"):Show("VoiceOver")
                        else
                            LibStub("LibDBIcon-1.0"):Hide("VoiceOver")
                        end
                    end,
                },
                MinimapButtonLock = {
                    type = "toggle",
                    order = 2,
                    name = "Lock Position",
                    get = function(info) return Addon.db.profile.MinimapButton.LibDBIcon.lock end,
                    set = function(info, value)
                        if value then
                            LibStub("LibDBIcon-1.0"):Lock("VoiceOver")
                        else
                            LibStub("LibDBIcon-1.0"):Unlock("VoiceOver")
                        end
                    end,
                },
                LineBreak1 = { type = "description", name = "", order = 3 },
                MinimapButtons = {
                    type = "group",
                    inline = true,
                    name = "",
                    handler = slashCommandsHandler,
                    args = {
                        MinimapButtonLeftClick = {
                            type = "select",
                            order = 4,
                            name = "Left Click",
                            desc = "Action performed by left-clicking the minimap button.",
                            values = "values",
                            get = "get",
                            set = "set",
                            arg = function(value) return Addon.db.profile.MinimapButton.Commands, "LeftButton" end,
                        },
                        MinimapButtonMiddleClick = {
                            type = "select",
                            order = 4,
                            name = "Middle Click",
                            desc = "Action performed by middle-clicking the minimap button.",
                            values = "values",
                            get = "get",
                            set = "set",
                            arg = function(value) return Addon.db.profile.MinimapButton.Commands, "MiddleButton" end,
                        },
                        MinimapButtonRightClick = {
                            type = "select",
                            order = 4,
                            name = "Right Click",
                            desc = "Action performed by right-clicking the minimap button.",
                            values = "values",
                            get = "get",
                            set = "set",
                            arg = function(value) return Addon.db.profile.MinimapButton.Commands, "RightButton" end,
                        }
                    }
                }
            }
        },
        Frame = {
            type = "group",
            order = 3,
            inline = true,
            name = "Frame",
            disabled = function(info) return Addon.db.profile.SoundQueueUI.HideFrame end,
            args = {
                LockFrame = {
                    type = "toggle",
                    order = 1,
                    name = "Lock Frame",
                    desc = "Prevent the frame from being moved or resized.",
                    get = function(info) return Addon.db.profile.SoundQueueUI.LockFrame end,
                    set = function(info, value)
                        Addon.db.profile.SoundQueueUI.LockFrame = value
                        SoundQueueUI:RefreshConfig()
                    end,
                },
                ResetFrame = {
                    type = "execute",
                    order = 2,
                    name = "Reset Frame",
                    desc = "Resets frame position and size back to default.",
                    func = function(info)
                        SoundQueueUI.frame:Reset()
                    end,
                },
                LineBreak1 = { type = "description", name = "", order = 3 },
                FrameStrata = {
                    type = "select",
                    order = 5,
                    name = "Frame Strata",
                    desc =
                    "Changes the \"depth\" of the frame, determining which other frames will it overlap or fall behind.",
                    values = FRAME_STRATAS,
                    get = function(info)
                        for k, v in ipairs(FRAME_STRATAS) do
                            if v == Addon.db.profile.SoundQueueUI.FrameStrata then
                                return k;
                            end
                        end
                    end,
                    set = function(info, value)
                        Addon.db.profile.SoundQueueUI.FrameStrata = FRAME_STRATAS[value]
                        SoundQueueUI.frame:SetFrameStrata(Addon.db.profile.SoundQueueUI.FrameStrata)
                    end,
                },
                FrameScale = {
                    type = "range",
                    order = 4,
                    name = "Frame Scale",
                    softMin = 0.5,
                    softMax = 2,
                    bigStep = 0.05,
                    isPercent = true,
                    get = function(info) return Addon.db.profile.SoundQueueUI.FrameScale end,
                    set = function(info, value)
                        local wasShown = Version.IsLegacyVanilla and SoundQueueUI.frame:IsShown() -- 1.12 quirk
                        if wasShown then
                            SoundQueueUI.frame:Hide()
                        end
                        Addon.db.profile.SoundQueueUI.FrameScale = value
                        SoundQueueUI:RefreshConfig()
                        if wasShown then
                            SoundQueueUI.frame:Show()
                        end
                    end,
                },
                LineBreak2 = { type = "description", name = "", order = 6 },
                HidePortrait = {
                    type = "toggle",
                    order = 7,
                    name = "Hide NPC Portrait",
                    desc = "Talking NPC portrait will not appear when voice over audio is played.\n\n" ..
                        Utils:ColorizeText(
                            "This might be useful when using other addons that replace the dialog experience, such as " ..
                            Utils:ColorizeText("Immersion", NORMAL_FONT_COLOR_CODE) .. ".",
                            GRAY_FONT_COLOR_CODE),
                    get = function(info) return Addon.db.profile.SoundQueueUI.HidePortrait end,
                    set = function(info, value)
                        Addon.db.profile.SoundQueueUI.HidePortrait = value
                        SoundQueueUI:RefreshConfig()
                    end,
                },
                HideFrame = {
                    type = "toggle",
                    order = 8,
                    name = "Hide Entirely",
                    desc = "Play voiceovers without ever displaying the frame.",
                    disabled = false,
                    get = function(info) return Addon.db.profile.SoundQueueUI.HideFrame end,
                    set = function(info, value)
                        Addon.db.profile.SoundQueueUI.HideFrame = value
                        SoundQueueUI:RefreshConfig()
                    end,
                },
            },
        },
        AdvancedPlayback = {
            type = "group",
            order = 3.5,
            inline = true,
            name = function()
                local iconString = "|TInterface\\AddOns\\AI_VoiceOver\\Textures\\UI-ChatIcon-Share:14:14:0:0|t"
                return iconString .. " Advanced Playback"
            end,
            args = {
                ObjectiveTrackerButton = {
                    type = "toggle",
                    order = 1,
                    name = "Show Objective Tracker Buttons",
                    desc = "Toggle visibility of play buttons in the Objective Tracker",
                    get = function(info) return Addon.db.profile.ShowObjectiveTrackerButtons end,
                    set = function(info, value)
                        Addon.db.profile.ShowObjectiveTrackerButtons = value
                        QuestOverlayUI:UpdateAllButtonsVisibility()
                    end,
                },
                ManualMode = {
                    type = "toggle",
                    order = 2,
                    name = "Play Manual Mode",
                    desc = "Disable automatic playback when interacting with NPCs",
                    get = function(info) return Addon.db.profile.ManualMode end,
                    set = function(info, value)
                        Addon.db.profile.ManualMode = value
                        print("ManualMode set to:", value) -- Debug
                    end,
                },
                ShowQuestFrameButton = {
                    type = "toggle",
                    order = 3,
                    name = "Show Quest Frame Button",
                    desc = "Show a button below Accept/Complete in the quest frame to manually play quest text",
                    get = function(info) return Addon.db.profile.ShowQuestFrameButton end,
                    set = function(info, value)
                        Addon.db.profile.ShowQuestFrameButton = value
                        if value then
                            -- Si se activa la opción, inicializamos el botón si aún no existe
                            if not QuestFrameAudioButton.playButton then
                                QuestFrameAudioButton:Initialize()
                            end
                        end
                        -- Actualizamos la visibilidad del botón
                        if QuestFrameAudioButton and QuestFrameAudioButton.UpdateButtonVisibility then
                            QuestFrameAudioButton:UpdateButtonVisibility()
                        else
                            DebugPrint("QuestFrameAudioButton no está disponible o no tiene UpdateButtonVisibility")
                        end
                    end,
                },
                EnableSoundControl = {
                    type = "toggle",
                    order = 4,
                    name = "Enable Sound Control",
                    desc = "Enable automatic volume adjustment for other sound channels when VoiceOver is playing",
                    get = function(info) return Addon.db.profile.EnableSoundControl end,
                    set = function(info, value)
                        Addon.db.profile.EnableSoundControl = value
                        if value then
                            Debug:Print("Sound Control Enabled", "SoundControlUI")
                            -- Aquí puedes añadir lógica adicional si es necesario
                        else
                            Debug:Print("Sound Control Disabled", "SoundControlUI")
                            -- Restaurar volúmenes si está deshabilitado
                            if SoundControlUI and SoundControlUI.RestoreVolumes then
                                SoundControlUI:RestoreVolumes()
                            end
                        end
                    end,
                },
            },
        },
        Audio = {
            type = "group",
            order = 4,
            inline = true,
            name = "Audio",
            args = {
                SoundChannel = Version:IsRetailOrAboveLegacyVersion(40000) and {
                    type = "select",
                    width = 0.75,
                    order = 1,
                    name = "Sound Channel",
                    desc = "Controls which sound channel VoiceOver will play in.",
                    values = Enums.SoundChannel:GetValueToNameMap(),
                    get = function(info) return Addon.db.profile.Audio.SoundChannel end,
                    set = function(info, value)
                        Addon.db.profile.Audio.SoundChannel = value
                        SoundQueueUI:RefreshConfig()
                    end,
                },
                LineBreak = { type = "description", name = "", order = 2 },
                GossipFrequency = {
                    type = "select",
                    width = 1.1,
                    order = 3,
                    name = "NPC Greeting Playback Frequency",
                    desc = "Controls how often VoiceOver will play NPC greeting dialog.",
                    values = {
                        [Enums.GossipFrequency.Always] = "Always",
                        [Enums.GossipFrequency.OncePerQuestNPC] = "Play Once for Quest NPCs",
                        [Enums.GossipFrequency.OncePerNPC] = "Play Once for All NPCs",
                        [Enums.GossipFrequency.Never] = "Never",
                    },
                    get = function(info) return Addon.db.profile.Audio.GossipFrequency end,
                    set = function(info, value)
                        Addon.db.profile.Audio.GossipFrequency = value
                        SoundQueueUI:RefreshConfig()
                    end,
                },
                AutoToggleDialog = (Version.IsLegacyVanilla or Version:IsRetailOrAboveLegacyVersion(60100) or nil) and {
                    type = "toggle",
                    width = 2.25,
                    order = 4,
                    name = "Mute Vocal NPCs Greetings While VoiceOver is Playing",
                    desc = Version.IsLegacyVanilla and
                        "Interrupts generic NPC greeting voicelines upon interacting with them if a voiceover will start playing." or
                        "While VoiceOver is playing, the Dialog channel will be muted.",
                    disabled = function()
                        return Version:IsRetailOrAboveLegacyVersion(60100) and
                            Addon.db.profile.Audio.SoundChannel == Enums.SoundChannel.Dialog
                    end,
                    get = function(info) return Addon.db.profile.Audio.AutoToggleDialog end,
                    set = function(info, value)
                        Addon.db.profile.Audio.AutoToggleDialog = value
                        SoundQueueUI:RefreshConfig()
                        if Addon.db.profile.Audio.AutoToggleDialog and Version:IsRetailOrAboveLegacyVersion(60100) then
                            SetCVar("Sound_EnableDialog", 1)
                        end
                    end,
                },
                LineBreak2 = { type = "description", name = "", order = 5 },
                ToggleSyncToWindowState = {
                    type = "toggle",
                    order = 6,
                    width = 2,
                    name = "Sync Dialog to Window State",
                    desc = "VoiceOver dialog will automatically stop when the gossip/quest window is closed.",
                    get = function(info) return Addon.db.profile.Audio.StopAudioOnDisengage end,
                    set = function(info, value)
                        Addon.db.profile.Audio.StopAudioOnDisengage = value
                    end,
                },
            }
        },
        Debug = {
            type = "group",
            order = 5,
            inline = true,
            name = "Debugging Tools",
            args = {
                DebugEnabled = {
                    type = "toggle",
                    order = 1,
                    width = 1.25,
                    name = "Enable Debug Messages",
                    desc = "Enables printing of some \"useful\" debug messages to the chat window.",
                    get = function(info) return Addon.db.profile.DebugEnabled end,
                    set = function(info, value) Addon.db.profile.DebugEnabled = value end,
                }
            }
        }
    }
}

---@type AceConfigOptionsTable
local AdvanceToolsTab = {
    name = "AdvanceTools",
    type = "group",
    order = 25,
    args = {
        LatamWarning = {
            type = "description",
            order = 0,
            name = "|cFFFFD700Note: All AdvanceTools except Quest Progress are available only for Latin America.|r",
            fontSize = "medium",
        },
        QuestProgressModule = {
            type = "group",
            order = 1,
            name = "Quest Progress",
            inline = true,
            args = {
                EnableModule = {
                    type = "toggle",
                    order = 1,
                    width = 1.50,
                    name = "Enable Quest Progress",
                    desc =
                    "Activa o desactiva el módulo que reproduce el texto de progreso cuando alcanzas el 50% de una misión.",
                    get = function(info) return Addon.db.profile.QuestProgressEnabled end,
                    set = function(info, value)
                        Addon.db.profile.QuestProgressEnabled = value
                        if value then
                            VoiceOver.MissionProgress.Activate()
                        else
                            Addon.db.profile.QuestProgressDebugEnabled = false
                            VoiceOver.MissionProgress.Deactivate()
                        end
                    end,
                },
                QuestProgressDebugEnabled = {
                    type = "toggle",
                    order = 2,
                    width = 0.75,
                    name = "DebugMode",
                    desc = "Enables debug messages specifically for Quest Progress module.",
                    disabled = function() return not Addon.db.profile.QuestProgressEnabled end,
                    get = function(info) return Addon.db.profile.QuestProgressDebugEnabled end,
                    set = function(info, value)
                        Addon.db.profile.QuestProgressDebugEnabled = value
                        if value then
                            print("|cffff0000Debug Mode for Quest Progress Activated|r")
                        else
                            print("|cffff0000Debug Mode for Quest Progress Deactivated|r")
                        end
                    end,
                },
                Description = {
                    type = "description",
                    order = 3,
                    name =
                    "\nEl módulo Quest Progress reproduce el texto de progreso cuando alcanzas el 50% de una misión, sin importar dónde te encuentres.\n",
                },
            },
        },
        LatamOnlyGroup = {
            type = "group",
            order = 2,
            name = "Latin America Only Features",
            args = {
                BonusQuestDetector = {
                    type = "group",
                    order = 1,
                    name = "Bonus Quest Detector",
                    inline = true,
                    args = {
                        EnableModule = {
                            type = "toggle",
                            order = 1,
                            width = 1.50,
                            name = "Enable Bonus Quest Progress",
                            desc =
                            "Activa o desactiva el módulo que detecta y maneja el progreso de las misiones de bonificación.",
                            get = function(info) return Addon.db.profile.BonusQuestDetectorEnabled end,
                            set = function(info, value)
                                Addon.db.profile.BonusQuestDetectorEnabled = value
                                if value then
                                    DEFAULT_CHAT_FRAME:AddMessage("|cffffff00Bonus Quest Progress Module Activated|r")
                                else
                                    Addon.db.profile.BonusQuestDetectorDebugEnabled = false
                                    DEFAULT_CHAT_FRAME:AddMessage("|cffffff00Bonus Quest Progress Module Deactivated|r")
                                end
                            end,
                        },
                        BonusQuestDebugEnabled = {
                            type = "toggle",
                            order = 2,
                            width = 0.75,
                            name = "DebugMode",
                            desc = "Enables debug messages specifically for Bonus Quest Progress module.",
                            disabled = function() return not Addon.db.profile.BonusQuestDetectorEnabled end,
                            get = function(info) return Addon.db.profile.BonusQuestDetectorDebugEnabled end,
                            set = function(info, value)
                                Addon.db.profile.BonusQuestDetectorDebugEnabled = value
                                BonusQuestDetector.DebugMode = value
                                if value then
                                    print("|cffff0000Debug Mode for Bonus Quest Progress Activated|r")
                                else
                                    print("|cffff0000Debug Mode for Bonus Quest Progress Deactivated|r")
                                end
                            end,
                        },
                        Description = {
                            type = "description",
                            order = 3,
                            name =
                            "\nEl módulo Bonus Quest Progress proporciona voz a las misiones de bonificación que no la tienen durante el leveleo, mejorando la inmersión y experiencia del jugador.\n",
                        },
                    },
                },
                ItemReaderModule = {
                    type = "group",
                    order = 2,
                    name = "Item Reader",
                    inline = true,
                    args = {
                        EnableModule = {
                            type = "toggle",
                            order = 1,
                            width = 1.50,
                            name = "Enable Item Reader",
                            desc =
                            "Activa o desactiva el módulo que reproduce el sonido de ítems de misión recogidos que sean de textos largos o relevantes.",
                            get = function(info) return Addon.db.profile.ItemReaderEnabled end,
                            set = function(info, value)
                                Addon.db.profile.ItemReaderEnabled = value
                                if value then
                                    VoiceOver.ItemReader.Activate()
                                else
                                    Addon.db.profile.ItemReaderDebugEnabled = false
                                    VoiceOver.ItemReader.Deactivate()
                                end
                            end,
                        },
                        ItemReaderDebugEnabled = {
                            type = "toggle",
                            order = 2,
                            width = 0.75,
                            name = "DebugMode",
                            desc = "Enables debug messages specifically for Item Reader module.",
                            disabled = function() return not Addon.db.profile.ItemReaderEnabled end,
                            get = function(info) return Addon.db.profile.ItemReaderDebugEnabled end,
                            set = function(info, value)
                                Addon.db.profile.ItemReaderDebugEnabled = value
                                if value then
                                    print("|cffff0000Debug Mode for Item Reader Activated|r")
                                else
                                    print("|cffff0000Debug Mode for Item Reader Deactivated|r")
                                end
                                isDebugEnabled = value
                            end,
                        },
                        Description = {
                            type = "description",
                            order = 3,
                            name =
                            "\nEl módulo Item Reader reproduce el sonido de ítems de misión recogidos que sean de textos largos o relevantes, mejorando la experiencia del jugador.\n",
                        },
                    },
                },
                RareAnnounceModule = {
                    type = "group",
                    order = 3,
                    name = "Rare Announce",
                    inline = true,
                    args = {
                        EnableModule = {
                            type = "toggle",
                            order = 1,
                            width = 1.50,
                            name = "Enable Rare Announce",
                            desc = "Activa o desactiva el narrador que te avisa cuando hay un rare cerca.",
                            get = function(info) return Addon.db.profile.RareAnnounceEnabled end,
                            set = function(info, value)
                                Addon.db.profile.RareAnnounceEnabled = value
                                if value then
                                    VoiceOver.RareAnnounce.Activate()
                                else
                                    Addon.db.profile.RareAnnounceDebugEnabled = false
                                    VoiceOver.RareAnnounce.Deactivate()
                                end
                            end,
                        },
                        RareAnnounceDebugEnabled = {
                            type = "toggle",
                            order = 2,
                            width = 0.75,
                            name = "DebugMode",
                            desc = "Enables debug messages specifically for Rare Announce module.",
                            disabled = function() return not Addon.db.profile.RareAnnounceEnabled end,
                            get = function(info) return Addon.db.profile.RareAnnounceDebugEnabled end,
                            set = function(info, value)
                                Addon.db.profile.RareAnnounceDebugEnabled = value
                                if value then
                                    print("|cffff0000Debug Mode for Rare Announce Activated|r")
                                else
                                    print("|cffff0000Debug Mode for Rare Announce Deactivated|r")
                                end
                                isDebugEnabled = value
                            end,
                        },
                        Description = {
                            type = "description",
                            order = 3,
                            name =
                            "\nEl módulo Rare Announce te avisa cuando hay un rare cerca, mejorando tu experiencia al explorar.\n",
                        },
                    },
                },
                GameObjectReaderModule = {
                    type = "group",
                    order = 4,
                    name = "Game Object Reader",
                    inline = true,
                    args = {
                        EnableModule = {
                            type = "toggle",
                            order = 1,
                            width = 1.50,
                            name = "Enable Game Object Reader",
                            desc =
                            "Activa o desactiva el módulo que reproduce sonidos de objetos interactivos en el mundo.",
                            get = function(info) return Addon.db.profile.GameObjectReaderEnabled end,
                            set = function(info, value)
                                Addon.db.profile.GameObjectReaderEnabled = value
                                if value then
                                    VoiceOver.GameObjectReader.Activate()
                                else
                                    Addon.db.profile.GameObjectReaderDebugEnabled = false
                                    VoiceOver.GameObjectReader.Deactivate()
                                end
                            end,
                        },
                        GameObjectReaderDebugEnabled = {
                            type = "toggle",
                            order = 2,
                            width = 0.75,
                            name = "DebugMode",
                            desc = "Enables debug messages specifically for Game Object Reader module.",
                            disabled = function() return not Addon.db.profile.GameObjectReaderEnabled end,
                            get = function(info) return Addon.db.profile.GameObjectReaderDebugEnabled end,
                            set = function(info, value)
                                Addon.db.profile.GameObjectReaderDebugEnabled = value
                                if value then
                                    print("|cffff0000Debug Mode for Game Object Reader Activated|r")
                                else
                                    print("|cffff0000Debug Mode for Game Object Reader Deactivated|r")
                                end
                                isGameObjectReaderDebugEnabled = value
                            end,
                        },
                        Description = {
                            type = "description",
                            order = 3,
                            name =
                            "\nEl módulo Game Object Reader reproduce sonidos de objetos interactivos en el mundo. Todavía está en construcción.\n",
                        },
                    },
                },
                NPCLiveIAModule = {
                    type = "group",
                    order = 5,
                    name = "NPC Live IA",
                    inline = true,
                    args = {
                        EnableModule = {
                            type = "toggle",
                            order = 1,
                            width = 1.50,
                            name = "Enable NPC Live IA",
                            desc =
                            "Activa o desactiva el módulo que reproduce voces para los textos de bocadillo de NPCs.",
                            get = function(info) return Addon.db.profile.NPCLiveIAEnabled end,
                            set = function(info, value)
                                Addon.db.profile.NPCLiveIAEnabled = value
                                if value then
                                    VoiceOver.NPCLiveIA.Activate()
                                else
                                    Addon.db.profile.NPCLiveIADebugEnabled = false
                                    VoiceOver.NPCLiveIA.Deactivate()
                                end
                            end,
                        },
                        NPCLiveIADebugEnabled = {
                            type = "toggle",
                            order = 2,
                            width = 0.75,
                            name = "DebugMode",
                            desc = "Enables debug messages specifically for NPC Live IA module.",
                            disabled = function() return not Addon.db.profile.NPCLiveIAEnabled end,
                            get = function(info) return Addon.db.profile.NPCLiveIADebugEnabled end,
                            set = function(info, value)
                                Addon.db.profile.NPCLiveIADebugEnabled = value
                                if value then
                                    print("|cffff0000Debug Mode for NPC Live IA Activated|r")
                                else
                                    print("|cffff0000Debug Mode for NPC Live IA Deactivated|r")
                                end
                                isNPCLiveIADebugEnabled = value
                            end,
                        },
                        Description = {
                            type = "description",
                            order = 3,
                            name =
                            "\nEl módulo NPC Live IA reproduce voces para los textos de bocadillo de NPCs en el mundo.\n",
                        },
                    },
                },
            },
        },
    },
}




---@type AceConfigOptionsTable
local LegacyWrathTab = (Version.IsLegacyWrath or Version.IsLegacyBurningCrusade or nil) and {
    type = "group",
    name = Version.IsLegacyBurningCrusade and "2.4.3 Backport" or "3.3.5 Backport",
    order = 19,
    args = {
        PlayOnMusicChannel = {
            type = "group",
            order = 100,
            name = "Play Voiceovers on Music Channel",
            inline = true,
            args = {
                Description = {
                    type = "description",
                    order = 100,
                    name = format(
                        "%s client lacks the ability to stop addon sounds at will. As a workaround, you can play the voiceovers on the music channel instead, which, unlike sounds, can be stopped. Regular background music will not be playing throughout the duration of voiceovers.|n|nIf you normally play with music disabled - it will be temporarily enabled during voiceovers, but no actual background music will be played.",
                        Version.IsLegacyBurningCrusade and "2.4.3" or "3.3.5"),
                },
                Enabled = {
                    type = "toggle",
                    order = 200,
                    name = "Enable",
                    get = function(info) return Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Enabled end,
                    set = function(info, value) Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Enabled = value end,
                },
                Disabled = {
                    type = "description",
                    order = 300,
                    name = format(
                        "With this option disabled you %swill not be able to pause|r voiceovers after they start playing. Attempting to pause will instead %1$spause the voiceover queue|r once the current sound has finished playing.",
                        RED_FONT_COLOR_CODE),
                    hidden = function(info) return Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Enabled end,
                },
                Settings = {
                    type = "group",
                    order = 400,
                    name = "",
                    inline = true,
                    hidden = function(info) return not Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Enabled end,
                    args = {
                        FadeOutMusic = {
                            type = "range",
                            order = 100,
                            name = "Music Fade Out (secs)",
                            desc =
                            "Background music will fade out over this number of seconds before playing voiceovers. Has no effect if in-game music is disabled or muted.",
                            min = 0,
                            softMax = 2,
                            bigStep = 0.05,
                            disabled = Version.IsLegacyBurningCrusade,
                            get = function(info) return Addon.db.profile.LegacyWrath.PlayOnMusicChannel.FadeOutMusic end,
                            set = function(info, value)
                                Addon.db.profile.LegacyWrath.PlayOnMusicChannel.FadeOutMusic =
                                    value
                            end,
                        },
                        Volume = {
                            type = "range",
                            order = 200,
                            name = "Voiceover Volume",
                            desc =
                            "Music channel volume will be temporarily adjusted to this value while the voiceovers are playing.",
                            min = 0,
                            max = 1,
                            bigStep = 0.01,
                            isPercent = true,
                            get = function(info) return Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Volume end,
                            set = function(info, value) Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Volume = value end,
                        },
                    }
                },
            }
        },
        Portraits = {
            type = "group",
            order = 200,
            name = "Animated Portraits",
            inline = true,
            args = {
                HDModels = {
                    type = "toggle",
                    order = 100,
                    name = "I Have HD Models",
                    desc =
                    "Turn this on if you're using patches with HD character models. This will correct the animation timings for HD models of Undead and Goblin NPCs.",
                    get = function(info) return Addon.db.profile.LegacyWrath.HDModels end,
                    set = function(info, value) Addon.db.profile.LegacyWrath.HDModels = value end,
                },
            }
        },
    }
}

-- Pestaña Agradecimientos
---@type AceConfigOptionsTable
local AcknowledgementsTab =
{
    name = "Acknowledgments",
    type = "group",
    order = 30,
    args = {
        Logo = {
            type = "description",
            order = 0,
            name = "",
            image = "Interface\\AddOns\\AI_VoiceOver\\gratitude_orc.tga",
            imageWidth = 600,
            imageHeight = 306,
        },
        ThankYouWall = {
            type = "group",
            order = 1,
            inline = true,
            name = "Wall of Gratitude",
            args = {
                Description = {
                    type = "description",
                    order = 1,
                    name = function()
                        local englishText = "|cFFFFD700Coming Soon: A Wall of Gratitude|r\n\n" ..
                            "We're preparing a special tribute to honor every individual who has contributed to VoiceOver. " ..
                            "Your support, no matter how small, has been instrumental in bringing this project to life. " ..
                            "Stay tuned as we unveil our heartfelt appreciation for each of you who have lent your voice to our cause."

                        local spanishText = "|cFFFFD700Próximamente: Un Muro de Agradecimientos|r\n\n" ..
                            "Estamos preparando un tributo especial para honrar a cada persona que ha contribuido a VoiceOver. " ..
                            "Tu apoyo, sin importar cuán pequeño, ha sido fundamental para dar vida a este proyecto. " ..
                            "Mantente atento mientras revelamos nuestro sincero agradecimiento a cada uno de ustedes que han prestado su voz a nuestra causa."

                        return englishText .. "\n\n" .. spanishText
                    end,
                },
            }
        }
    }
}

-- Pestaña Donaciones
---@type AceConfigOptionsTable
-- Variables para los textos en diferentes idiomas
-- Variables para los textos en diferentes idiomas
local donationTexts = {
    es =
    "|cffffffffLas donaciones serán usadas para crear la versión en Español Latino y Español de España, y a medida que avance el proyecto, se extenderá a todos los idiomas.|r",
    en =
    "|cffffffffDonations will be used to create the Latin American Spanish and European Spanish versions, and as the project progresses, it will expand to all languages.|r",
    fr =
    "|cffffffffLes dons seront utilisés pour créer les versions espagnoles d'Amérique latine et d'Espagne, et à mesure que le projet avancera, il s'étendra à toutes les langues.|r",
    it =
    "|cffffffffLe donazioni saranno utilizzate per creare le versioni spagnole latinoamericane e spagnole europee e, man mano che il progetto progredirà, si espanderà a tutte le lingue.|r",
    pt =
    "|cffffffffAs doações serão usadas para criar as versões em espanhol latino-americano e espanhol europeu e, à medida que o projeto avança, expandir-se-ão para todos os idiomas.|r",
}

-- Variable para almacenar el idioma seleccionado
local selectedLanguage = "es"

-- Pestaña Donaciones
local DonationsTab = {
    name = "Donations",
    type = "group",
    order = 35,
    args = {
        DiscordHeader = {
            type = "header",
            order = 1,
            name = "Discord Community",
        },
        DiscordInfo = {
            type = "description",
            order = 2,
            name = "For more information, visit us on Discord:",
            fontSize = "medium",
        },
        DiscordLink = {
            type = "input",
            order = 3,
            width = "full",
            name = "|cff7289DADiscord|r",
            desc = "Join our Discord community!",
            get = function() return "https://discord.gg/jHPsF2dt9y" end,
            set = function() end,
        },
        DonationInfo = {
            type = "group",
            order = 4,
            inline = true,
            name = "",
            args = {
                LanguageHeader = {
                    type = "header",
                    order = 1,
                    name = "Language Selection",
                },
                LanguageSelection = {
                    type = "select",
                    order = 2,
                    name = "Select Language",
                    desc = "Choose the language to view the corresponding description.",
                    values = {
                        es = "Español",
                        en = "English",
                        fr = "Français",
                        it = "Italiano",
                        pt = "Português",
                    },
                    get = function() return selectedLanguage end,
                    set = function(_, newValue)
                        selectedLanguage = newValue
                    end,
                },
                DescriptionHeader = {
                    type = "header",
                    order = 3,
                    name = "Project Description",
                },
                Description = {
                    type = "description",
                    order = 4,
                    name = function()
                        return donationTexts[selectedLanguage]
                    end,
                },
                DonationLinks = {
                    type = "group",
                    order = 5,
                    inline = true,
                    name = "",
                    args = {
                        DonationHeader = {
                            type = "header",
                            order = 1,
                            name = "Support Options",
                        },
                        PayPalLink = {
                            type = "input",
                            order = 2,
                            width = "full",
                            name = "|cff0079C1PayPal|r",
                            desc = "Donate via PayPal",
                            get = function() return "neo4400@hotmail.com" end,
                            set = function() end,
                        },
                        PatreonLink = {
                            type = "input",
                            order = 3,
                            width = "full",
                            name = "|cff3399FFPatreon|r",
                            desc = "Support us on Patreon",
                            get = function() return "https://patreon.com/NeoAuras" end,
                            set = function() end,
                        },
                        KoFiLink = {
                            type = "input",
                            order = 4,
                            width = "full",
                            name = "|cff00bfffKo-fi|r",
                            desc = "Buy us a coffee on Ko-fi",
                            get = function() return "https://ko-fi.com/andresneo7" end,
                            set = function() end,
                        },
                    }
                },
            }
        }
    }
}


---@type AceConfigOptionsTable
local DataModulesTab =
{
    name = function()
        return format("Data Modules%s",
            next(Options.table.args.DataModules.args.Available.args) and "|cFF00CCFF (NEW)|r" or "")
    end,
    type = "group",
    childGroups = "tree",
    order = 20,
    args = {
        DescriptionHeader = {
            type = "header",
            order = 1,
            name = "Data Modules Information / Información de Módulos de Datos",
        },
        Description = {
            type = "description",
            order = 2,
            name =
                "This module ensures that available packs in the addons folder are loaded. The voice pack does not need to be activated in the game like other addons, Voice Over Mod recognizes it just by installing it.\n\n" ..
                "Este módulo asegura que los paquetes disponibles en la carpeta de addons sean cargados. El paquete de voz no necesita ser activado en el juego como otros addons, Voice Over Mod lo reconoce con solo instalarlo.",
            fontSize = "medium",
        },
        LoadedPacksHeader = {
            type = "header",
            order = 3,
            name = "Loaded Sound Packages",
        },
        LoadedPacks = {
            type = "group",
            name = "",
            order = 4,
            inline = true,
            args = {}
        },
        Available = {
            type = "group",
            name = "|cFF00CCFFMore Sound Packs|r",
            order = 100000,
            hidden = function(info) return not next(Options.table.args.DataModules.args.Available.args) end,
            args = {}
        }
    }
}

---@type AceConfigOptionsTable
local SlashCommands = {
    type = "group",
    name = "Commands",
    order = 110,
    inline = true,
    dialogHidden = true,
    args = {
        PlayPause = {
            type = "execute",
            order = 1,
            name = "Play/Pause Audio",
            desc = "Play/Pause voiceovers",
            hidden = true,
            func = function(info)
                SoundQueue:TogglePauseQueue()
            end
        },
        Play = {
            type = "execute",
            order = 2,
            name = "Play Audio",
            desc = "Resume the playback of voiceovers",
            func = function(info)
                SoundQueue:ResumeQueue()
            end
        },
        Pause = {
            type = "execute",
            order = 3,
            name = "Pause Audio",
            desc = "Pause the playback of voiceovers",
            func = function(info)
                SoundQueue:PauseQueue()
            end
        },
        Skip = {
            type = "execute",
            order = 4,
            name = "Skip Line",
            desc = "Skip the currently played voiceover",
            func = function(info)
                local soundData = SoundQueue:GetCurrentSound()
                if soundData then
                    SoundQueue:RemoveSoundFromQueue(soundData)
                end
            end
        },
        Clear = {
            type = "execute",
            order = 5,
            name = "Clear Queue",
            desc = "Stop the playback and clears the voiceovers queue",
            func = function(info)
                SoundQueue:RemoveAllSoundsFromQueue()
            end
        },
        Options = {
            type = "execute",
            order = 100,
            name = "Open Options",
            desc = "Open the options panel",
            func = function(info)
                Options:OpenConfigWindow()
            end
        },
    }
}

---@type AceConfigOptionsTable
Options.table = {
    name = "Voice Over Mod 2.0",
    type = "group",
    childGroups = "tab",
    args = {
        General = GeneralTab,
        AdvanceTools = AdvanceToolsTab, -- Añadido AdvanceToolsTab aquí
        LegacyWrath = LegacyWrathTab,
        DataModules = DataModulesTab,
        Acknowledgements = AcknowledgementsTab,
        Donations = DonationsTab,
        Profiles = nil, -- Filled in Options:OnInitialize, order is implicitly 100
        SlashCommands = SlashCommands,
    }
}
------------------------------------------------------------

---@param module DataModuleMetadata
---@param order number
function Options:AddDataModule(module, order)
    local descriptionOrder = 0
    local function GetNextOrder()
        descriptionOrder = descriptionOrder + 1
        return descriptionOrder
    end
    local function MakeDescription(header, text)
        return {
            type = "description",
            order = GetNextOrder(),
            name = function()
                return format("%s%s: |r%s",
                    NORMAL_FONT_COLOR_CODE, header, type(text) == "function" and text() or text)
            end
        }
    end

    local name, title, notes, loadable, reason = DataModules:GetModuleAddOnInfo(module)
    if reason == "DEMAND_LOADED" or reason == "INTERFACE_VERSION" then
        reason = nil
    end
    DataModulesTab.args[module.AddonName] = {
        name = function()
            local isLoaded = C_AddOns.IsAddOnLoaded(module.AddonName)
            return format("%d. %s%s%s|r",
                order,
                reason and RED_FONT_COLOR_CODE or isLoaded and HIGHLIGHT_FONT_COLOR_CODE or GRAY_FONT_COLOR_CODE,
                string.gsub(module.Title, "VoiceOver Data %- ", ""),
                isLoaded and "" or " (not loaded)")
        end,
        type = "group",
        order = order,
        args = {
            AddonName = MakeDescription("Addon Name", module.AddonName),
            Title = MakeDescription("Title", module.Title),
            ModuleVersion = MakeDescription("Module Data Format Version", module.ModuleVersion),
            ModulePriority = MakeDescription("Module Priority", module.ModulePriority),
            ContentVersion = MakeDescription("Content Version", module.ContentVersion),
            LoadOnDemand = MakeDescription("Load on Demand", module.LoadOnDemand and "Yes" or "No"),
            Loaded = MakeDescription("Is Loaded",
                function() return C_AddOns.IsAddOnLoaded(module.AddonName) and "Yes" or "No" end),
            NotLoadableReason = {
                type = "description",
                order = GetNextOrder(),
                name = format("%sReason: |r%s%s|r", NORMAL_FONT_COLOR_CODE, RED_FONT_COLOR_CODE,
                    reason and _G["ADDON_" .. reason] or ""),
                hidden = not reason,
            },
            Load = {
                type = "execute",
                order = GetNextOrder(),
                name = "Load",
                hidden = function() return reason or not module.LoadOnDemand or C_AddOns.IsAddOnLoaded(module.AddonName) end,
                func = function()
                    local loaded, reason = DataModules:LoadModule(module)
                    if not loaded then
                        StaticPopup_Show("VOICEOVER_ERROR",
                            format([[Failed to load data module "%s". Reason: %s]], module.AddonName,
                                reason and _G["ADDON_" .. reason] or "Unknown"))
                    end
                end,
            },
        }
    }
end

---@param module AvailableDataModule
---@param order number
---@param update boolean Data module has update
function Options:AddAvailableDataModule(module, order, update)
    local descriptionOrder = 0
    local function GetNextOrder()
        descriptionOrder = descriptionOrder + 1
        return descriptionOrder
    end
    local function MakeDescription(header, text)
        return {
            type = "description",
            order = GetNextOrder(),
            name = function()
                return format("%s%s: |r%s",
                    NORMAL_FONT_COLOR_CODE, header, type(text) == "function" and text() or text)
            end
        }
    end

    DataModulesTab.args.Available.args[module.AddonName] = {
        name = Utils:ColorizeText(
            format(update and "%s (Update)" or "%s", string.gsub(module.Title, "VoiceOver Data %- ", "")), "|cFF00CCFF"),
        type = "group",
        order = order,
        args = {
            AddonName = MakeDescription("Addon Name", module.AddonName),
            Title = MakeDescription("Title", module.Title),
            ContentVersion = MakeDescription("Content Version",
                format(update and "%2$s -> |cFF00CCFF%1$s|r" or "%s", module.ContentVersion,
                    update and DataModules:GetPresentModule(module.AddonName).ContentVersion)),
            URL = {
                type = "input",
                order = GetNextOrder(),
                width = "full",
                name = "Download URL",
                get = function(info) return module.URL end,
                set = function(info) end,
            },
        }
    }
end

---Initialization of opens panel
function Options:Initialize()
    self.table.args.Profiles = AceDBOptions:GetOptionsTable(Addon.db)

    -- Create options table
    Debug:Print("Registering options table...", "Options")
    local AceConfig = LibStub("AceConfig-3.0")
    if Addon.RegisterOptionsTable then
        -- Embedded version for 1.12
        AceConfig = Addon
    end
    AceConfig:RegisterOptionsTable("VoiceOver", self.table, "vo")
    AceConfigDialog:AddToBlizOptions("VoiceOver")
    for key, tab in Utils:Ordered(Options.table.args, SortAceConfigOptions) do
        if not tab.hidden and not tab.dialogHidden then
            AceConfigDialog:AddToBlizOptions("VoiceOver", type(tab.name) == "function" and tab.name() or tab.name,
                "VoiceOver", key)
        end
    end
    Debug:Print("Done!", "Options")

    -- Create the option frame
    ---@type AceGUIFrame|AceGUIWidget
    self.frame = AceGUI:Create("Frame")
    --AceConfigDialog:SetDefaultSize("VoiceOver", 640, 780) -- Let it be auto-sized
    AceConfigDialog:Open("VoiceOver", self.frame)
    self.frame:SetLayout("Fill")
    self.frame:Hide()

    -- Enable the frame to be closed with Escape key
    _G["VoiceOverOptions"] = self.frame.frame
    tinsert(UISpecialFrames, "VoiceOverOptions")
end

function Options:OpenConfigWindow()
    if self.frame:IsShown() then
        PlaySound(SOUNDKIT.IG_MAINMENU_CLOSE)
        self.frame:Hide()
    else
        PlaySound(SOUNDKIT.IG_MAINMENU_OPEN)
        self.frame:Show()
        AceConfigDialog:Open("VoiceOver", self.frame)
    end
end
