local ADDON_NAME, ns = ...

ns.config = ns.config or {}
local Cfg = ns.config

-- =============================================================
-- pom_config.lua
-- Defensive settings UI builder (nil-safe for templates)
-- NOTE:
-- - Castbar settings are intentionally removed (handled elsewhere)
-- - Added: "Use base colors when solo" toggle (overrides other logic)
-- - Added: Button to open /pomca
-- =============================================================

-- Prefer centralized font list if present (pom_fonts.lua), fallback to local list
local AVAILABLE_FONTS = {
    -- Blizzard / Standard fonts ONLY
    { name = "Default (Friz Quadrata)", path = _G.STANDARD_TEXT_FONT or "Fonts\\FRIZQT__.TTF" },
    { name = "Friz Quadrata",           path = "Fonts\\FRIZQT__.TTF" },
    { name = "Arial Narrow",            path = "Fonts\\ARIALN.TTF" },
    { name = "Skurri",                  path = "Fonts\\skurri.ttf" },
    { name = "Morpheus",                path = "Fonts\\MORPHEUS.ttf" },
    { name = "2002",                    path = "Fonts\\2002.ttf" },
}


-- =========================================================
-- Popup: Skins
-- =========================================================
local function ShowSkinList(anchor, skins, currentID, onPick)
    if Cfg._skinList and Cfg._skinList:IsShown() then
        Cfg._skinList:Hide()
    end

    if not Cfg._skinList then
        local f = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
        f:SetFrameStrata("DIALOG")
        f:SetBackdrop({ bgFile="Interface\\Buttons\\WHITE8x8", edgeFile="Interface\\Buttons\\WHITE8x8", edgeSize=1 })
        f:SetBackdropColor(0,0,0,0.95)
        f:SetBackdropBorderColor(0,0,0,1)
        f.buttons = {}
        Cfg._skinList = f
    end

    local f = Cfg._skinList
    f:ClearAllPoints()
    f:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, -2)

    for i = 1, #f.buttons do
        f.buttons[i]:Hide()
    end

    local btnH = 18
    local w = 260
    local maxShown = 30

    local count = math.min(#skins, maxShown)
    f:SetSize(w, count * btnH + 8)

    for i = 1, count do
        local skin = skins[i]
        local b = f.buttons[i]
        if not b then
            b = CreateFrame("Button", nil, f)
            b:SetSize(w - 8, btnH)
            b:SetPoint("TOPLEFT", f, "TOPLEFT", 4, -4 - (i-1) * btnH)

            local t = b:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
            t:SetPoint("LEFT", b, "LEFT", 4, 0)
            t:SetJustifyH("LEFT")
            b.text = t

            b:SetScript("OnEnter", function(self) self.text:SetTextColor(1, 0.82, 0) end)
            b:SetScript("OnLeave", function(self) self.text:SetTextColor(1, 1, 1) end)

            f.buttons[i] = b
        end

        b.text:SetText(((i == currentID) and "|cff00ff00•|r " or "  ") .. (skin.name or ("Skin " .. i)))
        b:SetScript("OnClick", function()
            f:Hide()
            if onPick then onPick(i) end
        end)

        b:Show()
    end

    f:Show()
end

-- =========================================================
-- Popup: Fonts
-- =========================================================
local function ShowFontList(anchor, fonts, currentPath, onPick)
    if Cfg._fontList and Cfg._fontList:IsShown() then
        Cfg._fontList:Hide()
    end

    if not Cfg._fontList then
        local f = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
        f:SetFrameStrata("DIALOG")
        f:SetBackdrop({ bgFile="Interface\\Buttons\\WHITE8x8", edgeFile="Interface\\Buttons\\WHITE8x8", edgeSize=1 })
        f:SetBackdropColor(0,0,0,0.95)
        f:SetBackdropBorderColor(0,0,0,1)
        f.buttons = {}
        Cfg._fontList = f
    end

    local f = Cfg._fontList
    f:ClearAllPoints()
    f:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, -2)

    for i = 1, #f.buttons do
        f.buttons[i]:Hide()
    end

    local btnH = 18
    local w = 260
    local maxShown = 18

    local count = math.min(#fonts, maxShown)
    f:SetSize(w, count * btnH + 8)

    for i = 1, count do
        local font = fonts[i]
        local b = f.buttons[i]
        if not b then
            b = CreateFrame("Button", nil, f)
            b:SetSize(w - 8, btnH)
            b:SetPoint("TOPLEFT", f, "TOPLEFT", 4, -4 - (i-1) * btnH)

            local t = b:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
            t:SetPoint("LEFT", b, "LEFT", 4, 0)
            t:SetJustifyH("LEFT")
            b.text = t

            b:SetScript("OnEnter", function(self) self.text:SetTextColor(1, 0.82, 0) end)
            b:SetScript("OnLeave", function(self) self.text:SetTextColor(1, 1, 1) end)

            f.buttons[i] = b
        end

        local isCurrent = (font.path == currentPath)
        b.text:SetText((isCurrent and "|cff00ff00•|r " or "  ") .. (font.name or ("Font " .. i)))
        b:SetScript("OnClick", function()
            f:Hide()
            if onPick then onPick(font) end
        end)

        b:Show()
    end

    f:Show()
end

local function ApplyAll(applyAll)
    if applyAll then applyAll() end
end

-- =========================================================
-- Helper: get label fontstring from checkbox template
-- =========================================================
local function GetCheckLabel(cb)
    if not cb then return nil end
    if cb.Text and cb.Text.SetText then return cb.Text end
    if cb.text and cb.text.SetText then return cb.text end
    local n = cb.GetName and cb:GetName()
    if n and _G[n .. "Text"] and _G[n .. "Text"].SetText then
        return _G[n .. "Text"]
    end
    return nil
end

local function MakeSectionTitle(parent, text, x, y)
    local t = parent:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    t:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
    t:SetText(text)
    return t
end

local function MakeCheck(parent, label, key, x, y, applyAll)
    local cb = CreateFrame("CheckButton", nil, parent, "ChatConfigCheckButtonTemplate")
    cb:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)

    local lbl = GetCheckLabel(cb)
    if lbl then lbl:SetText(label) end

    local function refresh()
        cb:SetChecked(PlateOMaticDB[key] and true or false)
    end
    refresh()

    cb:SetScript("OnClick", function(self)
        PlateOMaticDB[key] = self:GetChecked() and true or false
        ApplyAll(applyAll)
    end)

    return cb
