local notification_constructor = Critmatic:NewModule("notification_constructor")

local L = LibStub("AceLocale-3.0"):GetLocale("CritMatic")

function ResetAlertSettingsToDefault()
    Critmatic.db.profile.alertNotificationFormat.strings = CopyTable(Critmatic.db.defaults.profile.alertNotificationFormat.strings)
    Critmatic.db.profile.alertNotificationFormat.position = CopyTable(Critmatic.db.defaults.profile.alertNotificationFormat.position)
end
function ResetFontSettingsToDefault()
    Critmatic.db.profile.fontSettings = CopyTable(Critmatic.db.defaults.profile.fontSettings)
end
function notification_constructor:OnInitialize()

end

function notification_constructor:OnEnable()
end

function notification_constructor:formatConstructor(message, isDamage, isCrit, sound_string)
    local LSM = LibStub("LibSharedMedia-3.0")
    -- Define a local table with 15 different spell names
    local spellNames = {}
    local r, g, b
    if isDamage then
        spellNames = {
            "Fireball",
            "Shadow Bolt",
            "Chain Lightning",
            "Death Coil",
            "Starfire",
            "Eviscerate",
            "Mind Blast",
            "Heroic Strike",
            "Arcane Shot",
            "Blade Flurry",
            "Judgment",
            "Shadowflame",
            "Stormstrike",
            "Mutilate",
            "Hammer of Wrath"
        }
    else
        spellNames = {
            "Circle of Healing",
            "Rejuvenation",
            "Lay on Hands",
            "Renew",
            "Riptide",
            "Holy Light",
            "Lifebloom",
            "Healing Rain",
            "Soothing Mist",
            "Penance",
            "Wild Growth",
            "Prayer of Healing"
        }
    end

    local soundCrit = LSM:Fetch("sound", Critmatic.db.profile.soundSettings.damageCrit)
    local soundHit = LSM:Fetch("sound", Critmatic.db.profile.soundSettings.damageNormal)
    local soundCritHeal = LSM:Fetch("sound", Critmatic.db.profile.soundSettings.healCrit)
    local soundHeal = LSM:Fetch("sound", Critmatic.db.profile.soundSettings.healNormal)

    -- Select a random spell name
    local spellName = spellNames[math.random(#spellNames)]
    local string = ""
    -- Generate a random number between 3000 and 8000 for amount
    local amount = math.random(500, 8000)
    if Critmatic.db.profile.alertNotificationFormat.global.isUpper then
        -- If spellName does not end with 'Heal', use the format string as is
        string = string.upper(string.format(message, spellName, amount))
    else
        string = string.format(message, spellName,
                amount)

    end

    if isCrit then
        r, g, b = unpack(Critmatic.db.profile.fontSettings.fontColorCrit)
    else
        r, g, b = unpack(Critmatic.db.profile.fontSettings.fontColor)
    end
    Critmatic.MessageFrame:CreateMessage(string, r, g, b)
    if not Critmatic.db.profile.soundSettings.muteAllSounds then

        if sound_string == "soundCrit" then
            PlaySoundFile(soundCrit)
        elseif sound_string == "soundHit" then
            PlaySoundFile(soundHit)
        elseif sound_string == "soundCritHeal" then
            PlaySoundFile(soundCritHeal)
        elseif sound_string == "soundHeal" then
            PlaySoundFile(soundHeal)
        end
    end
end

function Critmatic:AlertGeneralFragment()
    local generalWidth = "300"
    return {
        maxMessages = {
            name = "Max Messages",
            desc = "Set the maximum number of messages",
            type = "range",
            min = 2,
            max = 8,
            step = 1,
            order = 1,
            width = generalWidth,
            get = function()
                return Critmatic.db.profile.alertNotificationFormat.global.maxMessages
            end,
            set = function(_, newVal)
                Critmatic.db.profile.alertNotificationFormat.global.maxMessages = newVal
            end,
        },
        resetMaxMessages = {
            name = "Reset Max Messages",
            type = "execute",
            order = 2,
            width = generalWidth,
            func = function()
                Critmatic.db.profile.alertNotificationFormat.global.maxMessages = 4
            end,
        },
        fadeTime = {
            name = "Fade Time",
            desc = "Set the fade time",
            type = "range",
            min = 0,
            max = 10,
            step = 0.1,
            order = 5,
            width = generalWidth,
            get = function()
                return Critmatic.db.profile.alertNotificationFormat.global.fadeTime
            end,
            set = function(_, newVal)
                Critmatic.db.profile.alertNotificationFormat.global.fadeTime = newVal
            end,
        },
        resetFadeTime = {
            name = "Reset Fade Time",
            type = "execute",
            order = 6,
            width = generalWidth,
            func = function()
                Critmatic.db.profile.alertNotificationFormat.global.fadeTime = 0.5
            end,
        },
        resetStartDelay = {
            name = "Reset Start Delay",
            type = "execute",
            order = 4,
            width = generalWidth,
            func = function()
                Critmatic.db.profile.alertNotificationFormat.global.startDelay = 7.5
            end,
        },
        resetCountUpDuration = {
            name = "Reset Animation Length",
            type = "execute",
            order = 8,
            width = generalWidth,
            func = function()
                Critmatic.db.profile.alertNotificationFormat.global.countUpDuration = 3
            end,
        },
        resetCountUpHold = {
            name = "Reset Stay After Animation",
            type = "execute",
            order = 10,
            width = generalWidth,
            func = function()
                Critmatic.db.profile.alertNotificationFormat.global.countUpHold = 3
            end,
        },
        resetPosition = {
            name = "Reset Position",
            type = "execute",
            order = 13,
            width = generalWidth,
            func = function()
                Critmatic.db.profile.alertNotificationFormat.position.xPos = Critmatic.db.defaults.profile.alertNotificationFormat.position.xPos
                Critmatic.db.profile.alertNotificationFormat.position.yPos = Critmatic.db.defaults.profile.alertNotificationFormat.position.yPos
            end,
        },
    }
end

function Critmatic:AlertMessageExtras()
    return {
        isUpper = {
            name = L["options_alert_chat_notification_format_upper"],
            desc = L["options_alert_notification_format_upper_desc"],
            type = "toggle",
            order = 2,
            set = function(_, newVal)
                Critmatic.db.profile.alertNotificationFormat.global.isUpper = newVal
            end,
            get = function()
                return Critmatic.db.profile.alertNotificationFormat.global.isUpper
            end,
        },
        resetAlertSettings = {
            name = L["options_alert_notification_format_reset"],
            desc = L["options_alert_notification_format_reset_desc"],
            width = "full",
            type = "execute",
            func = ResetAlertSettingsToDefault,
            confirm = true,
            confirmText = L["options_alert_notification_format_reset_confirm"],
            order = 100,
        },
    }
end

function Critmatic:AlertFontFragment()
    local LSM = LibStub("LibSharedMedia-3.0")
    local args = {
        font = {
            name = L["options_alert_font"],
            type = "select",
            desc = L["options_alert_font_desc"],
            dialogControl = "LSM30_Font",
            values = LSM:HashTable("font"),
            width = "full",
            order = 1,
            get = function()
                return Critmatic.db.profile.fontSettings.font
            end,
            set = function(_, newVal)
                Critmatic.db.profile.fontSettings.font = newVal
            end,
        },
        fontSize = {
            name = L["options_alert_font_size"],
            type = "range",
            min = 8,
            max = 32,
            step = 1,
            order = 2,
            width = "full",
            get = function()
                return Critmatic.db.profile.fontSettings.fontSize
            end,
            set = function(_, newVal)
                Critmatic.db.profile.fontSettings.fontSize = newVal
            end,
        },
        fontColorCrit = {
            type = "color",
            name = L["options_alert_font_color_crit"],
            desc = L["options_alert_font_color_crit_desc"],
            order = 3,
            hasAlpha = false,
            width = "normal",
            get = function()
                local r, g, b = unpack(Critmatic.db.profile.fontSettings.fontColorCrit)
                return r, g, b
            end,
            set = function(_, r, g, b)
                Critmatic.db.profile.fontSettings.fontColorCrit = { r, g, b }
            end,
        },
        fontColor = {
            type = "color",
            name = L["options_alert_font_c_non_crit"],
            desc = L["options_alert_font_c_non_crit_desc"],
            order = 4,
            width = "normal",
            hasAlpha = false,
            get = function()
                local r, g, b = unpack(Critmatic.db.profile.fontSettings.fontColor)
                return r, g, b
            end,
            set = function(_, r, g, b)
                Critmatic.db.profile.fontSettings.fontColor = { r, g, b }
            end,
        },
        fontOutline = {
            name = L["options_alert_font_outline"],
            type = "select",
            values = {
                ["NONE"] = L["options_alert_font_none"],
                ["OUTLINE"] = L["options_alert_font_outline"],
                ["OUTLINEMONOCHROME"] = L["options_alert_font_outline_mono"],
                ["THICKOUTLINE"] = L["options_alert_font_outline_thick"],
                ["THICKOUTLINEMONOCHROME"] = L["options_alert_font_outline_thick_mono"],
            },
            width = "full",
            order = 5,
            get = function()
                return Critmatic.db.profile.fontSettings.fontOutline
            end,
            set = function(_, newVal)
                Critmatic.db.profile.fontSettings.fontOutline = newVal
            end,
        },
        fontShadowSizeX = {
            type = 'range',
            name = L["options_alert_font_shadow_x"],
            desc = L["options_alert_font_shadow_x_desc"],
            min = -10,
            max = 10,
            step = 1,
            order = 6,
            width = "normal",
            get = function()
                return Critmatic.db.profile.fontSettings.fontShadowSize[1]
            end,
            set = function(_, value)
                Critmatic.db.profile.fontSettings.fontShadowSize[1] = value
            end,
        },
        fontShadowSizeY = {
            type = 'range',
            name = L["options_alert_font_shadow_y"],
            desc = L["options_alert_font_shadow_y_desc"],
            min = -10,
            max = 10,
            step = 1,
            order = 7,
            width = "normal",
            get = function()
                return Critmatic.db.profile.fontSettings.fontShadowSize[2]
            end,
            set = function(_, value)
                Critmatic.db.profile.fontSettings.fontShadowSize[2] = value
            end,
        },
        fontShadowColor = {
            type = 'color',
            name = L["options_alert_font_shadow_color"],
            desc = L["options_alert_font_shadow_color_desc"],
            hasAlpha = false,
            order = 8,
            get = function()
                return unpack(Critmatic.db.profile.fontSettings.fontShadowColor)
            end,
            set = function(_, r, g, b)
                Critmatic.db.profile.fontSettings.fontShadowColor = { r, g, b }
            end,
        },
        resetFontSettings = {
            name = L["options_alert_font_reset"],
            desc = L["options_alert_font_reset_desc"],
            width = "full",
            type = "execute",
            func = ResetFontSettingsToDefault,
            confirm = true,
            confirmText = L["options_alert_font_reset_confirm"],
            order = 9,
        },
    }
    local LMSettings = LibStub("LibMatic-Settings-1.0", true)
    if LMSettings and LMSettings.BuildShadowControls then
        local sc = LMSettings:BuildShadowControls({
            order = 8.5,
            width = "full",
            strength = {
                get = function() return Critmatic.db.profile.fontSettings.shadowStrength end,
                set = function(_, v) Critmatic.db.profile.fontSettings.shadowStrength = v end,
            },
            names = {
                strength = L["options_alert_font_shadow_strength"],
                strengthDesc = L["options_alert_font_shadow_strength_desc"],
            },
        })
        args.shadowStrength = sc.strength
    end
    return args
end
