-- NP_CastbarTest/caset.lua
local ADDON, ns = ...

ns.CASet = ns.CASet or {}
local UI = ns.CASet

local function DB()
    -- Must be SavedVariables-backed
    PomcaDB = PomcaDB or {}
    ns.DB = ns.DB or PomcaDB
    return ns.DB
end

local function RefreshPlates()
    if ns.Castbar and ns.Castbar.RefreshAllPlates then
        ns.Castbar:RefreshAllPlates()
    end
end

-- ---------------------------------------------------------
-- UI helpers
-- ---------------------------------------------------------
local function MakeLabel(parent, text, template)
    local fs = parent:CreateFontString(nil, "OVERLAY", template or "GameFontNormal")
    fs:SetJustifyH("LEFT")
    fs:SetText(text or "")
    return fs
end

local function MakeButton(parent, text, w, h)
    local b = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    b:SetSize(w or 140, h or 22)
    b:SetText(text or "Button")
    return b
end

local function MakeCheck(parent, text)
    local cb = CreateFrame("CheckButton", nil, parent, "UICheckButtonTemplate")
    local t = cb.Text or cb.text
    if t then t:SetText(text or "") end
    return cb
end

local _sid = 0
local function CreateSlider(parent, label, x, y, minV, maxV, step, getV, setV, fmt)
    _sid = _sid + 1
    local name = "POMCA_Slider_" .. _sid

    local l = MakeLabel(parent, label, "GameFontNormal")
    l:SetPoint("TOPLEFT", x, y)

    local valText = parent:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    valText:SetPoint("TOPLEFT", x + 280, y)
    valText:SetJustifyH("LEFT")

    local s = CreateFrame("Slider", name, parent, "OptionsSliderTemplate")
    s:SetPoint("TOPLEFT", x, y - 18)
    s:SetWidth(320)
    s:SetMinMaxValues(minV, maxV)
    s:SetValueStep(step)
    s:SetObeyStepOnDrag(true)

    local function UpdateText(v)
        if fmt then valText:SetText(string.format(fmt, v)) else valText:SetText(tostring(v)) end
    end

    local v0 = getV()
    if type(v0) ~= "number" then v0 = minV end
    s:SetValue(v0)
    UpdateText(v0)

    s:SetScript("OnValueChanged", function(_, v)
        setV(v)
        UpdateText(getV())
        RefreshPlates()
    end)

    local txt = _G[name .. "Text"]
    if txt then txt:SetText("") end
    return s
end

-- ---------------------------------------------------------
-- Dropdown (nil-safe)
-- ---------------------------------------------------------
local function NormalizeItems(items)
    if type(items) ~= "table" then items = {} end
    if #items == 0 then items[1] = { name = "(missing)" } end
    return items
end

local function BuildDropdown(parent, items, getIndex, setIndex, onChange)
    items = NormalizeItems(items)
    local dd = CreateFrame("Frame", nil, parent, "UIDropDownMenuTemplate")

    local function OnClick(btn)
        local v = btn and btn.value
        if type(v) ~= "number" then return end
        setIndex(v)
        UIDropDownMenu_SetSelectedValue(dd, v)
        if onChange then onChange() end
    end

    UIDropDownMenu_Initialize(dd, function(_, level)
        level = level or 1
        for i, it in ipairs(items) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = (it and it.name) or ("Item " .. i)
            info.value = i
            info.func = OnClick
            UIDropDownMenu_AddButton(info, level)
        end
    end)

    UIDropDownMenu_SetWidth(dd, 260)
    local sel = getIndex()
    if type(sel) ~= "number" or sel < 1 or sel > #items then sel = 1 end
    UIDropDownMenu_SetSelectedValue(dd, sel)
    return dd
end

-- ---------------------------------------------------------
-- Background (fallback + overlay png)
-- ---------------------------------------------------------
local function ApplyBackground(f)
    f:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
        tile = true, tileSize = 32, edgeSize = 32,
        insets = { left = 11, right = 12, top = 12, bottom = 11 },
    })

    local texPath = "Interface\\AddOns\\" .. tostring(ADDON) .. "\\pombackground1.png"

    f._pomBg = f._pomBg or f:CreateTexture(nil, "BACKGROUND", nil, 2)
    f._pomBg:SetPoint("TOPLEFT", f, "TOPLEFT", 12, -12)
    f._pomBg:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -12, 12)
    pcall(f._pomBg.SetTexture, f._pomBg, texPath)
    f._pomBg:SetVertexColor(1, 1, 1, 1)
    f._pomBg:Show()

    f._shade = f._shade or f:CreateTexture(nil, "BACKGROUND", nil, 3)
    f._shade:SetPoint("TOPLEFT", f, "TOPLEFT", 12, -12)
    f._shade:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -12, 12)
    f._shade:SetColorTexture(0,0,0,1)
    f._shade:Show()