end

-- =========================================================
-- Color swatch (nil-safe)
-- =========================================================
local function MakeColorSwatch(parent, x, y, getColor, setColor, applyAll)
    local b = CreateFrame("Button", nil, parent)
    b:SetSize(18, 18)
    b:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)

    local bg = b:CreateTexture(nil, "BACKGROUND")
    bg:SetAllPoints()
    bg:SetColorTexture(0.15, 0.15, 0.15, 1)

    local sw = b:CreateTexture(nil, "OVERLAY")
    sw:SetPoint("TOPLEFT", 1, -1)
    sw:SetPoint("BOTTOMRIGHT", -1, 1)

    local function SafeColor()
        local c = nil
        if getColor then c = getColor() end
        if type(c) ~= "table" then c = { r=1, g=1, b=1, a=1 } end
        return c
    end

    local function refresh()
        local c = SafeColor()
        sw:SetColorTexture(c.r or 1, c.g or 1, c.b or 1, c.a or 1)
    end
    refresh()

    b:SetScript("OnClick", function()
        local c = SafeColor()

        ColorPickerFrame:SetupColorPickerAndShow({
            r = c.r or 1, g = c.g or 1, b = c.b or 1,
            opacity = 1 - (c.a or 1),
            hasOpacity = true,

            swatchFunc = function()
                local r, g, b = ColorPickerFrame:GetColorRGB()
                local a = 1 - (ColorPickerFrame:GetColorAlpha() or 0)
                if setColor then setColor(r, g, b, a) end
                refresh()
                ApplyAll(applyAll)
            end,

            opacityFunc = function()
                local r, g, b = ColorPickerFrame:GetColorRGB()
                local a = 1 - (ColorPickerFrame:GetColorAlpha() or 0)
                if setColor then setColor(r, g, b, a) end
                refresh()
                ApplyAll(applyAll)
            end,

            cancelFunc = function(prev)
                if prev and setColor then
                    local a = 1 - (prev.opacity or 0)
                    setColor(prev.r, prev.g, prev.b, a)
                end
                refresh()
                ApplyAll(applyAll)
            end,
        })
    end)

    return b
end

