local addonName, addon = ...

local FONT_PATH = "Interface\\AddOns\\compact_utility_panel\\Media\\Fonts\\"

local FONT_LIST = {
    {
        name = "Arial Bold",
        file = FONT_PATH .. "Arial Bold.TTF",
    },
    {
        name = "Arial Narrow",
        file = FONT_PATH .. "Arial Narrow.ttf",
    },
    {
        name = "Avant Garde Naowh",
        file = FONT_PATH .. "Avant Garde Naowh.ttf",
    },
    {
        name = "Barlow Condensed",
        file = FONT_PATH .. "Barlow Condensed.ttf",
    },
    {
        name = "Changa",
        file = FONT_PATH .. "Changa.ttf",
    },
    {
        name = "Cinzel Decorative",
        file = FONT_PATH .. "Cinzel Decorative.ttf",
    },
    {
        name = "Exo",
        file = FONT_PATH .. "Exo.otf",
    },
    {
        name = "Expressway Bold",
        file = FONT_PATH .. "Expressway Bold.ttf",
    },
    {
        name = "Expressway",
        file = FONT_PATH .. "Expressway.TTF",
    },
    {
        name = "FiraSans Bold",
        file = FONT_PATH .. "FiraSans Bold.ttf",
    },
    {
        name = "FiraSans Light",
        file = FONT_PATH .. "FiraSans Light.ttf",
    },
    {
        name = "FiraSans Medium",
        file = FONT_PATH .. "FiraSans Medium.ttf",
    },
    {
        name = "Future X Black",
        file = FONT_PATH .. "Future X Black.otf",
    },
    {
        name = "Gotham Narrow Ultra",
        file = FONT_PATH .. "Gotham Narrow Ultra.otf",
    },
    {
        name = "Gotham Narrow",
        file = FONT_PATH .. "Gotham Narrow.otf",
    },
    {
        name = "Homespun",
        file = FONT_PATH .. "Homespun.ttf",
    },
    {
        name = "KMT Kimberly",
        file = FONT_PATH .. "KMT Kimberly.otf",
    },
    {
        name = "KMT Ninja Naruto",
        file = FONT_PATH .. "KMT Ninja Naruto.ttf",
    },
    {
        name = "Poppins",
        file = FONT_PATH .. "Poppins.ttf",
    },
    {
        name = "Russo One",
        file = FONT_PATH .. "Russo One.ttf",
    },
    {
        name = "Ubuntu",
        file = FONT_PATH .. "Ubuntu.ttf",
    },
}

addon.FONT_LIST = FONT_LIST