end

-- ---------------------------------------------------------
-- Build
-- ---------------------------------------------------------
function UI:EnsureBuilt()
    if self.frame then return end

    local db = DB()

    local f = CreateFrame("Frame", "POMCA_SettingsFrame", UIParent, "BackdropTemplate")
    f:SetSize(980, 680)
    f:SetPoint("CENTER")
    f:SetFrameStrata("DIALOG")
    f:SetFrameLevel(50)

    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop", f.StopMovingOrSizing)

    ApplyBackground(f)

    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("TOPLEFT", 18, -14)
    title:SetText("Castbar - Settings")

    local close = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    close:SetPoint("TOPRIGHT", -4, -4)

    local content = CreateFrame("Frame", nil, f)
    content:SetPoint("TOPLEFT", 16, -74)
    content:SetPoint("BOTTOMRIGHT", -16, 16)

    local pages = {}
    for i = 1, 4 do
        local p = CreateFrame("Frame", nil, content)
        p:SetAllPoints(content)
        p:Hide()
        pages[i] = p
    end

    local tabs = {}
    local function SetTab(i)
        for k = 1, 4 do
            pages[k]:SetShown(k == i)
            if tabs[k] and tabs[k].bg then
                if k == i then tabs[k].bg:SetColorTexture(0.18,0.18,0.18,0.90)
                else tabs[k].bg:SetColorTexture(0.10,0.10,0.10,0.70) end
            end
        end
    end

    local function MakeTab(i, text)
        local b = CreateFrame("Button", nil, f)
        b:SetSize(130, 24)
        if i == 1 then b:SetPoint("TOPLEFT", 16, -42)
        else b:SetPoint("LEFT", tabs[i-1], "RIGHT", 6, 0) end

        b.bg = b:CreateTexture(nil, "BACKGROUND")
        b.bg:SetAllPoints()
        b.bg:SetColorTexture(0.10,0.10,0.10,0.70)

        b.txt = b:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        b.txt:SetPoint("CENTER")
        b.txt:SetText(text)

        b:SetScript("OnClick", function() SetTab(i) end)
        tabs[i] = b
    end

    MakeTab(1, "General")
    MakeTab(2, "Castbar")
    MakeTab(3, "Colors")
    MakeTab(4, "Debug")

    -- =====================================================
    -- TAB 1: General
    -- =====================================================
    do
        local p = pages[1]
        local head = MakeLabel(p, "General", "GameFontNormalLarge")
        head:SetPoint("TOPLEFT", 0, 0)

        local enabled = MakeCheck(p, "Enable addon")
        enabled:SetPoint("TOPLEFT", 0, -40)
        enabled:SetChecked(db.enabled == true)
        enabled:SetScript("OnClick", function(self)
            db.enabled = self:GetChecked() and true or false
            RefreshPlates()
        end)
    end

    -- =====================================================
    -- TAB 2: Castbar (ALL settings)
    -- =====================================================
    do
        local p = pages[2]
        local xL, xR = 18, 520
        local y = -8

        db.fonts = db.fonts or { index=1, size=10, outline="OUTLINE" }
        db.skins = db.skins or { index=1 }
        db.interrupt = db.interrupt or { ttl=0.80 }
        db.position = db.position or { attachToBlizz=true, point="CENTER", relPoint="CENTER", x=0, y=0, unlocked=false, alwaysShow=false }

        local iconBtn = MakeButton(p, "Icon: ON", 160, 22)
        iconBtn:SetPoint("TOPLEFT", xL, y)
        local function UpdateIcon() iconBtn:SetText(db.showIcon and "Icon: ON" or "Icon: OFF") end
        iconBtn:SetScript("OnClick", function()
            db.showIcon = not db.showIcon
            UpdateIcon()
            RefreshPlates()
        end)
        UpdateIcon()

        local borderBtn = MakeButton(p, "Border: ON", 160, 22)
        borderBtn:SetPoint("LEFT", iconBtn, "RIGHT", 10, 0)
        local function UpdateBorder() borderBtn:SetText(db.showBorder and "Border: ON" or "Border: OFF") end
        borderBtn:SetScript("OnClick", function()
            db.showBorder = not db.showBorder
            UpdateBorder()
            RefreshPlates()
        end)
        UpdateBorder()

        -- -------------------------------------------------
        -- Position / Preview controls
        -- -------------------------------------------------
        y = y - 38

        local preview = MakeCheck(p, "Always show preview castbar (only on your target)")
        preview:SetPoint("TOPLEFT", xL, y)
        preview:SetChecked(db.position.alwaysShow == true)
        preview:SetScript("OnClick", function(self)
            db.position.alwaysShow = self:GetChecked() and true or false
            RefreshPlates()
        end)

        y = y - 28
        local unlock = MakeCheck(p, "Unlock castbar movement (drag the preview bar)")
        unlock:SetPoint("TOPLEFT", xL, y)
        unlock:SetChecked(db.position.unlocked == true)
        unlock:SetScript("OnClick", function(self)
            db.position.unlocked = self:GetChecked() and true or false
            RefreshPlates()
        end)

        y = y - 28
        local attach = MakeCheck(p, "Anchor to Blizzard castbar (recommended)")
        attach:SetPoint("TOPLEFT", xL, y)
        attach:SetChecked(db.position.attachToBlizz ~= false)
        attach:SetScript("OnClick", function(self)
            db.position.attachToBlizz = self:GetChecked() and true or false
            RefreshPlates()
        end)

        y = y - 18
        CreateSlider(p, "X Offset", xL, y - 18, -300, 300, 1,
            function() return math.floor(tonumber(db.position.x) or 0) end,
            function(v) db.position.x = math.floor(v + 0.5) end,
            "%d"
        )

        y = y - 68
        CreateSlider(p, "Y Offset", xL, y - 18, -300, 300, 1,
            function() return math.floor(tonumber(db.position.y) or 0) end,
            function(v) db.position.y = math.floor(v + 0.5) end,
            "%d"
        )

        local resetPos = MakeButton(p, "Reset Position", 160, 22)
        resetPos:SetPoint("TOPLEFT", xL, y - 90)
        resetPos:SetScript("OnClick", function()
            db.position.point = "CENTER"
            db.position.relPoint = "CENTER"
            db.position.x = 0
            db.position.y = 0
            db.position.attachToBlizz = true
            RefreshPlates()
            -- Re-sync slider texts by forcing a rebuild next toggle
            if UI and UI.frame and UI.frame:IsShown() then
                UI.frame:Hide(); UI.frame:Show()
            end
        end)

        local hint = MakeLabel(p, "Tip: Target ANY unit with a nameplate, enable preview, then drag the bar (when unlocked).", "GameFontHighlightSmall")
        hint:SetPoint("TOPLEFT", xL + 180, y - 86)

        y = y - 140
        CreateSlider(p, "Scale", xL, y, 0.60, 1.60, 0.01,
            function() return db.scale or 1.0 end,
            function(v) db.scale = v end,
            "%.2f"
        )

        y = y - 68
        CreateSlider(p, "Width", xL, y, 90, 320, 1,
            function() return math.floor(db.width or 140) end,
            function(v) db.width = math.floor(v + 0.5) end,
            "%d"
        )

        y = y - 68
        CreateSlider(p, "Height", xL, y, 8, 30, 1,
            function() return math.floor(db.height or 12) end,
            function(v) db.height = math.floor(v + 0.5) end,
            "%d"
        )

        y = y - 68
        CreateSlider(p, "Interrupt Flash Time", xL, y, 0.20, 1.50, 0.05,
            function() return (db.interrupt and db.interrupt.ttl) or 0.80 end,
            function(v) db.interrupt.ttl = v end,
            "%.2f"
        )

        local fontItems = {}
        if ns.Castbar and ns.Castbar.FONTS then
            for _, it in ipairs(ns.Castbar.FONTS) do
                fontItems[#fontItems+1] = { name = it.name }
            end
        end

        local fontLabel = MakeLabel(p, "Font", "GameFontNormal")
        fontLabel:SetPoint("TOPLEFT", xR, -8)

        local fontDD = BuildDropdown(
            p, fontItems,
            function() return db.fonts.index or 1 end,
            function(i) db.fonts.index = i end,
            RefreshPlates
        )
        fontDD:SetPoint("TOPLEFT", xR - 16, -28)

        CreateSlider(p, "Font Size", xR, -110, 8, 20, 1,
            function() return math.floor(db.fonts.size or 10) end,
            function(v) db.fonts.size = math.floor(v + 0.5) end,
            "%d"
        )

        local OUTLINES = {
            { name = "NONE" },
            { name = "OUTLINE" },
            { name = "THICKOUTLINE" },
            { name = "MONOCHROMEOUTLINE" },
        }

        local outlineLabel = MakeLabel(p, "Outline", "GameFontNormal")
        outlineLabel:SetPoint("TOPLEFT", xR, -200)

        local outlineDD = BuildDropdown(
            p, OUTLINES,
            function()
                local o = db.fonts.outline or "OUTLINE"
                for i, it in ipairs(OUTLINES) do
                    if it.name == o then return i end
                end
                return 2
            end,
            function(i) db.fonts.outline = OUTLINES[i].name end,
            RefreshPlates
        )
        outlineDD:SetPoint("TOPLEFT", xR - 16, -220)

        local skinItems = {}
        if ns.Castbar and ns.Castbar.SKINS then
            for _, it in ipairs(ns.Castbar.SKINS) do
                skinItems[#skinItems+1] = { name = it.name }
            end
        end

        local skinLabel = MakeLabel(p, "Skin / Texture", "GameFontNormal")
        skinLabel:SetPoint("TOPLEFT", xR, -300)

        local skinDD = BuildDropdown(
            p, skinItems,
            function() return db.skins.index or 1 end,
            function(i) db.skins.index = i end,
            RefreshPlates
        )
        skinDD:SetPoint("TOPLEFT", xR - 16, -320)
    end

    -- =====================================================
    -- TAB 3: Colors (8 pickers)
    -- =====================================================
    do
        local p = pages[3]
        local head = MakeLabel(p, "Colors (8 pickers)", "GameFontNormalLarge")
        head:SetPoint("TOPLEFT", 0, 0)

        local CP = ns.Util and ns.Util.ColorPicker
        if not (CP and CP.CreateRow) then
            local warn = MakeLabel(p, "ColorPicker util not loaded. (Check colorpicker.lua)", "GameFontNormal")
            warn:SetPoint("TOPLEFT", 0, -40)
        else
            db.colors = db.colors or {}

            local rows = {
                { label = "Normal",             key = "normal" },
                { label = "Important",          key = "important" },
                { label = "NoKick",             key = "noKick" },
                { label = "Interrupted",        key = "interrupted" },
                { label = "Text",               key = "text" },
                { label = "Background",         key = "bg" },
                { label = "Border",             key = "border" },
                { label = "Shield Tint",        key = "shield" },
            }

            local x = 18
            local startY = -50

            for i, r in ipairs(rows) do
                db.colors[r.key] = db.colors[r.key] or { r=1, g=1, b=1, a=1 }
                CP.CreateRow(p, {
                    label = r.label,
                    point = "TOPLEFT",
                    rel = "TOPLEFT",
                    x = x,
                    y = startY - ((i - 1) * 28),
                    color = db.colors[r.key],
                    hasOpacity = true,
                    onChanged = RefreshPlates,
                })
            end
        end
    end

    -- =====================================================
    -- TAB 4: Debug
    -- =====================================================
    do
        local p = pages[4]
        local head = MakeLabel(p, "Debug", "GameFontNormalLarge")
        head:SetPoint("TOPLEFT", 0, 0)

        local reload = MakeButton(p, "Reload UI", 140, 26)
        reload:SetPoint("TOPLEFT", 0, -40)
        reload:SetScript("OnClick", ReloadUI)

        local bgInfo = MakeLabel(p, "BG path: Interface\\AddOns\\"..tostring(ADDON).."\\pombackground1.png", "GameFontHighlightSmall")
        bgInfo:SetPoint("TOPLEFT", 0, -80)
    end

    self.frame = f

    -- Pick default tab
    SetTab(2)

    -- ✅ CRITICAL FIX: Make sure first toggle shows the frame (not hides it)
    f:Hide()
end

function UI:Toggle()
    self:EnsureBuilt()
    if not self.frame then return end
    self.frame:SetShown(not self.frame:IsShown())
end