local function MakeSkinRow(parent, skins, label, typeKey, x, y, applyAll)
    local row = CreateFrame("Frame", nil, parent)
    row:SetSize(420, 20)
    row:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)

    local txt = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    txt:SetPoint("LEFT", row, "LEFT", 0, 0)
    txt:SetText(label)

    local btn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
    btn:SetSize(220, 20)
    btn:SetPoint("RIGHT", row, "RIGHT", 0, 0)

    local function refresh()
        PlateOMaticDB.skins = PlateOMaticDB.skins or {}
        local id = PlateOMaticDB.skins[typeKey] or 1
        local s = skins[id]
        btn:SetText(s and s.name or ("Skin " .. id))
    end
    refresh()

    btn:SetScript("OnClick", function()
        PlateOMaticDB.skins = PlateOMaticDB.skins or {}
        local currentID = PlateOMaticDB.skins[typeKey] or 1
        ShowSkinList(btn, skins, currentID, function(id)
            PlateOMaticDB.skins[typeKey] = id
            refresh()
            ApplyAll(applyAll)
        end)
    end)

    return row
end

local function MakeHeightRow(parent, label, key, x, y, applyAll)
    local row = CreateFrame("Frame", nil, parent)
    row:SetSize(420, 20)
    row:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)

    local txt = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    txt:SetPoint("LEFT", row, "LEFT", 0, 0)
    txt:SetText(label)

    local eb = CreateFrame("EditBox", nil, row, "InputBoxTemplate")
    eb:SetSize(50, 18)
    eb:SetPoint("RIGHT", row, "RIGHT", 0, 0)
    eb:SetAutoFocus(false)
    eb:SetNumeric(true)

    local function refresh()
        PlateOMaticDB.heights = PlateOMaticDB.heights or {}
        eb:SetNumber(PlateOMaticDB.heights[key] or 16)
    end
    refresh()

    eb:SetScript("OnEnterPressed", function(self)
        PlateOMaticDB.heights = PlateOMaticDB.heights or {}
        PlateOMaticDB.heights[key] = tonumber(self:GetText()) or (PlateOMaticDB.heights[key] or 16)
        self:ClearFocus()
        ApplyAll(applyAll)
    end)

    return row
end

local function MakeColorRow(parent, label, key, x, y, applyAll)
    local row = CreateFrame("Frame", nil, parent)
    row:SetSize(420, 20)
    row:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)

    local txt = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    txt:SetPoint("LEFT", row, "LEFT", 0, 0)
    txt:SetText(label)

    MakeColorSwatch(
        row, 300, -1,
        function()
            PlateOMaticDB.colors = PlateOMaticDB.colors or {}
            PlateOMaticDB.colors[key] = PlateOMaticDB.colors[key] or { r=1, g=1, b=1, a=1 }
            return PlateOMaticDB.colors[key]
        end,
        function(r,g,b,a)
            PlateOMaticDB.colors = PlateOMaticDB.colors or {}
            PlateOMaticDB.colors[key] = PlateOMaticDB.colors[key] or { r=1, g=1, b=1, a=1 }
            local c = PlateOMaticDB.colors[key]
            c.r, c.g, c.b, c.a = r, g, b, a
        end,
        applyAll
    )

    return row
end

local function MakeThreatRow(parent, label, key, x, y, applyAll)
    local row = CreateFrame("Frame", nil, parent)
    row:SetSize(390, 22)
    row:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)

    local txt = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    txt:SetPoint("LEFT", row, "LEFT", 0, 0)
    txt:SetText(label)

    MakeColorSwatch(
        row, 240, -2,
        function()
            PlateOMaticDB.colors = PlateOMaticDB.colors or {}
            PlateOMaticDB.colors[key] = PlateOMaticDB.colors[key] or { r=1, g=1, b=1, a=1 }
            return PlateOMaticDB.colors[key]
        end,
        function(r, g, b, a)
            PlateOMaticDB.colors = PlateOMaticDB.colors or {}
            PlateOMaticDB.colors[key] = PlateOMaticDB.colors[key] or { r=1, g=1, b=1, a=1 }
            local c = PlateOMaticDB.colors[key]
            c.r, c.g, c.b = r, g, b
            if a ~= nil then c.a = a end
        end,
        applyAll
    )

    return row
end

