local TXUI, F, E, I, V, P, G = unpack(select(2, ...))
local PF = TXUI:GetModule("Profiles")

local next = next
local ipairs = ipairs
local unpack = unpack

local function customTextSize(args)
    local ret = {}
    for _, v in ipairs(args) do
        local name, font, size, outline = unpack(v)
        ret[name] = {
            font = F.GetFontOverride(font),
            size = F.FontScale(size),
            fontOutline = F.GetFontStyleOverride(font, outline),
        }
    end
    return ret
end

function PF:ElvUIFont()
    F.Table.Crush(E.db, {
        -- General
        general = {
            font = F.GetFontOverride(I.Fonts.Primary),
            fontSize = F.FontScale(14, 13),
            fontStyle = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),

            itemLevel = {
                itemLevelFont = F.GetFontOverride(I.Fonts.PrimaryBold),
                itemLevelFontSize = 11,
                itemLevelFontOutline = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),
            },

            altPowerBar = {
                font = F.GetFontOverride(I.Fonts.Title),
                fontSize = F.FontScale(18),
                fontOutline = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
            },

            minimap = {
                locationFont = F.GetFontOverride(I.Fonts.Title),
                locationFontSize = F.FontScale(22),
                locationFontOutline = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),

                icons = {
                    queueStatus = {
                        font = F.GetFontOverride(I.Fonts.Primary),
                        fontSize = F.FontScale(12),
                        fontOutline = F.GetFontStyleOverride(I.Fonts.Primary, "OUTLINE"),
                    },
                },
            },

            lootRoll = {
                nameFont = F.GetFontOverride(I.Fonts.Primary),
                nameFontSize = F.FontScale(14),
                nameFontOutline = F.GetFontStyleOverride(I.Fonts.Primary, "OUTLINE"),
            },

            totems = {
                font = F.GetFontOverride(I.Fonts.Primary),
                fontSize = F.FontScale(14),
                fontOutline = F.GetFontStyleOverride(I.Fonts.Primary, "OUTLINE"),
            },
        },

        -- Bags
        bags = {
            itemLevelFont = F.GetFontOverride(I.Fonts.Number),
            itemLevelFontSize = F.FontScale(22),
            itemLevelFontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),

            itemInfoFont = F.GetFontOverride(I.Fonts.Number),
            itemInfoFontSize = F.FontScale(26),
            itemInfoFontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),

            countFont = F.GetFontOverride(I.Fonts.Number),
            countFontSize = F.FontScale(26),
            countFontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),

            cooldown = {
                fonts = {
                    enable = true,
                    font = F.GetFontOverride(I.Fonts.Number),
                    fontSize = F.FontScale(20),
                    fontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),
                },
            },

            bagBar = {
                font = F.GetFontOverride(I.Fonts.Primary),
                fontSize = F.FontScale(14),
                fontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),
            },
        },

        -- Chat
        chat = {
            font = F.GetFontOverride(I.Fonts.Primary),
            fontOutline = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),

            tabFont = F.GetFontOverride(I.Fonts.Title),
            tabFontSize = F.FontScale(14, 13),
            tabFontOutline = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
        },

        -- Auras
        auras = {
            -- Buffs
            buffs = {
                countFont = F.GetFontOverride(I.Fonts.Number),
                countFontSize = F.FontScale(26),
                countFontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),

                timeFont = F.GetFontOverride(I.Fonts.Title),
                timeFontSize = F.FontScale(22),
                timeFontOutline = F.GetFontStyleOverride(I.Fonts.Number, "NONE"),
            },

            -- Debuffs
            debuffs = {
                countFont = F.GetFontOverride(I.Fonts.Number),
                countFontSize = F.FontScale(26),
                countFontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),

                timeFont = F.GetFontOverride(I.Fonts.Title),
                timeFontSize = F.FontScale(22),
                timeFontOutline = F.GetFontStyleOverride(I.Fonts.Number, "NONE"),
            },
        },

        unitframe = {
            font = F.GetFontOverride(I.Fonts.Title),
            fontSize = F.FontScale(20),
            fontOutline = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),

            cooldown = {
                fonts = {
                    enable = true,
                    font = F.GetFontOverride(I.Fonts.Number),
                    fontSize = F.FontScale(28),
                    fontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),
                },
            },

            units = {
                player = {
                    customTexts = customTextSize {
                        { "!Name", I.Fonts.Title, 26, "NONE" },
                        { "!Health", I.Fonts.Number, 22, "NONE" },
                    },

                    buffs = {
                        countFont = F.GetFontOverride(I.Fonts.Title),
                        countFontSize = F.FontScale(22),
                    },

                    debuffs = {
                        countFont = F.GetFontOverride(I.Fonts.Title),
                        countFontSize = F.FontScale(22),
                    },

                    castbar = {
                        customTextFont = {
                            enable = true,
                            font = F.GetFontOverride(I.Fonts.Title),
                            fontSize = F.FontScale(22),
                            fontStyle = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                        },

                        customTimeFont = {
                            enable = true,
                            font = F.GetFontOverride(I.Fonts.Title),
                            fontSize = F.FontScale(22),
                            fontStyle = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                        },
                    },
                },

                target = {
                    customTexts = customTextSize {
                        { "!Name", I.Fonts.Title, 26, "NONE" },
                        { "!Health", I.Fonts.Number, 22, "NONE" },
                    },

                    buffs = {
                        countFont = F.GetFontOverride(I.Fonts.Title),
                        countFontSize = F.FontScale(22),
                    },

                    debuffs = {
                        countFont = F.GetFontOverride(I.Fonts.Title),
                        countFontSize = F.FontScale(22),
                    },

                    castbar = {
                        customTextFont = {
                            enable = true,
                            font = F.GetFontOverride(I.Fonts.Title),
                            fontSize = F.FontScale(22),
                            fontStyle = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                        },

                        customTimeFont = {
                            enable = true,
                            font = F.GetFontOverride(I.Fonts.Title),
                            fontSize = F.FontScale(22),
                            fontStyle = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                        },
                    },
                },

                pet = {
                    customTexts = customTextSize { { "!Name", I.Fonts.Title, 16, "NONE" } },
                },

                targettarget = {
                    customTexts = customTextSize { { "!Name", I.Fonts.Title, 16, "NONE" } },
                },

                focus = {
                    customTexts = customTextSize {
                        { "!Name", I.Fonts.Title, 26, "NONE" },
                        { "!Health", I.Fonts.Number, 22, "NONE" },
                    },

                    buffs = {
                        countFont = F.GetFontOverride(I.Fonts.Title),
                        countFontSize = F.FontScale(22),
                    },

                    debuffs = {
                        countFont = F.GetFontOverride(I.Fonts.Title),
                        countFontSize = F.FontScale(22),
                    },

                    castbar = {
                        customTextFont = {
                            enable = true,
                            font = F.GetFontOverride(I.Fonts.Title),
                            fontSize = F.FontScale(22),
                            fontStyle = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                        },

                        customTimeFont = {
                            enable = true,
                            font = F.GetFontOverride(I.Fonts.Title),
                            fontSize = F.FontScale(22),
                            fontStyle = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                        },
                    },
                },

                party = F.Table.Join(
                    {
                        customTexts = customTextSize {
                            { "!Name", I.Fonts.Title, 26, "NONE" },
                            { "!Health", I.Fonts.Number, 24, "NONE" },
                        },

                        buffs = {
                            countFont = F.GetFontOverride(I.Fonts.Number),
                            countFontSize = F.FontScale(18),
                        },

                        debuffs = {
                            countFont = F.GetFontOverride(I.Fonts.Number),
                            countFontSize = F.FontScale(18),
                        },

                        rdebuffs = {
                            font = F.GetFontOverride(I.Fonts.Number),
                            fontSize = F.FontScale(18),
                            fontOutline = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                        },
                    },
                    F.Table.If(E.db.TXUI.installer.layout == I.Enum.Layouts.HEALER, {
                        customTexts = customTextSize { { "!Name", I.Fonts.Title, 26, "NONE" }, { "!Health", I.Fonts.Number, 32, "NONE" } },
                    })
                ),

                raid1 = {
                    customTexts = customTextSize { { "!Name", I.Fonts.Title, 16, "OUTLINE" } },

                    rdebuffs = {
                        font = F.GetFontOverride(I.Fonts.Title),
                        fontSize = F.FontScale(16),
                        fontOutline = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                    },
                },

                raid2 = {
                    customTexts = customTextSize { { "!Name", I.Fonts.Title, 16, "OUTLINE" } },

                    rdebuffs = {
                        font = F.GetFontOverride(I.Fonts.Title),
                        fontSize = F.FontScale(16),
                        fontOutline = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                    },
                },

                raid3 = {
                    customTexts = customTextSize { { "!Name", I.Fonts.Title, 16, "OUTLINE" } },

                    rdebuffs = {
                        font = F.GetFontOverride(I.Fonts.Title),
                        fontSize = F.FontScale(16),
                        fontOutline = F.GetFontStyleOverride(I.Fonts.Title, "NONE"),
                    },
                },

                arena = {
                    customTexts = customTextSize {
                        { "!Health", I.Fonts.Number, 20, "NONE" },
                        { "!Name", I.Fonts.Title, 24, "NONE" },
                        { "!Power", I.Fonts.Number, 20, "OUTLINE" },
                    },

                    buffs = {
                        countFont = F.GetFontOverride(I.Fonts.Number),
                        countFontSize = F.FontScale(22),
                    },

                    debuffs = {
                        countFont = F.GetFontOverride(I.Fonts.Number),
                        countFontSize = F.FontScale(22),
                    },
                },

                boss = {
                    customTexts = customTextSize {
                        { "!Health", I.Fonts.Number, 24, "NONE" },
                        { "!Name", I.Fonts.Title, 24, "NONE" },
                        { "!Power", I.Fonts.Number, 20, "OUTLINE" },
                    },

                    buffs = {
                        countFont = F.GetFontOverride(I.Fonts.Number),
                        countFontSize = F.FontScale(22),
                    },

                    debuffs = {
                        countFont = F.GetFontOverride(I.Fonts.Number),
                        countFontSize = F.FontScale(22),
                    },
                },
            },
        },

        -- Tooltip
        tooltip = {
            font = F.GetFontOverride(I.Fonts.Primary),
            fontOutline = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),
            textFontSize = F.FontScale(14), -- is fontSize (has old name)

            headerFont = F.GetFontOverride(I.Fonts.Primary),
            headerFontSize = F.FontScale(16),
            headerFontOutline = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),

            smallTextFontSize = F.FontScale(14),

            healthBar = {
                font = F.GetFontOverride(I.Fonts.Title),
                fontSize = F.FontScale(18),
                fontOutline = F.GetFontStyleOverride(I.Fonts.Title, "OUTLINE"),
            },
        },

        -- ActionBar
        actionbar = {
            font = F.GetFontOverride(I.Fonts.Title),
            fontOutline = F.GetFontStyleOverride(I.Fonts.Title, "OUTLINE"),
            fontSize = F.FontScale(18),

            cooldown = {
                fonts = {
                    enable = true,
                    font = F.GetFontOverride(I.Fonts.Number),
                    fontSize = F.FontScale(20),
                    fontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),
                },
            },
        },

        -- Cooldowns
        cooldown = {
            fonts = {
                enable = true,
                font = F.GetFontOverride(I.Fonts.Number),
                fontSize = F.FontScale(22),
                fontOutline = F.GetFontStyleOverride(I.Fonts.Number, "OUTLINE"),
            },
        },
    })

    -- ActionBars Main
    for i = 1, 10 do
        F.Table.Crush(E.db.actionbar["bar" .. i], {
            countFont = F.GetFontOverride(I.Fonts.Title),
            countFontOutline = F.GetFontStyleOverride(I.Fonts.Title, "OUTLINE"),
            countFontSize = F.FontScale(19),

            hotkeyFont = F.GetFontOverride(I.Fonts.Title),
            hotkeyFontOutline = F.GetFontStyleOverride(I.Fonts.Title, "OUTLINE"),
            hotkeyFontSize = F.FontScale(19),

            macroFont = F.GetFontOverride(I.Fonts.Title),
            macroFontOutline = F.GetFontStyleOverride(I.Fonts.Title, "OUTLINE"),
            macroFontSize = F.FontScale(14),
        })
    end

    -- ActionBars Additional
    for _, bar in next, { "barPet", "stanceBar", "vehicleExitButton", "extraActionButton" } do
        local ab = {}

        ab.hotkeyFont = F.GetFontOverride(I.Fonts.Title)
        ab.hotkeyFontOutline = F.GetFontStyleOverride(I.Fonts.Title, "OUTLINE")
        ab.hotkeyFontSize = F.FontScale(18)

        if bar == "barPet" then
            ab.countFont = F.GetFontOverride(I.Fonts.Title)
            ab.countFontOutline = F.GetFontStyleOverride(I.Fonts.Title, "OUTLINE")
            ab.countFontSize = F.FontScale(38)
        end

        F.Table.Crush(E.db.actionbar[bar], ab)
    end

    -- WT
    if F.IsAddOnEnabled("ElvUI_WindTools") then
        F.Table.Crush(E.db.WT, {
            social = {
                friendList = {
                    infoFont = {
                        name = F.GetFontOverride(I.Fonts.Primary),
                        size = 12,
                        style = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),
                    },

                    nameFont = {
                        name = F.GetFontOverride(I.Fonts.Primary),
                        size = 14,
                        style = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),
                    },
                },
            },
        })
    end
