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

local function colorGroup(tbl, key, name, desc)
    return {
        key = key,
        name = name,
        desc = desc,
        get = function() return unpack(tbl().colors[key]) end,
        set = function(_, r, g, b) tbl().colors[key] = { r, g, b } end,
    }
end

local function compactStyleToggle(field, order, name, desc)
    return {
        name = name,
        desc = desc,
        type = "toggle",
        order = order,
        set = function(_, newVal)
            local broker = Critmatic.db.profile.brokerSettings
            if newVal then
                broker.compactNumbers = false
                broker.compactInitials = false
                broker.compactLabels = false
                broker[field] = true
            else
                broker[field] = false
            end
            if Critmatic.UpdateBroker then Critmatic.UpdateBroker() end
        end,
        get = function()
            return Critmatic.db.profile.brokerSettings[field]
        end,
    }
end

function Critmatic:TooltipAppearanceFragment()
    local function S() return Critmatic.db.profile.tooltipFontSettings end
    return {
        name = L["options_tab_tooltip"],
        order = 2.5,
        font = {
            get = function() return S().font end,
            set = function(_, v) S().font = v end,
        },
        fontSize = {
            get = function() return S().fontSize end,
            set = function(_, v) S().fontSize = v end,
        },
        fontOutline = {
            get = function() return S().fontOutline end,
            set = function(_, v) S().fontOutline = v end,
        },
        colorGroups = {
            colorGroup(S, "spellName", L["appearance_color_spell_name"], L["appearance_color_spell_name_desc"]),
            colorGroup(S, "crit",      L["appearance_color_crit"],       L["appearance_color_crit_desc"]),
            colorGroup(S, "hit",       L["appearance_color_hit"],        L["appearance_color_hit_desc"]),
            colorGroup(S, "critHeal",  L["appearance_color_crit_heal"],  L["appearance_color_crit_heal_desc"]),
            colorGroup(S, "heal",      L["appearance_color_heal"],       L["appearance_color_heal_desc"]),
        },
        sort = {
            get = function() return S().sortMode end,
            set = function(_, v) S().sortMode = v end,
        },
        group = {
            get = function() return S().groupByType end,
            set = function(_, v) S().groupByType = v end,
        },
        groupOrder = {
            get = function() return S().groupOrder or "damage" end,
            set = function(_, v) S().groupOrder = v end,
        },
        names = {
            font            = L["appearance_font"],
            fontSize        = L["appearance_font_size"],
            fontOutline     = L["appearance_font_outline"],
            outlineNone     = L["options_alert_font_none"],
            outline         = L["options_alert_font_outline"],
            outlineMono     = L["options_alert_font_outline_mono"],
            outlineThick    = L["options_alert_font_outline_thick"],
            outlineThickMono = L["options_alert_font_outline_thick_mono"],
            sort            = L["appearance_sort"],
            sortRecent      = L["appearance_sort_recent"],
            sortHighest     = L["appearance_sort_highest"],
            group           = L["appearance_group"],
            groupDesc       = L["appearance_group_desc"],
            groupOrder       = L["appearance_group_order"],
            groupOrderDesc   = L["appearance_group_order_desc"],
            groupOrderDamage  = L["appearance_group_order_damage"],
            groupOrderHealing = L["appearance_group_order_healing"],
        },
    }
end