-- =========================================================
-- Slider helper (nil-name safe)
-- =========================================================
local function MakeSlider(parent, label, key, x, y, minV, maxV, step, applyAll, width)
    width = tonumber(width) or 340

    local row = CreateFrame("Frame", nil, parent)
    row:SetSize(width, 42)
    row:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)

    local txt = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    txt:SetPoint("TOPLEFT", row, "TOPLEFT", 0, 0)
    txt:SetText(label)

    local s = CreateFrame("Slider", nil, row, "OptionsSliderTemplate")
    s:SetPoint("TOPLEFT", row, "TOPLEFT", 0, -16)
    s:SetPoint("TOPRIGHT", row, "TOPRIGHT", 0, -16)
    s:SetMinMaxValues(minV, maxV)
    s:SetValueStep(step)
    s:SetObeyStepOnDrag(true)

    local low  = s.Low
    local high = s.High
    local text = s.Text

    if not low then
        low = s:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        low:SetPoint("TOPLEFT", s, "BOTTOMLEFT", 0, -2)
        s.Low = low
    end
    if not high then
        high = s:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        high:SetPoint("TOPRIGHT", s, "BOTTOMRIGHT", 0, -2)
        s.High = high
    end
    if not text then
        text = s:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        text:SetPoint("TOP", s, "BOTTOM", 0, -2)
        s.Text = text
    end

    local function refresh()
        local v = PlateOMaticDB[key]
        if v == nil then v = minV end
        s:SetValue(v)
        low:SetText(tostring(minV))
        high:SetText(tostring(maxV))
        text:SetText(string.format("%.2f", v))
    end
    refresh()

    s:SetScript("OnValueChanged", function(self, value)
        PlateOMaticDB[key] = value
        self.Text:SetText(string.format("%.2f", value))
        ApplyAll(applyAll)
    end)

    return row
end

local function MakeFontButton(parent, fonts, x, y, applyAll)
    local btn = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    btn:SetSize(220, 20)
    btn:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)

    local function FontNameFromPath(p)
        for _, fnt in ipairs(fonts) do
            if fnt.path == p then return fnt.name end
        end
        return "Custom"
    end

    local function refresh()
        btn:SetText("Font: " .. FontNameFromPath(PlateOMaticDB.fontPath))
    end
    refresh()

    btn:SetScript("OnClick", function()
        ShowFontList(btn, fonts, PlateOMaticDB.fontPath, function(pick)
            PlateOMaticDB.fontPath = pick.path
            refresh()
            ApplyAll(applyAll)
        end)
    end)

    return btn
end

-- =========================================================
-- Run slash safely (for /pomca button)
-- =========================================================
local function RunSlash(cmd)
    if ChatEdit_ExecuteCommand then
        ChatEdit_ExecuteCommand(cmd)
        return
    end
    local eb = ChatFrame1EditBox or _G.ChatFrame1EditBox
    if eb and eb.SetText and ChatEdit_SendText then
        eb:SetText(cmd)
        ChatEdit_SendText(eb, 0)
    end
end

