-- CursorEffects - Options and Settings Panel
-- Provides in-game settings interface (Auctionator-style anchor chain layout)

local Options = {}

-- Default settings for when CE is not available
local DEFAULT_SETTINGS = {
    enabled = true,
    effects = { glow = true },
    glowIntensity = 1.0,
    pulseSpeed = 1.0,
    colors = {
        glow      = { r = 0, g = 1, b = 1 },
        pulse     = { r = 0, g = 1, b = 1 },
        trail     = { r = 0, g = 1, b = 1 },
        sparkle   = { r = 0, g = 1, b = 1 },
        crosshair = { r = 0, g = 1, b = 1 },
    },
    rainbow = {
        glow      = false,
        pulse     = false,
        trail     = false,
        sparkle   = false,
        crosshair = false,
    },
    crosshairEnabled = true,
    crosshairSensitivity = 1.0,
    scale = 1.5,
}

-- Always fetch CursorEffects at call time (options.lua loads before core.lua)
local function GetSetting(key)
    local ce = CursorEffects
    if ce and ce.settings then
        return ce.settings[key]
    end
    return DEFAULT_SETTINGS[key]
end

local function SetSetting(key, value)
    local ce = CursorEffects
    if ce and ce.settings then
        ce.settings[key] = value
    end
end

---------------------------------------------------------------------------
-- Helper: Create a section heading (Auctionator style, height ~30)
---------------------------------------------------------------------------
local function CreateHeading(parent, anchorTo, text, xOff, yOff)
    local frame = CreateFrame("Frame", nil, parent)
    frame:SetHeight(30)
    frame:SetPoint("TOPLEFT", anchorTo, "BOTTOMLEFT", xOff or 0, yOff or -8)
    frame:SetPoint("RIGHT", parent, "RIGHT", -16, 0)

    local label = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    label:SetPoint("TOPLEFT", 0, -4)
    label:SetText(text)

    local line = frame:CreateTexture(nil, "ARTWORK")
    line:SetHeight(1)
    line:SetPoint("TOPLEFT", label, "BOTTOMLEFT", 0, -4)
    line:SetPoint("RIGHT", frame, "RIGHT")
    line:SetColorTexture(0.5, 0.5, 0.5, 0.6)

    return frame
end

---------------------------------------------------------------------------
-- Helper: Create a checkbox row (height 30)
---------------------------------------------------------------------------
local function CreateCheckbox(parent, anchorTo, text, yOff)
    local row = CreateFrame("Frame", nil, parent)
    row:SetHeight(30)
    row:SetPoint("TOPLEFT", anchorTo, "BOTTOMLEFT", 0, yOff or 0)
    row:SetPoint("RIGHT", parent, "RIGHT", -16, 0)

    local btn = CreateFrame("CheckButton", nil, row, "UICheckButtonTemplate")
    btn:SetPoint("TOPLEFT", 4, -2)

    local label = row:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
    label:SetPoint("LEFT", btn, "RIGHT", 4, 0)
    label:SetText(text)

    row:EnableMouse(true)
    row:SetScript("OnMouseUp", function() btn:Click() end)

    row.button = btn
    return row
end

---------------------------------------------------------------------------
-- Helper: Create a slider row (height 50)
---------------------------------------------------------------------------
local function CreateSliderRow(parent, anchorTo, label, min, max, step, yOff)
    local row = CreateFrame("Frame", nil, parent)
    row:SetHeight(50)
    row:SetPoint("TOPLEFT", anchorTo, "BOTTOMLEFT", 0, yOff or 0)
    row:SetPoint("RIGHT", parent, "RIGHT", -16, 0)

    local title = row:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
    title:SetPoint("TOPLEFT", 8, -2)
    title:SetText(label)

    local slider = CreateFrame("Slider", nil, row, "OptionsSliderTemplate")
    slider:SetPoint("TOPLEFT", 8, -20)
    slider:SetWidth(200)
    slider:SetMinMaxValues(min, max)
    slider:SetValueStep(step)
    slider:SetObeyStepOnDrag(true)

    slider.Low:SetText(tostring(min))
    slider.High:SetText(tostring(max))

    local valueText = row:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
    valueText:SetPoint("LEFT", slider, "RIGHT", 10, 0)
    valueText:SetText("")

    row.slider = slider
    row.valueText = valueText
    return row
