local AceConfig = LibStub("AceConfig-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("CritMatic")
Critmatic = Critmatic or {}

function Critmatic:CreateOptionsTable()
    local Settings = LibStub("LibMatic-Settings-1.0", true)
    local notification_constructor = Critmatic:GetModule("notification_constructor", true)
    local args = {}

    local function alertStrings()
        return Critmatic.db.profile.alertNotificationFormat.strings
    end

    local function preview(formatKey, isDamage, isCrit, sound)
        return function()
            if notification_constructor then
                notification_constructor:formatConstructor(alertStrings()[formatKey], isDamage, isCrit, sound)
            end
        end
    end

    if Settings then
        args.general_tab = Settings:BuildGeneralPage({
            name = L["options_general"],
            order = 1,
            currentAddon = "CritMatic",
            bind = { table = function() return Critmatic.db.profile.generalSettings end },
            toggles = {
                { key = "alertNotificationsEnabled", order = 2, name = L["options_show_alert_notifications"], desc = L["options_show_alert_notifications_desc"] },
                { key = "chatNotificationsEnabled", order = 3, name = L["options_show_chat_notifications"], desc = L["options_show_chat_notifications_desc"] },
                { key = "isChangeLogAutoPopUpEnabled", order = 4, name = L["options_show_change_log"], desc = L["options_show_change_log_desc"] },
                { key = "critsOnlyEnabled", order = 5, name = L["options_crits_only"], desc = L["options_crits_only_desc"] },
                { key = "showPreviousRecord", order = 6, name = L["options_show_previous_record"], desc = L["options_show_previous_record_desc"] },
                { key = "ignoreTrivialTargets", order = 7, name = L["options_ignore_trivial_targets"], desc = L["options_ignore_trivial_targets_desc"] },
            },
            extras = {
                critLogEnabled = {
                    name = L["options_show_crit_log"],
                    desc = L["options_show_crit_log_desc"],
                    type = "toggle",
                    order = 1,
                    set = function(_, newVal)
                        if newVal ~= Critmatic.db.profile.isCritLogFrameShown then
                            toggleCritMaticCritLog()
                        end
                    end,
                    get = function()
                        return Critmatic.db.profile.isCritLogFrameShown
                    end,
                },
                critLogLocked = {
                    name = L["options_lock_crit_log"],
                    desc = L["options_lock_crit_log_desc"],
                    type = "toggle",
                    order = 1.5,
                    set = function(_, newVal)
                        Critmatic.db.profile.critLogWidgetPos.lock = newVal
                    end,
                    get = function()
                        return Critmatic.db.profile.critLogWidgetPos.lock
                    end,
                },
                minimapIcon = {
                    name = L["options_show_minimap_icon"],
                    desc = L["options_show_minimap_icon_desc"],
                    type = "toggle",
                    order = 1.75,
                    set = function(_, newVal)
                        Critmatic.SetMinimapHidden(not newVal)
                    end,
                    get = function()
                        return not (Critmatic.db.profile.minimap and Critmatic.db.profile.minimap.hide)
                    end,
                },
            },
            support = {
                discordURL = "https://discord.gg/34JJyrnGGC",
                coffeeURL = "https://buymeacoffee.com/infiniteloopalchemist",
                coffeeIcon = "Interface\\AddOns\\CritMatic\\Media\\Textures\\bmc-logo.tga",
            },
            nav = {
                iconRoot = "Interface\\AddOns\\CritMatic\\Media\\Textures\\",
                factionIcons = false,
                extraLinks = {
                    { label = L["options_x_link"] or "Follow on X", url = "https://x.com/infiniteloopalc", icon = "x-logo.tga" },
                },
            },
        })

        args.alertFont_Tab = Settings:BuildAlertPage({
            order = 2,
            bind = { table = alertStrings },
            notificationTypes = {
                {
                    key = "critAlertNotificationFormat",
                    title = L["options_alert_chat_notification_format_crit"],
                    desc = L["options_alert_chat_notification_format_crit_desc"],
                    defaultFormat = "New %s Crit: %d!",
                    preview = preview("critAlertNotificationFormat", true, true, "soundCrit"),
                },
                {
                    key = "hitAlertNotificationFormat",
                    title = L["options_alert_chat_notification_format_hit"],
                    desc = L["options_alert_chat_notification_format_hit_desc"],
                    defaultFormat = "New %s Hit: %d!",
                    preview = preview("hitAlertNotificationFormat", true, false, "soundHit"),
                },
                {
                    key = "critHealAlertNotificationFormat",
                    title = L["options_alert_chat_notification_format_crit_heal"],
                    desc = L["options_alert_chat_notification_format_crit_heal_desc"],
                    defaultFormat = "New %s Crit Heal: %d!",
                    preview = preview("critHealAlertNotificationFormat", false, true, "soundCritHeal"),
                },
                {
                    key = "healAlertNotificationFormat",
                    title = L["options_alert_chat_notification_format_heal"],
                    desc = L["options_alert_chat_notification_format_heal_desc"],
                    defaultFormat = "New %s Heal: %d!",
                    preview = preview("healAlertNotificationFormat", false, false, "soundHeal"),
                },
            },
            globals = Critmatic:AlertGeneralFragment(),
            font = Critmatic:AlertFontFragment(),
            messageExtras = Critmatic:AlertMessageExtras(),
            bounce = {
                get = function()
                    return Critmatic.db.profile.alertNotificationFormat.global.bounceStyle or "legacy"
                end,
                set = function(_, val)
                    Critmatic.db.profile.alertNotificationFormat.global.bounceStyle = val
                end,
            },
            position = {
                order = 10,
                get = function()
                    return Critmatic.db.profile.alertNotificationFormat.position.xPos,
                        Critmatic.db.profile.alertNotificationFormat.position.yPos
                end,
                set = function(x, y)
                    Critmatic.db.profile.alertNotificationFormat.position.xPos = x
                    Critmatic.db.profile.alertNotificationFormat.position.yPos = y
                end,
                default = function() return 50, 70 end,
                font = function()
                    local LSM = LibStub("LibSharedMedia-3.0", true)
                    local fs = Critmatic.db.profile.fontSettings
                    local path = (LSM and LSM:Fetch("font", fs.font)) or STANDARD_TEXT_FONT
                    return path, fs.fontSize, fs.fontOutline
                end,
                color = function()
                    return unpack(Critmatic.db.profile.fontSettings.fontColorCrit)
                end,
                close = function()
                    local frame = AceConfigDialog and AceConfigDialog.OpenFrames
                        and AceConfigDialog.OpenFrames["CritMaticOptions"]
                    if frame then frame:Hide() end
                end,
                reopen = function()
                    local frame = AceConfigDialog and AceConfigDialog.OpenFrames
                        and AceConfigDialog.OpenFrames["CritMaticOptions"]
                    if frame then frame:Show() end
                end,
            },
        })

        args.sound_tab = Settings:BuildSoundPage({
            name = L["options_sound_settings"],
            order = 3,
            bind = {
                table = function() return Critmatic.db.profile.soundSettings end,
                defaults = function() return Critmatic.db.defaults.profile.soundSettings end,
            },
            slots = {
                { key = "damageCrit", label = L["options_sound_crit"] },
                { key = "damageNormal", label = L["options_sound_hit"] },
                { key = "healCrit", label = L["options_sound_crit_heal"] },
                { key = "healNormal", label = L["options_sound_heal"] },
            },
            muteToggle = {
                key = "muteAllSounds",
                name = L["options_sound_mute_all"],
                desc = L["options_sound_mute_all_desc"],
            },
        })

        args.social_tab = Settings:BuildSocialPage({
            name = L["options_social"],
            order = 4,
            bind = { table = function() return Critmatic.db.profile.social end },
            channels = {
                { key = "canSendCritsToParty", name = L["options_social_send_crits_toParty"], desc = L["options_social_send_crits_toParty_desc"] },
                { key = "canSendCritsToRaid", name = L["options_social_send_crits_toRaid"], desc = L["options_social_send_crits_toRaid_desc"] },
                { key = "canSendCritsToGuild", name = L["options_social_send_crits_toGuild"], desc = L["options_social_send_crits_toGuild_desc"] },
                { key = "canSendCritsToBattleGrounds", name = L["options_social_send_crits_toBattleGrounds"], desc = L["options_social_send_crits_toBattleGrounds_desc"] },
            },
        })

        args.changeLog_tab = Settings:BuildChangeLogPage({
            name = L["options_change_log"],
            order = 5,
            profile = function() return Critmatic.db.profile.changeLogPopUp end,
        })
    end

    args.ignoredSpells_tab = Critmatic:IgnoredSpellsTab_Initialize()

    return {
        name = "CritMatic Options",
        type = "group",
        args = args,
    }
end

AceConfig:RegisterOptionsTable("CritMaticOptions", Critmatic:CreateOptionsTable())

local blizzPanel = AceConfigDialog:AddToBlizOptions("CritMaticOptions", "CritMatic")

if type(InterfaceOptionsList_DisplayPanel) == "function" then
    hooksecurefunc("InterfaceOptionsList_DisplayPanel", function(frame)
        if frame == blizzPanel then
        end
    end)
end