-- =========================================================
-- Build()
-- =========================================================
function Cfg:Build(frame, skins, applyAll)
    local Lx = 16
    local Rx = 460
    local top = -40

    local y = top

    MakeSectionTitle(frame, "Skins", Lx, y); y = y - 28
    MakeSkinRow(frame, skins, "Normal", "normal", Lx, y, applyAll); y = y - 24
    MakeSkinRow(frame, skins, "Highlevel (+2)", "highlevel", Lx, y, applyAll); y = y - 24
    MakeSkinRow(frame, skins, "Player +1", "plusOne", Lx, y, applyAll); y = y - 24
    MakeSkinRow(frame, skins, "Elite Caster", "caster", Lx, y, applyAll); y = y - 24
    MakeSkinRow(frame, skins, "Elite Melee", "melee", Lx, y, applyAll); y = y - 32

    MakeSectionTitle(frame, "Heights", Lx, y); y = y - 28
    MakeHeightRow(frame, "Normal Height", "normal", Lx, y, applyAll); y = y - 24
    MakeHeightRow(frame, "Highlevel Height", "highlevel", Lx, y, applyAll); y = y - 24
    MakeHeightRow(frame, "Player+1 Height", "plusOne", Lx, y, applyAll); y = y - 24
    MakeHeightRow(frame, "Caster Height", "caster", Lx, y, applyAll); y = y - 24
    MakeHeightRow(frame, "Melee Height", "melee", Lx, y, applyAll); y = y - 32

    MakeSectionTitle(frame, "Base Colors", Lx, y); y = y - 28
    MakeColorRow(frame, "Normal", "normal", Lx, y, applyAll); y = y - 24
    MakeColorRow(frame, "Highlevel", "highlevel", Lx, y, applyAll); y = y - 24
    MakeColorRow(frame, "Player +1", "plusOne", Lx, y, applyAll); y = y - 24
    MakeColorRow(frame, "Caster", "caster", Lx, y, applyAll); y = y - 24
    MakeColorRow(frame, "Melee", "melee", Lx, y, applyAll); y = y - 32

    MakeSectionTitle(frame, "Threat Colors", Lx, y); y = y - 28
    MakeThreatRow(frame, "Aggro (High Threat)", "threatHigh", Lx, y, applyAll); y = y - 22
    MakeThreatRow(frame, "Warning (Medium)", "threatMedium", Lx, y, applyAll); y = y - 22
    MakeThreatRow(frame, "Safe/Low", "threatLow", Lx, y, applyAll); y = y - 22
    MakeThreatRow(frame, "Tank: Safe (Have Aggro)", "threatTankSafe", Lx, y, applyAll); y = y - 22
    MakeThreatRow(frame, "Tank: Off-Tank Has Aggro", "threatOffTank", Lx, y, applyAll); y = y - 26

    MakeSectionTitle(frame, "Target Border", Lx, y); y = y - 28
    local tbRow = CreateFrame("Frame", nil, frame)
    tbRow:SetSize(390, 22)
    tbRow:SetPoint("TOPLEFT", frame, "TOPLEFT", Lx, y)

    local tbTxt = tbRow:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    tbTxt:SetPoint("LEFT", tbRow, "LEFT", 0, 0)
    tbTxt:SetText("Target Border Color")

    MakeColorSwatch(
        tbRow, 240, -2,
        function()
            PlateOMaticDB.targetBorderColor = PlateOMaticDB.targetBorderColor or { r=1, g=0.82, b=0, a=1 }
            return PlateOMaticDB.targetBorderColor
        end,
        function(r,g,b,a)
            PlateOMaticDB.targetBorderColor = PlateOMaticDB.targetBorderColor or { r=1, g=0.82, b=0, a=1 }
            PlateOMaticDB.targetBorderColor.r = r
            PlateOMaticDB.targetBorderColor.g = g
            PlateOMaticDB.targetBorderColor.b = b
            PlateOMaticDB.targetBorderColor.a = a
        end,
        applyAll
    )

    -- =========================================================
    -- OPTIONS (right column)
    -- =========================================================
    MakeSectionTitle(frame, "Options", Rx, top)

    local cy = top - 28
    local cgap = 24

    MakeFontButton(frame, AVAILABLE_FONTS, Rx, cy, applyAll); cy = cy - cgap

    local outlineBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
    outlineBtn:SetSize(220, 20)
    outlineBtn:SetPoint("TOPLEFT", frame, "TOPLEFT", Rx, cy)

    local function refreshOutline()
        local v = PlateOMaticDB.fontOutline or "OUTLINE"
        outlineBtn:SetText("Outline: " .. v)
    end
    refreshOutline()

    outlineBtn:SetScript("OnClick", function()
        local v = PlateOMaticDB.fontOutline or "OUTLINE"
        local nxt = (v == "NONE") and "OUTLINE" or (v == "OUTLINE") and "THICKOUTLINE" or "NONE"
        PlateOMaticDB.fontOutline = nxt
        refreshOutline()
        ApplyAll(applyAll)
    end)
    cy = cy - cgap

    MakeSlider(frame, "Font Size", "fontSize", Rx, cy, 6, 20, 1, applyAll); cy = cy - 46

    -- NEW: Solo base colors override (default off)
    local soloCheck = MakeCheck(frame, "Use Base Colors When Solo (Overrides Other Colors)", "useBaseColorsSolo", Rx, cy, applyAll)
    local soloLbl = GetCheckLabel(soloCheck)
    if soloLbl then soloLbl:SetTextColor(0.9, 0.9, 0.9) end
    cy = cy - cgap

    -- NEW: Button to open /pomca (castbar settings handled elsewhere)
    local caBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
    caBtn:SetSize(220, 20)
    caBtn:SetPoint("TOPLEFT", frame, "TOPLEFT", Rx, cy)
    caBtn:SetText("Open Castbar Settings (/pomca)")
    caBtn:SetScript("OnClick", function()
        RunSlash("/pomca")
    end)
    cy = cy - (cgap + 6)

    MakeCheck(frame, "Hide Elite Icon", "hideClassIcon", Rx, cy, applyAll); cy = cy - cgap
    MakeCheck(frame, "Flash Yellow (Threat Warning)", "flashAggro", Rx, cy, applyAll); cy = cy - cgap
    MakeCheck(frame, "Show Target Arrows", "showTargetArrow", Rx, cy, applyAll); cy = cy - cgap
    MakeCheck(frame, "Invert Arrows", "arrowPointingOut", Rx, cy, applyAll); cy = cy - cgap
    MakeCheck(frame, "Color Bar by Threat", "colorBarByThreat", Rx, cy, applyAll); cy = cy - cgap

    local gcCheck = MakeCheck(frame, "Group Combat Color (DPS/Heal)", "groupAggroColorEnabled", Rx, cy, applyAll)
    local gcLbl = GetCheckLabel(gcCheck)
    if gcLbl then gcLbl:SetTextColor(0.6, 0.9, 1.0) end
    cy = cy - cgap

    do
        local row = CreateFrame("Frame", nil, frame)
        row:SetSize(320, 20)
        row:SetPoint("TOPLEFT", frame, "TOPLEFT", Rx, cy)

        local txt2 = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
        txt2:SetPoint("LEFT", row, "LEFT", 0, 0)
        txt2:SetText("Group Combat Color")

        MakeColorSwatch(
            row, 240, -1,
            function()
                PlateOMaticDB.colors = PlateOMaticDB.colors or {}
                PlateOMaticDB.colors.groupAggro = PlateOMaticDB.colors.groupAggro or { r=0.2, g=0.7, b=1.0, a=1.0 }
                return PlateOMaticDB.colors.groupAggro
            end,
            function(r, g, b, a)
                PlateOMaticDB.colors = PlateOMaticDB.colors or {}
                PlateOMaticDB.colors.groupAggro = PlateOMaticDB.colors.groupAggro or { r=0.2, g=0.7, b=1.0, a=1.0 }
                local c = PlateOMaticDB.colors.groupAggro
                c.r, c.g, c.b, c.a = r, g, b, a
            end,
            applyAll
        )
    end
    cy = cy - cgap

    MakeCheck(frame, "Enable Tank Mode Logic", "tankModeEnabled", Rx, cy, applyAll); cy = cy - cgap

    local otCheck = MakeCheck(frame, "Check Off-Tank Aggro", "checkOffTank", Rx, cy, applyAll)
    local otLbl = GetCheckLabel(otCheck)
    if otLbl then otLbl:SetTextColor(0.6, 0.6, 1.0) end
    cy = cy - cgap

    MakeCheck(frame, "Show Threat %", "showThreatPerc", Rx, cy, applyAll); cy = cy - cgap
    MakeCheck(frame, "Show Quest Icon", "showQuestIcon", Rx, cy, applyAll); cy = cy - cgap
    MakeCheck(frame, "Show Quest Progress", "showQuestProg", Rx, cy, applyAll); cy = cy - cgap

    -- =========================================================
    -- SLIDERS (right column)
    -- NOTE: castbar sliders removed intentionally
    -- =========================================================
    MakeSectionTitle(frame, "Sliders", Rx, cy); cy = cy - 28

    MakeSlider(frame, "Global Scale", "globalScale", Rx, cy, 0.6, 1.6, 0.01, applyAll); cy = cy - 46
    MakeSlider(frame, "Target Scale", "targetScale", Rx, cy, 1.0, 1.6, 0.01, applyAll); cy = cy - 46
    MakeSlider(frame, "Buff Size", "buffSize", Rx, cy, 12, 40, 1, applyAll); cy = cy - 46
    MakeSlider(frame, "Debuff Size", "debuffSize", Rx, cy, 12, 40, 1, applyAll); cy = cy - 46
    MakeSlider(frame, "Flash Duration (0=until fixed)", "flashDuration", Rx, cy, 0, 5, 0.1, applyAll); cy = cy - 46
end