end

---------------------------------------------------------------------------
-- Helper: Create a radio-button group row (height 30)
---------------------------------------------------------------------------
local function CreateRadioGroup(parent, anchorTo, options, yOff)
    local row = CreateFrame("Frame", nil, parent)
    row:SetHeight(30)
    row:SetPoint("TOPLEFT", anchorTo, "BOTTOMLEFT", 0, yOff or 0)
    row:SetPoint("RIGHT", parent, "RIGHT", -16, 0)

    local buttons = {}
    local xPos = 8
    for _, opt in ipairs(options) do
        local btn = CreateFrame("CheckButton", nil, row)
        btn:SetPoint("TOPLEFT", xPos, -6)
        btn:SetSize(16, 16)

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

        local checked = btn:CreateTexture(nil, "ARTWORK")
        checked:SetPoint("CENTER")
        checked:SetSize(10, 10)
        checked:SetColorTexture(0.0, 0.8, 1.0, 1)
        btn:SetCheckedTexture(checked)

        local hl = btn:CreateTexture(nil, "HIGHLIGHT")
        hl:SetAllPoints()
        hl:SetColorTexture(1, 1, 1, 0.2)
        btn:SetHighlightTexture(hl)

        local label = btn:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
        label:SetPoint("LEFT", btn, "RIGHT", 4, 0)
        label:SetText(opt.label)

        btn.value = opt.value
        btn:SetScript("OnClick", function(self)
            for _, b in ipairs(buttons) do b:SetChecked(false) end
            self:SetChecked(true)
            if row.onChanged then row.onChanged(self.value) end
        end)

        table.insert(buttons, btn)
        xPos = xPos + 110
    end

    row.buttons = buttons
    row.SetValue = function(self, val)
        for _, b in ipairs(buttons) do
            b:SetChecked(b.value == val)
        end
    end
    row.GetValue = function(self)
        for _, b in ipairs(buttons) do
            if b:GetChecked() then return b.value end
        end
    end
    return row
end