function addon:CreateSettings()
    if self.settingsCategory then
        return self.settingsCategory
    end

    if self.InitializeDatabase then
        self:InitializeDatabase()
    end

    local db = CompactUtilityPanelDB

    if not db then
        return
    end

    if not db.fontPath or db.fontPath == "" then
        db.fontPath = "Fonts\\FRIZQT__.TTF"
    end

    if not db.fontSize or tonumber(db.fontSize) <= 0 then
        db.fontSize = 14
    end

    if db.pullCountdown == nil then
        db.pullCountdown = 10
    end

    if db.opacity == nil then
        db.opacity = 0.90
    end

    if db.opacity < 0 then
        db.opacity = 0
    elseif db.opacity > 1 then
        db.opacity = 1
    end

    self.fontPath = db.fontPath
    self.fontSize = tonumber(db.fontSize) or 14

    if not Settings or not Settings.RegisterCanvasLayoutCategory then
        return
    end

    local panel = CreateFrame(
        "Frame",
        nil,
        UIParent
    )

    panel.name = "Compact Utility Panel"

    local scrollFrame = CreateFrame(
        "ScrollFrame",
        nil,
        panel,
        "UIPanelScrollFrameTemplate"
    )

    scrollFrame:SetPoint(
        "TOPLEFT",
        panel,
        "TOPLEFT",
        0,
        0
    )

    scrollFrame:SetPoint(
        "BOTTOMRIGHT",
        panel,
        "BOTTOMRIGHT",
        -28,
        0
    )

    local content = CreateFrame(
        "Frame",
        nil,
        scrollFrame
    )

    content:SetWidth(520)
    content:SetHeight(1100)

    scrollFrame:SetScrollChild(content)

    local title = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormalLarge"
    )

    title:SetPoint(
        "TOPLEFT",
        content,
        "TOPLEFT",
        20,
        -20
    )

    title:SetText("Compact Utility Panel")

    local description = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontHighlight"
    )

    description:SetPoint(
        "TOPLEFT",
        title,
        "BOTTOMLEFT",
        0,
        -10
    )

    description:SetWidth(500)
    description:SetJustifyH("LEFT")
    description:SetText(
        "Configure the Compact Utility Panel."
    )

    local visibilityLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    visibilityLabel:SetPoint(
        "TOPLEFT",
        description,
        "BOTTOMLEFT",
        0,
        -20
    )

    visibilityLabel:SetText("Panel Visibility")

    local visibilityDropdown = CreateFrame(
        "DropdownButton",
        nil,
        content,
        "WowStyle1DropdownTemplate"
    )

    visibilityDropdown:SetPoint(
        "TOPLEFT",
        visibilityLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    visibilityDropdown:SetWidth(250)

    local function GetVisibilityLabel(key)
        for _, option in ipairs(addon.VISIBILITY_OPTIONS or {}) do
            if option.key == key then
                return option.label
            end
        end

        return "Always Visible"
    end

    local function SetSelectedVisibility(option)
        db.visibility = option.key

        if visibilityDropdown.SetText then
            visibilityDropdown:SetText(option.label)
        end

        if addon.UpdateVisibility then
            addon:UpdateVisibility()
        end
    end

    visibilityDropdown:SetupMenu(
        function(dropdown, rootDescription)
            for _, option in ipairs(addon.VISIBILITY_OPTIONS or {}) do
                rootDescription:CreateRadio(
                    option.label,
                    function()
                        return db.visibility == option.key
                    end,
                    function()
                        SetSelectedVisibility(option)
                    end
                )
            end
        end
    )

    if visibilityDropdown.SetText then
        visibilityDropdown:SetText(GetVisibilityLabel(db.visibility))
    end

    local locked = CreateFrame(
        "CheckButton",
        nil,
        content,
        "InterfaceOptionsCheckButtonTemplate"
    )

    locked:SetPoint(
        "TOPLEFT",
        visibilityDropdown,
        "BOTTOMLEFT",
        0,
        -12
    )

    locked.Text:SetText("Lock Panel Position")
    locked:SetChecked(db.locked)

    locked:SetScript(
        "OnClick",
        function(button)
            db.locked = button:GetChecked()
        end
    )

    local scaleLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    scaleLabel:SetPoint(
        "TOPLEFT",
        locked,
        "BOTTOMLEFT",
        0,
        -20
    )

    scaleLabel:SetText("Panel Scale")

    local scale = CreateFrame(
        "Slider",
        nil,
        content,
        "OptionsSliderTemplate"
    )

    scale:SetPoint(
        "TOPLEFT",
        scaleLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    scale:SetWidth(250)
    scale:SetMinMaxValues(0.75, 1.25)
    scale:SetValueStep(0.05)
    scale:SetObeyStepOnDrag(true)

    local currentScale = tonumber(db.scale) or 1
    scale:SetValue(currentScale)

    scale.Low:SetText("0.75")
    scale.High:SetText("1.25")
    scale.Text:SetText(
        string.format("Scale: %.2f", currentScale)
    )

    scale:SetScript(
        "OnValueChanged",
        function(slider, value)
            value = math.floor(value * 100 + 0.5) / 100

            db.scale = value

            slider.Text:SetText(
                string.format("Scale: %.2f", value)
            )

            if addon.panel then
                addon.panel:SetScale(value)
            end
        end
    )

    local fontSizeLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    fontSizeLabel:SetPoint(
        "TOPLEFT",
        scale,
        "BOTTOMLEFT",
        0,
        -22
    )

    fontSizeLabel:SetText("Font Size")

    local fontSize = CreateFrame(
        "Slider",
        nil,
        content,
        "OptionsSliderTemplate"
    )

    fontSize:SetPoint(
        "TOPLEFT",
        fontSizeLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    fontSize:SetWidth(250)
    fontSize:SetMinMaxValues(10, 24)
    fontSize:SetValueStep(1)
    fontSize:SetObeyStepOnDrag(true)

    local currentFontSize = tonumber(db.fontSize) or 14

    fontSize:SetValue(currentFontSize)
    fontSize.Low:SetText("10")
    fontSize.High:SetText("24")

    fontSize.Text:SetText(
        "Font Size: " .. tostring(currentFontSize)
    )

    fontSize:SetScript(
        "OnValueChanged",
        function(slider, value)
            value = math.floor(value + 0.5)

            db.fontSize = value
            addon.fontSize = value

            slider.Text:SetText(
                "Font Size: " .. tostring(value)
            )

            if addon.RefreshFonts then
                addon:RefreshFonts()
            end
        end
    )

    --------------------------------------------------
    -- PULL COUNTDOWN SLIDER
    --------------------------------------------------

    local pullTimerLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    pullTimerLabel:SetPoint(
        "TOPLEFT",
        fontSize,
        "BOTTOMLEFT",
        0,
        -22
    )

    pullTimerLabel:SetText("Pull Countdown (Seconds)")

    local pullTimer = CreateFrame(
        "Slider",
        nil,
        content,
        "OptionsSliderTemplate"
    )

    pullTimer:SetPoint(
        "TOPLEFT",
        pullTimerLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    pullTimer:SetWidth(250)
    pullTimer:SetMinMaxValues(1, 30)
    pullTimer:SetValueStep(1)
    pullTimer:SetObeyStepOnDrag(true)

    local currentPullTimer = tonumber(db.pullCountdown) or 10

    pullTimer:SetValue(currentPullTimer)
    pullTimer.Low:SetText("1s")
    pullTimer.High:SetText("30s")

    pullTimer.Text:SetText(
        "Pull Countdown: " .. tostring(currentPullTimer) .. "s"
    )

    pullTimer:SetScript(
        "OnValueChanged",
        function(slider, value)
            value = math.floor(value + 0.5)

            db.pullCountdown = value

            slider.Text:SetText(
                "Pull Countdown: " .. tostring(value) .. "s"
            )
        end
    )

    local fontLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    fontLabel:SetPoint(
        "TOPLEFT",
        pullTimer,
        "BOTTOMLEFT",
        0,
        -22
    )

    fontLabel:SetText("Font")

    local fontDropdown = CreateFrame(
        "DropdownButton",
        nil,
        content,
        "WowStyle1DropdownTemplate"
    )

    fontDropdown:SetPoint(
        "TOPLEFT",
        fontLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    fontDropdown:SetWidth(250)

    local function GetCurrentFontName()
        local current = db.fontPath

        for _, fontInfo in ipairs(FONT_LIST) do
            if fontInfo.file == current then
                return fontInfo.name
            end
        end

        return "Default"
    end

    local function SetSelectedFont(fontInfo)
        db.fontPath = fontInfo.file
        db.font = fontInfo.name
        addon.fontPath = fontInfo.file

        if addon.LoadFontSettings then
            addon:LoadFontSettings()
        end

        if addon.RefreshFonts then
            addon:RefreshFonts()
        end

        if fontDropdown.SetText then
            fontDropdown:SetText(fontInfo.name)
        end
    end

    fontDropdown:SetupMenu(
        function(dropdown, rootDescription)
            for _, fontInfo in ipairs(FONT_LIST) do
                rootDescription:CreateRadio(
                    fontInfo.name,
                    function()
                        return db.fontPath == fontInfo.file
                    end,
                    function()
                        SetSelectedFont(fontInfo)
                    end
                )
            end
        end
    )

    if fontDropdown.SetText then
        fontDropdown:SetText(GetCurrentFontName())
    end

    local opacityLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    opacityLabel:SetPoint(
        "TOPLEFT",
        fontDropdown,
        "BOTTOMLEFT",
        0,
        -22
    )

    opacityLabel:SetText("Panel Opacity")

    local opacity = CreateFrame(
        "Slider",
        nil,
        content,
        "OptionsSliderTemplate"
    )

    opacity:SetPoint(
        "TOPLEFT",
        opacityLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    opacity:SetWidth(250)

    opacity:SetMinMaxValues(
        0,
        1
    )

    opacity:SetValueStep(0.05)
    opacity:SetObeyStepOnDrag(true)

    local currentOpacity = tonumber(db.opacity) or 0.90

    currentOpacity = math.max(
        0,
        math.min(
            1,
            currentOpacity
        )
    )

    opacity:SetValue(currentOpacity)

    opacity.Low:SetText("0%")
    opacity.High:SetText("100%")

    opacity.Text:SetText(
        string.format(
            "Opacity: %d%%",
            math.floor(currentOpacity * 100 + 0.5)
        )
    )

    opacity:SetScript(
        "OnValueChanged",
        function(slider, value)
            value = math.floor(
                value * 20 + 0.5
            ) / 20

            value = math.max(
                0,
                math.min(
                    1,
                    value
                )
            )

            db.opacity = value

            slider.Text:SetText(
                string.format(
                    "Opacity: %d%%",
                    math.floor(value * 100 + 0.5)
                )
            )

            if addon.ApplyVisualSettings then
                addon:ApplyVisualSettings()
            end
        end
    )

    local panelColorLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    panelColorLabel:SetPoint(
        "TOPLEFT",
        opacity,
        "BOTTOMLEFT",
        0,
        -25
    )

    panelColorLabel:SetText("Panel Color")

    local panelColorButton = CreateFrame(
        "Button",
        nil,
        content,
        "UIPanelButtonTemplate"
    )

    panelColorButton:SetSize(250, 24)

    panelColorButton:SetPoint(
        "TOPLEFT",
        panelColorLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    panelColorButton:SetText("Choose Panel Color")

    panelColorButton:SetScript(
        "OnClick",
        function()
            if not ColorPickerFrame then
                return
            end

            local c = db.panelColor

            if type(c) ~= "table" then
                c = {
                    r = 0.05,
                    g = 0.05,
                    b = 0.05,
                }

                db.panelColor = c
            end

            local previous = {
                r = c.r,
                g = c.g,
                b = c.b,
            }

            local function ApplyColor()
                local r, g, b

                if ColorPickerFrame.GetColorRGB then
                    r, g, b =
                        ColorPickerFrame:GetColorRGB()
                else
                    r, g, b =
                        ColorPickerFrame:GetColor()
                end

                db.panelColor.r = r
                db.panelColor.g = g
                db.panelColor.b = b

                if addon.ApplyVisualSettings then
                    addon:ApplyVisualSettings()
                end
            end

            local function CancelColor()
                db.panelColor.r = previous.r
                db.panelColor.g = previous.g
                db.panelColor.b = previous.b

                if addon.ApplyVisualSettings then
                    addon:ApplyVisualSettings()
                end
            end

            ColorPickerFrame:SetupColorPickerAndShow({
                r = c.r,
                g = c.g,
                b = c.b,
                swatchFunc = ApplyColor,
                cancelFunc = CancelColor,
            })
        end
    )

    local borderColorLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    borderColorLabel:SetPoint(
        "TOPLEFT",
        panelColorButton,
        "BOTTOMLEFT",
        0,
        -20
    )

    borderColorLabel:SetText("Border Color")

    local borderColorButton = CreateFrame(
        "Button",
        nil,
        content,
        "UIPanelButtonTemplate"
    )

    borderColorButton:SetSize(250, 24)

    borderColorButton:SetPoint(
        "TOPLEFT",
        borderColorLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    borderColorButton:SetText("Choose Border Color")

    borderColorButton:SetScript(
        "OnClick",
        function()
            if not ColorPickerFrame then
                return
            end

            local c = db.borderColor

            if type(c) ~= "table" then
                c = {
                    r = 0.35,
                    g = 0.35,
                    b = 0.35,
                }

                db.borderColor = c
            end

            local previous = {
                r = c.r,
                g = c.g,
                b = c.b,
            }

            local function ApplyColor()
                local r, g, b

                if ColorPickerFrame.GetColorRGB then
                    r, g, b =
                        ColorPickerFrame:GetColorRGB()
                else
                    r, g, b =
                        ColorPickerFrame:GetColor()
                end

                db.borderColor.r = r
                db.borderColor.g = g
                db.borderColor.b = b

                if addon.ApplyVisualSettings then
                    addon:ApplyVisualSettings()
                end
            end

            local function CancelColor()
                db.borderColor.r = previous.r
                db.borderColor.g = previous.g
                db.borderColor.b = previous.b

                if addon.ApplyVisualSettings then
                    addon:ApplyVisualSettings()
                end
            end

            ColorPickerFrame:SetupColorPickerAndShow({
                r = c.r,
                g = c.g,
                b = c.b,
                swatchFunc = ApplyColor,
                cancelFunc = CancelColor,
            })
        end
    )

    local borderWidthLabel = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontNormal"
    )

    borderWidthLabel:SetPoint(
        "TOPLEFT",
        borderColorButton,
        "BOTTOMLEFT",
        0,
        -22
    )

    borderWidthLabel:SetText("Border Width")

    local borderWidth = CreateFrame(
        "Slider",
        nil,
        content,
        "OptionsSliderTemplate"
    )

    borderWidth:SetPoint(
        "TOPLEFT",
        borderWidthLabel,
        "BOTTOMLEFT",
        0,
        -8
    )

    borderWidth:SetWidth(250)
    borderWidth:SetMinMaxValues(0, 3)
    borderWidth:SetValueStep(1)
    borderWidth:SetObeyStepOnDrag(true)

    local currentBorderWidth =
        tonumber(db.borderWidth) or 1

    borderWidth:SetValue(currentBorderWidth)
    borderWidth.Low:SetText("0")
    borderWidth.High:SetText("3")

    borderWidth.Text:SetText(
        "Border Width: " ..
        tostring(currentBorderWidth)
    )

    borderWidth:SetScript(
        "OnValueChanged",
        function(slider, value)
            value = math.floor(value + 0.5)

            db.borderWidth = value

            slider.Text:SetText(
                "Border Width: " ..
                tostring(value)
            )

            if addon.ApplyVisualSettings then
                addon:ApplyVisualSettings()
            end
        end
    )

    local positionInfo = content:CreateFontString(
        nil,
        "ARTWORK",
        "GameFontHighlight"
    )

    positionInfo:SetPoint(
        "TOPLEFT",
        borderWidth,
        "BOTTOMLEFT",
        0,
        -25
    )

    positionInfo:SetWidth(500)
    positionInfo:SetJustifyH("LEFT")

    positionInfo:SetText(
        "Panel Position:\n" ..
        "Use EllesmereUI's Unlock Mode to move the panel.\n" ..
        "The position is saved automatically."
    )

    local reset = CreateFrame(
        "Button",
        nil,
        content,
        "UIPanelButtonTemplate"
    )

    reset:SetSize(130, 24)

    reset:SetPoint(
        "TOPLEFT",
        positionInfo,
        "BOTTOMLEFT",
        0,
        -12
    )

    reset:SetText("Reset Position")

    reset:SetScript(
        "OnClick",
        function()
            if addon.ResetPosition then
                addon:ResetPosition()
            end
        end
    )

    local category =
        Settings.RegisterCanvasLayoutCategory(
            panel,
            "Compact Utility Panel"
        )

    Settings.RegisterAddOnCategory(category)

    self.settingsCategory = category

    return category
end