function Critmatic:CritLogAppearanceFragment()
    local function S() return Critmatic.db.profile.critLogFontSettings end
    return {
        name = L["options_tab_critlog"],
        order = 2.6,
        font = {
            get = function() return S().font end,
            set = function(_, v) S().font = v end,
        },
        fontSize = {
            get = function() return S().fontSize end,
            set = function(_, v) S().fontSize = v end,
        },
        fontOutline = {
            get = function() return S().fontOutline end,
            set = function(_, v) S().fontOutline = v end,
        },
        colorGroups = {
            colorGroup(S, "spellName", L["appearance_color_spell_name"], L["appearance_color_spell_name_desc"]),
            colorGroup(S, "crit",      L["appearance_color_crit"],       L["appearance_color_crit_desc"]),
            colorGroup(S, "hit",       L["appearance_color_hit"],        L["appearance_color_hit_desc"]),
            colorGroup(S, "critHeal",  L["appearance_color_crit_heal"],  L["appearance_color_crit_heal_desc"]),
            colorGroup(S, "heal",      L["appearance_color_heal"],       L["appearance_color_heal_desc"]),
        },
        sort = {
            get = function() return S().sortMode end,
            set = function(_, v) S().sortMode = v end,
        },
        group = {
            get = function() return S().groupByType end,
            set = function(_, v) S().groupByType = v end,
        },
        groupOrder = {
            get = function() return S().groupOrder or "damage" end,
            set = function(_, v) S().groupOrder = v end,
        },
        names = {
            font            = L["appearance_font"],
            fontSize        = L["appearance_font_size"],
            fontOutline     = L["appearance_font_outline"],
            outlineNone     = L["options_alert_font_none"],
            outline         = L["options_alert_font_outline"],
            outlineMono     = L["options_alert_font_outline_mono"],
            outlineThick    = L["options_alert_font_outline_thick"],
            outlineThickMono = L["options_alert_font_outline_thick_mono"],
            sort            = L["appearance_sort"],
            sortRecent      = L["appearance_sort_recent"],
            sortHighest     = L["appearance_sort_highest"],
            group           = L["appearance_group"],
            groupDesc       = L["appearance_group_desc"],
            groupOrder       = L["appearance_group_order"],
            groupOrderDesc   = L["appearance_group_order_desc"],
            groupOrderDamage  = L["appearance_group_order_damage"],
            groupOrderHealing = L["appearance_group_order_healing"],
        },
    }
end

function Critmatic:BrokerAppearanceFragment()
    local function S() return Critmatic.db.profile.brokerColorSettings end
    local function T() return Critmatic.db.profile.tooltipFontSettings end
    return {
        name = L["options_tab_broker"],
        order = 2.7,
        font = {
            get = function() return T().font end,
            set = function(_, v) T().font = v end,
        },
        fontSize = {
            get = function() return T().fontSize end,
            set = function(_, v) T().fontSize = v end,
        },
        fontOutline = {
            get = function() return T().fontOutline end,
            set = function(_, v) T().fontOutline = v end,
        },
        names = {
            font            = L["appearance_font"],
            fontSize        = L["appearance_font_size"],
            fontOutline     = L["appearance_font_outline"],
            outlineNone     = L["options_alert_font_none"],
            outline         = L["options_alert_font_outline"],
            outlineMono     = L["options_alert_font_outline_mono"],
            outlineThick    = L["options_alert_font_outline_thick"],
            outlineThickMono = L["options_alert_font_outline_thick_mono"],
        },
        colorGroups = {
            colorGroup(S, "crit",  L["appearance_color_crit"],  L["appearance_color_crit_desc"]),
            colorGroup(S, "value", L["appearance_color_value"], L["appearance_color_value_desc"]),
        },
        extra = {
            brokerHitFirst = {
                name = L["options_broker_hit_first"],
                desc = L["options_broker_hit_first_desc"],
                type = "toggle",
                order = 40,
                set = function(_, newVal)
                    Critmatic.db.profile.brokerSettings.hitFirst = newVal and true or false
                    if Critmatic.UpdateBroker then Critmatic.UpdateBroker() end
                end,
                get = function()
                    return Critmatic.db.profile.brokerSettings.hitFirst
                end,
            },
            brokerCompactNumbers = compactStyleToggle("compactNumbers", 41, L["options_broker_compact_numbers"], L["options_broker_compact_numbers_desc"]),
            brokerCompactInitials = compactStyleToggle("compactInitials", 42, L["options_broker_compact_initials"], L["options_broker_compact_initials_desc"]),
            brokerCompactLabels = compactStyleToggle("compactLabels", 43, L["options_broker_compact_labels"], L["options_broker_compact_labels_desc"]),
            brokerShowFullLog = {
                name = L["options_broker_show_full_log"],
                desc = L["options_broker_show_full_log_desc"],
                type = "toggle",
                order = 44,
                set = function(_, newVal)
                    Critmatic.db.profile.brokerSettings.showFullLog = newVal and true or false
                end,
                get = function()
                    return Critmatic.db.profile.brokerSettings.showFullLog ~= false
                end,
            },
            brokerTooltipCap = {
                name = L["options_broker_tooltip_cap"],
                desc = L["options_broker_tooltip_cap_desc"],
                type = "range",
                order = 45,
                min = 5,
                max = 50,
                step = 1,
                set = function(_, newVal)
                    Critmatic.db.profile.brokerSettings.tooltipSpellCap = newVal
                end,
                get = function()
                    return Critmatic.db.profile.brokerSettings.tooltipSpellCap or 15
                end,
            },
        },
    }
end