---------------------------------------------------------------------------
-- CreateOptionsPanel  (Auctionator-style vertical anchor chain)
---------------------------------------------------------------------------
function Options:CreateOptionsPanel()
    local panel = CreateFrame("Frame", "CursorEffectsOptionsPanel")
    panel.name = "Cursor Effects"
    panel.OnCommit = function() end
    panel.OnDefault = function() end
    panel.OnRefresh = function() end
    _G.CursorEffectsOptionsPanel = panel

    ---------------------------------------------------------------------------
    -- ScrollFrame so content can exceed the visible area
    ---------------------------------------------------------------------------
    local scrollFrame = CreateFrame("ScrollFrame", nil, panel, "UIPanelScrollFrameTemplate")
    scrollFrame:SetPoint("TOPLEFT", 0, 0)
    scrollFrame:SetPoint("BOTTOMRIGHT", -26, 0)

    local scrollChild = CreateFrame("Frame", nil, scrollFrame)
    scrollChild:SetWidth(scrollFrame:GetWidth() or 560)
    scrollFrame:SetScrollChild(scrollChild)

    -- Resize scroll child width when panel resizes
    panel:SetScript("OnSizeChanged", function(self, w, h)
        scrollFrame:SetPoint("BOTTOMRIGHT", -26, 0)
        scrollChild:SetWidth(w - 40)
    end)

    -- Title area (height 60)
    local titleFrame = CreateFrame("Frame", nil, scrollChild)
    titleFrame:SetHeight(60)
    titleFrame:SetPoint("TOPLEFT", 16, -16)
    titleFrame:SetPoint("RIGHT", scrollChild, "RIGHT", -16, 0)

    local title = titleFrame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    title:SetPoint("TOPLEFT")
    title:SetText("Cursor Effects")

    local subtitle = titleFrame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    subtitle:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -4)
    subtitle:SetText("Customize your cursor appearance  —  |cff888888/ce help|r for slash commands")

    -----------------------------------------------------------------------
    -- General section
    -----------------------------------------------------------------------
    local genHeading = CreateHeading(scrollChild, titleFrame, "General")

    -- Enable checkbox
    local enableRow = CreateCheckbox(scrollChild, genHeading, "Enable Cursor Effects")
    enableRow.button:SetScript("OnClick", function(self)
        SetSetting("enabled", self:GetChecked() and true or false)
    end)

    -----------------------------------------------------------------------
    -- Effect Type section
    -----------------------------------------------------------------------
    local fxHeading = CreateHeading(scrollChild, enableRow, "Effect Types")

    local fxGlow = CreateCheckbox(scrollChild, fxHeading, "Glow")
    fxGlow.button:SetScript("OnClick", function(self)
        local effects = GetSetting("effects")
        if effects then
            effects.glow = self:GetChecked() and true or nil
            effects.rachel = nil
        end
    end)

    local fxPulse = CreateCheckbox(scrollChild, fxGlow, "Pulse")
    fxPulse.button:SetScript("OnClick", function(self)
        local effects = GetSetting("effects")
        if effects then
            effects.pulse = self:GetChecked() and true or nil
            effects.rachel = nil
        end
    end)

    local fxTrail = CreateCheckbox(scrollChild, fxPulse, "Trail")
    fxTrail.button:SetScript("OnClick", function(self)
        local effects = GetSetting("effects")
        if effects then
            effects.trail = self:GetChecked() and true or nil
            effects.rachel = nil
        end
    end)

    local fxSparkle = CreateCheckbox(scrollChild, fxTrail, "Sparkle")
    fxSparkle.button:SetScript("OnClick", function(self)
        local effects = GetSetting("effects")
        if effects then
            effects.sparkle = self:GetChecked() and true or nil
            effects.rachel = nil
        end
    end)

    -----------------------------------------------------------------------
    -- Crosshair section
    -----------------------------------------------------------------------
    local chHeading = CreateHeading(scrollChild, fxSparkle, "Shake-to-Find Crosshair")

    local chEnable = CreateCheckbox(scrollChild, chHeading, "Enable Crosshair on Mouse Shake")
    chEnable.button:SetScript("OnClick", function(self)
        SetSetting("crosshairEnabled", self:GetChecked() and true or false)
    end)

    -- Crosshair Sensitivity
    local chSensitivityRow = CreateSliderRow(scrollChild, chEnable, "Crosshair Sensitivity", 0.5, 2.0, 0.1)
    chSensitivityRow.slider:SetScript("OnValueChanged", function(self, v)
        v = math.floor(v * 10 + 0.5) / 10
        SetSetting("crosshairSensitivity", v)
        chSensitivityRow.valueText:SetText(string.format("%.1f", v))
    end)

    -----------------------------------------------------------------------
    -- Sliders section
    -----------------------------------------------------------------------
    local sliderHeading = CreateHeading(scrollChild, chSensitivityRow, "Adjustments")

    -- Mouse Size
    local sizeRow = CreateSliderRow(scrollChild, sliderHeading, "Mouse Size", 0.5, 3.0, 0.1)
    sizeRow.slider:SetScript("OnValueChanged", function(self, v)
        v = math.floor(v * 10 + 0.5) / 10
        SetSetting("scale", v)
        sizeRow.valueText:SetText(string.format("%.1f", v))
    end)

    -- Glow Intensity
    local glowRow = CreateSliderRow(scrollChild, sizeRow, "Glow Intensity", 0, 2.0, 0.1)
    glowRow.slider:SetScript("OnValueChanged", function(self, v)
        v = math.floor(v * 10 + 0.5) / 10
        SetSetting("glowIntensity", v)
        glowRow.valueText:SetText(string.format("%.1f", v))
    end)

    -- Pulse Speed
    local pulseRow = CreateSliderRow(scrollChild, glowRow, "Pulse Speed", 0.5, 2.0, 0.1)
    pulseRow.slider:SetScript("OnValueChanged", function(self, v)
        v = math.floor(v * 10 + 0.5) / 10
        SetSetting("pulseSpeed", v)
        pulseRow.valueText:SetText(string.format("%.1f", v))
    end)

    -----------------------------------------------------------------------
    -- Per-Effect Color section
    -----------------------------------------------------------------------
    local colorHeading = CreateHeading(scrollChild, pulseRow, "Effect Colors")

    -- Helper: create a color row for a specific effect
    local colorRows = {}
    local rainbowCheckboxes = {}
    local function CreateEffectColorRow(parent, anchorTo, effectKey, label)
        local row = CreateFrame("Frame", nil, parent)
        row:SetHeight(30)
        row:SetPoint("TOPLEFT", anchorTo, "BOTTOMLEFT", 0, 0)
        row:SetPoint("RIGHT", parent, "RIGHT", -16, 0)

        local nameLabel = row:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
        nameLabel:SetPoint("TOPLEFT", 8, -6)
        nameLabel:SetWidth(80)
        nameLabel:SetJustifyH("LEFT")
        nameLabel:SetText(label)

        local preview = CreateFrame("Frame", nil, row)
        preview:SetPoint("LEFT", nameLabel, "RIGHT", 4, 0)
        preview:SetSize(22, 22)
        local previewTex = preview:CreateTexture(nil, "BACKGROUND")
        previewTex:SetAllPoints()
        previewTex:SetColorTexture(0, 1, 1, 1)
        preview.bgTexture = previewTex

        local pickBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
        pickBtn:SetPoint("LEFT", preview, "RIGHT", 8, 0)
        pickBtn:SetSize(80, 22)
        pickBtn:SetText("Pick")
        pickBtn:SetScript("OnClick", function()
            Options:ShowColorPickerForEffect(effectKey)
        end)
        
        -- Rainbow checkbox
        local rainbowCheck = CreateFrame("CheckButton", nil, row, "UICheckButtonTemplate")
        rainbowCheck:SetPoint("LEFT", pickBtn, "RIGHT", 8, 0)
        rainbowCheck:SetSize(20, 20)
        local rainbowLabel = row:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
        rainbowLabel:SetPoint("LEFT", rainbowCheck, "RIGHT", 2, 0)
        rainbowLabel:SetText("Rainbow")
        rainbowCheck:SetScript("OnClick", function(self)
            local rainbow = GetSetting("rainbow")
            if rainbow then
                rainbow[effectKey] = self:GetChecked() and true or false
                -- Update preview to show rainbow hint when enabled
                if self:GetChecked() then
                    previewTex:SetColorTexture(1, 0, 0, 1)
                else
                    local colors = GetSetting("colors") or {}
                    local c = colors[effectKey] or { r = 0, g = 1, b = 1 }
                    previewTex:SetColorTexture(c.r, c.g, c.b, 1)
                end
            end
        end)

        row.effectKey = effectKey
        row.preview = preview
        row.previewTex = previewTex
        row.rainbowCheck = rainbowCheck
        colorRows[effectKey] = row
        rainbowCheckboxes[effectKey] = rainbowCheck
        return row
    end

    local glowColorRow      = CreateEffectColorRow(scrollChild, colorHeading,  "glow",      "Glow")
    local pulseColorRow     = CreateEffectColorRow(scrollChild, glowColorRow,  "pulse",     "Pulse")
    local trailColorRow     = CreateEffectColorRow(scrollChild, pulseColorRow, "trail",     "Trail")
    local sparkleColorRow   = CreateEffectColorRow(scrollChild, trailColorRow, "sparkle",   "Sparkle")
    local crosshairColorRow = CreateEffectColorRow(scrollChild, sparkleColorRow, "crosshair", "Crosshair")

    -- "Set All Colors" button
    local setAllRow = CreateFrame("Frame", nil, scrollChild)
    setAllRow:SetHeight(30)
    setAllRow:SetPoint("TOPLEFT", crosshairColorRow, "BOTTOMLEFT", 0, -2)
    setAllRow:SetPoint("RIGHT", scrollChild, "RIGHT", -16, 0)

    local setAllBtn = CreateFrame("Button", nil, setAllRow, "UIPanelButtonTemplate")
    setAllBtn:SetPoint("TOPLEFT", 8, -4)
    setAllBtn:SetSize(140, 22)
    setAllBtn:SetText("Set All Colors")
    setAllBtn:SetScript("OnClick", function()
        Options:ShowColorPickerForEffect("all")
    end)

    -- Preset color grid
    local presetHeading = CreateFrame("Frame", nil, scrollChild)
    presetHeading:SetHeight(20)
    presetHeading:SetPoint("TOPLEFT", setAllRow, "BOTTOMLEFT", 0, -4)
    presetHeading:SetPoint("RIGHT", scrollChild, "RIGHT", -16, 0)
    local presetTitle = presetHeading:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
    presetTitle:SetPoint("TOPLEFT", 8, 0)
    presetTitle:SetText("Preset Colors")

    local presets = {
        { name = "White",       r = 1,    g = 1,    b = 1 },
        { name = "Red",         r = 1,    g = 0,    b = 0 },
        { name = "Green",       r = 0,    g = 1,    b = 0 },
        { name = "Blue",        r = 0,    g = 0,    b = 1 },
        { name = "Yellow",      r = 1,    g = 1,    b = 0 },
        { name = "Cyan",        r = 0,    g = 1,    b = 1 },
        { name = "Magenta",     r = 1,    g = 0,    b = 1 },
        { name = "Orange",      r = 1,    g = 0.5,  b = 0 },
        { name = "Pink",        r = 1,    g = 0.75, b = 0.8 },
        { name = "Coral",       r = 1,    g = 0.5,  b = 0.31 },
        { name = "Crimson",     r = 0.86, g = 0.08, b = 0.24 },
        { name = "Sky Blue",    r = 0.53, g = 0.81, b = 0.92 },
        { name = "Turquoise",   r = 0.25, g = 0.88, b = 0.82 },
        { name = "Teal",        r = 0,    g = 0.5,  b = 0.5 },
        { name = "Indigo",      r = 0.29, g = 0,    b = 0.51 },
        { name = "Gold",        r = 1,    g = 0.84, b = 0 },
        { name = "Hot Pink",    r = 1,    g = 0.41, b = 0.71 },
        { name = "Lime",        r = 0,    g = 1,    b = 0 },
        { name = "Lavender",    r = 0.9,  g = 0.73, b = 1 },
        { name = "Forest",      r = 0.13, g = 0.55, b = 0.13 },
        { name = "Silver",      r = 0.75, g = 0.75, b = 0.75 },
        { name = "Navy",        r = 0,    g = 0,    b = 0.5 },
        { name = "Olive",       r = 0.5,  g = 0.5,  b = 0 },
        { name = "Electric",    r = 0.49, g = 0.98, b = 1 },
    }

    local btnW, btnH = 85, 22
    local cols = 6
    local hGap, vGap = 5, 4
    local totalRows = math.ceil(#presets / cols)
    local gridHeight = totalRows * (btnH + vGap)

    local presetGrid = CreateFrame("Frame", nil, scrollChild)
    presetGrid:SetHeight(gridHeight + 4)
    presetGrid:SetPoint("TOPLEFT", presetHeading, "BOTTOMLEFT", 0, -2)
    presetGrid:SetPoint("RIGHT", scrollChild, "RIGHT", -16, 0)

    for i, p in ipairs(presets) do
        local col = (i - 1) % cols
        local row = math.floor((i - 1) / cols)

        local btn = CreateFrame("Button", nil, presetGrid)
        btn:SetSize(btnW, btnH)
        btn:SetPoint("TOPLEFT", 8 + col * (btnW + hGap), -(row * (btnH + vGap)))

        local bg = btn:CreateTexture(nil, "BACKGROUND")
        bg:SetAllPoints()
        bg:SetColorTexture(p.r, p.g, p.b, 1)

        local hl = btn:CreateTexture(nil, "HIGHLIGHT")
        hl:SetAllPoints()
        hl:SetColorTexture(1, 1, 1, 0.3)
        btn:SetHighlightTexture(hl)

        local txt = btn:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
        txt:SetPoint("CENTER")
        txt:SetText(p.name)
        -- Readable text on light backgrounds
        local lum = p.r * 0.299 + p.g * 0.587 + p.b * 0.114
        if lum > 0.6 then txt:SetTextColor(0, 0, 0) end

        btn:SetScript("OnClick", function()
            local colors = GetSetting("colors")
            if colors then
                for effect, _ in pairs(colors) do
                    colors[effect] = { r = p.r, g = p.g, b = p.b }
                end
            end
            -- Update all color row previews
            for _, cRow in pairs(colorRows) do
                cRow.previewTex:SetColorTexture(p.r, p.g, p.b, 1)
            end
        end)
    end

    -----------------------------------------------------------------------
    -- Info footer
    -----------------------------------------------------------------------
    local footer = scrollChild:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    footer:SetPoint("TOPLEFT", presetGrid, "BOTTOMLEFT", 8, -12)
    footer:SetWidth(550)
    footer:SetJustifyH("LEFT")
    footer:SetText("Slash commands:  |cff00ffff/ce toggle|r  |cff00ffff/ce effect <type>|r  |cff00ffff/ce color <name>|r  |cff00ffff/ce color <effect> <name>|r  |cff00ffff/ce crosshair|r")

    -- Bottom spacer to ensure scroll range covers all content
    local bottomSpacer = CreateFrame("Frame", nil, scrollChild)
    bottomSpacer:SetHeight(20)
    bottomSpacer:SetPoint("TOPLEFT", footer, "BOTTOMLEFT", 0, -4)
    bottomSpacer:SetPoint("RIGHT", scrollChild, "RIGHT")

    -- Set scroll child height to contain all content
    scrollChild:SetHeight(
        60   -- title
        + 30 + 30  -- general heading + enable
        + 30 + (30 * 4)  -- fx heading + 4 checkboxes
        + 30 + 30  -- crosshair heading + checkbox
        + 30 + (50 * 3)  -- slider heading + 3 sliders
        + 30 + (30 * 5) + 30 + 20  -- color heading + 5 color rows + set-all + preset heading
        + gridHeight + 4  -- preset grid
        + 30 + 20  -- footer + spacer
        + 80  -- padding
    )

    -----------------------------------------------------------------------
    -- OnShow: refresh every control from live settings
    -----------------------------------------------------------------------
    panel:SetScript("OnShow", function()
        enableRow.button:SetChecked(GetSetting("enabled") and true or false)
        local effects = GetSetting("effects") or {}
        fxGlow.button:SetChecked(effects.glow and true or false)
        fxPulse.button:SetChecked(effects.pulse and true or false)
        fxTrail.button:SetChecked(effects.trail and true or false)
        fxSparkle.button:SetChecked(effects.sparkle and true or false)
        chEnable.button:SetChecked(GetSetting("crosshairEnabled") and true or false)
        chSensitivityRow.slider:SetValue(GetSetting("crosshairSensitivity") or 1.0)
        sizeRow.slider:SetValue(GetSetting("scale"))
        glowRow.slider:SetValue(GetSetting("glowIntensity"))
        pulseRow.slider:SetValue(GetSetting("pulseSpeed"))
        local colors = GetSetting("colors") or {}
        local rainbow = GetSetting("rainbow") or {}
        for effect, cRow in pairs(colorRows) do
            local isRainbow = rainbow[effect] and true or false
            rainbowCheckboxes[effect]:SetChecked(isRainbow)
            if isRainbow then
                -- Show red preview as hint for rainbow mode
                cRow.previewTex:SetColorTexture(1, 0, 0, 1)
            else
                local c = colors[effect] or { r = 0, g = 1, b = 1 }
                cRow.previewTex:SetColorTexture(c.r, c.g, c.b, 1)
            end
        end
    end)

    panel.colorRows = colorRows
    panel.rainbowCheckboxes = rainbowCheckboxes
    return panel
end

---------------------------------------------------------------------------
-- Color Picker  (12.0.1 SetupColorPickerAndShow API) — per-effect
---------------------------------------------------------------------------
function Options:ShowColorPickerForEffect(effectKey)
    if not ColorPickerFrame then return end
    local panel = _G.CursorEffectsOptionsPanel
    local colors = GetSetting("colors") or {}
    local c
    if effectKey == "all" then
        c = colors.glow or { r = 0, g = 1, b = 1 }
    else
        c = colors[effectKey] or { r = 0, g = 1, b = 1 }
    end

    local info = {
        swatchFunc = function()
            local r, g, b = ColorPickerFrame:GetColorRGB()
            local allColors = GetSetting("colors")
            if not allColors then return end
            if effectKey == "all" then
                for k in pairs(allColors) do
                    allColors[k] = { r = r, g = g, b = b }
                end
            else
                allColors[effectKey] = { r = r, g = g, b = b }
            end
            -- Update previews
            if panel and panel.colorRows then
                for k, cRow in pairs(panel.colorRows) do
                    local cc = allColors[k]
                    if cc then cRow.previewTex:SetColorTexture(cc.r, cc.g, cc.b, 1) end
                end
            end
        end,
        cancelFunc = function(prev)
            if not prev then return end
            local allColors = GetSetting("colors")
            if not allColors then return end
            if effectKey == "all" then
                for k in pairs(allColors) do
                    allColors[k] = { r = prev.r, g = prev.g, b = prev.b }
                end
            else
                allColors[effectKey] = { r = prev.r, g = prev.g, b = prev.b }
            end
            if panel and panel.colorRows then
                for k, cRow in pairs(panel.colorRows) do
                    local cc = allColors[k]
                    if cc then cRow.previewTex:SetColorTexture(cc.r, cc.g, cc.b, 1) end
                end
            end
        end,
        r = c.r, g = c.g, b = c.b,
        hasOpacity = false,
    }
    ColorPickerFrame:SetupColorPickerAndShow(info)
end

---------------------------------------------------------------------------
-- Settings API registration
---------------------------------------------------------------------------
function Options:Initialize()
    if Options.initialized then return end
    Options.initialized = true
    self:CreateOptionsPanel()
    self:RegisterWithInterfaceOptions()
end

function Options:RegisterWithInterfaceOptions()
    local panel = _G.CursorEffectsOptionsPanel
    if not panel then return end
    if not Settings or not Settings.RegisterCanvasLayoutCategory then return end

    local ok, err = pcall(function()
        local category = Settings.RegisterCanvasLayoutCategory(panel, "Cursor Effects")
        Settings.RegisterAddOnCategory(category)
        Options.settingsCategory = category
    end)
    if not ok then
        print("|cffff0000Cursor Effects:|r Registration error: " .. tostring(err))
    end
end

function Options:OpenOptions()
    if Options.settingsCategory and Settings and Settings.OpenToCategory then
        Settings.OpenToCategory(Options.settingsCategory:GetID())
    end
end

_G.CursorEffectsOptions = Options

-- Self-register: listen for PLAYER_LOGIN and initialize immediately
local loader = CreateFrame("Frame")
loader:RegisterEvent("PLAYER_LOGIN")
loader:SetScript("OnEvent", function(self, event)
    self:UnregisterAllEvents()
    -- Small delay to let core.lua initialize first
    C_Timer.After(0.2, function()
        Options:Initialize()
    end)
end)

return Options