end

function PF:ElvUIFontPrivates()
    -- ElvUI
    F.Table.Crush(E.private, {
        general = {
            -- General
            chatBubbleFont = F.GetFontOverride(I.Fonts.Primary),
            chatBubbleFontSize = F.FontScale(14),
            chatBubbleFontOutline = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),

            -- Blizzard
            dmgfont = F.GetFontOverride(I.Fonts.BigNumber),
            namefont = F.GetFontOverride(I.Fonts.Primary),
        },
    })

    -- WT
    if F.IsAddOnEnabled("ElvUI_WindTools") then
        F.Table.Crush(E.private.WT, {
            maps = {
                instanceDifficulty = {
                    name = F.GetFontOverride(I.Fonts.Primary),
                    size = F.FontScale(19),
                    style = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),
                },
            },

            quest = {
                objectiveTracker = {
                    header = {
                        name = F.GetFontOverride(I.Fonts.Primary),
                        size = F.FontScale(24),
                        style = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),
                    },

                    title = {
                        name = F.GetFontOverride(I.Fonts.Primary),
                        size = F.FontScale(17),
                        style = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),
                    },

                    info = {
                        name = F.GetFontOverride(I.Fonts.Primary),
                        size = F.FontScale(14),
                        style = F.GetFontStyleOverride(I.Fonts.Primary, "NONE"),
                    },
                },
            },
        })
    end
end

function PF:ApplyFontSizeChange(value)
    -- No update needed
    if E.db.TXUI.addons.fontScale == value then return end

    -- Set font db value
    E.db.TXUI.addons.fontScale = value

    -- Apply font change
    self:ElvUIFont()
    self:ElvUIFontPrivates()

    -- Update ElvUI
    E:UpdateMedia()
    E:StaggeredUpdateAll()
end
