local addonName, NS = ...

-- =========================================================================
-- SAFE REFERENCE & LOCAL HELPERS
-- =========================================================================

local GR = _G["GRS_MainFrame"] or NS.GR

-- If GR doesn't exist yet, we can't attach methods.
if not GR then
    print("|cffff0000GRS Error:|r Main Frame not found in Settings.lua")
    return
end

-- Helper: Create or Update Background
local function SafeCreateBg(f, r, g, b, a)
    if not f then return end
    if f.bg then
        f.bg:SetColorTexture(r, g, b, a)
    else
        local t = f:CreateTexture(nil, "BORDER")
        t:SetAllPoints()
        t:SetColorTexture(r, g, b, a)
        f.bg = t
    end
end

-- Helper: Create or Update Border
local function SafeCreateBorder(f, r, g, b, a)
    if not f then return end
    if f.border then
        f.border:SetColorTexture(r, g, b, a)
    else
        local border = f:CreateTexture(nil, "BACKGROUND")
        border:SetPoint("TOPLEFT", -1, 1)
        border:SetPoint("BOTTOMRIGHT", 1, -1)
        border:SetColorTexture(r, g, b, a)
        f.border = border
    end
end

-- Helper: Skin Button
local function SafeSkinButton(btn)
    if not btn then return end
    btn:SetNormalTexture("")
    btn:SetHighlightTexture("")
    btn:SetPushedTexture("")
    btn:SetDisabledTexture("")
    
    if btn.Left then btn.Left:SetAlpha(0) end
    if btn.Middle then btn.Middle:SetAlpha(0) end
    if btn.Right then btn.Right:SetAlpha(0) end
    
    SafeCreateBg(btn, 0.2, 0.2, 0.2, 1)
    SafeCreateBorder(btn, 0, 0, 0, 1)
    
    -- Force Gold Text
    if btn.GetFontString and btn:GetFontString() then
        btn:GetFontString():SetTextColor(1, 0.82, 0)
    end

    btn:HookScript("OnEnter", function(s) 
        if s.bg then s.bg:SetColorTexture(0.3, 0.3, 0.3, 1) end 
    end)
    btn:HookScript("OnLeave", function(s) 
        if s.bg then s.bg:SetColorTexture(0.2, 0.2, 0.2, 1) end 
    end)
end

-- Helper: Create Slider
local function CreateColorSlider(parent, label, getVal, setVal)
    local s = CreateFrame("Slider", nil, parent, "OptionsSliderTemplate")
    s:SetWidth(180) 
    s:SetHeight(15)
    s:SetMinMaxValues(0, 1)
    s:SetValueStep(0.01)
    s:SetObeyStepOnDrag(true)
    
    local txt = s:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    txt:SetPoint("BOTTOMLEFT", s, "TOPLEFT", 0, 2)
    txt:SetText(label)

    local val = s:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    val:SetPoint("BOTTOMRIGHT", s, "TOPRIGHT", 0, 2)
    
    -- Strip Blizz text
    local n = s:GetName()
    if n then 
        if _G[n.."Low"] then _G[n.."Low"]:SetText("") end
        if _G[n.."High"] then _G[n.."High"]:SetText("") end
        if _G[n.."Text"] then _G[n.."Text"]:SetText("") end
    end
    
    -- Safety check for getVal
    local initialVal = 0
    if getVal then initialVal = getVal() or 0 end
    
    s:SetValue(initialVal)
    val:SetText(string.format("%.2f", initialVal))

    s:SetScript("OnValueChanged", function(self, v)
        v = math.floor(v * 100 + 0.5) / 100
        val:SetText(string.format("%.2f", v))
        if setVal then setVal(v) end
    end)
    
    return s
end

-- =========================================================================
-- 1. SETTINGS VIEW BUILDER
-- =========================================================================

function GR:BuildSettingsView()
    -- Defaults
    if not self.db then self.db = {} end
    if not self.db.theme then self.db.theme = {} end
    
    local d = self.db.theme
    if not d.header then d.header = {r=0.1, g=0.1, b=0.2, a=1} end
    if not d.background then d.background = {r=0.05, g=0.05, b=0.05, a=0.95} end
    if not d.buttons then d.buttons = {r=0.2, g=0.2, b=0.2, a=1} end

    -- Create the Settings Container (Fills the ViewContainer)
    local parent = CreateFrame("Frame", "GRS_SettingsView", self.ViewContainer)
    parent:SetAllPoints()
    parent:Hide()
    self.views[7] = parent

    -- Main Settings Canvas
    local canvas = CreateFrame("Frame", nil, parent)
    canvas:SetAllPoints()
    SafeCreateBg(canvas, 0.1, 0.1, 0.1, 1) 
    self.SettingsCanvas = canvas

    -- Helper to update live
    local function UpdateLiveTheme()
        GR:ApplyTheme(nil) 
    end

    -- =========================================================
    -- PANE 1: LEFT (Width 500) - UI Scale & General
    -- =========================================================
    local paneLeft = CreateFrame("Frame", nil, canvas)
    -- [[ GEOMETRY UPDATE: 15px Left Offset, -50px Top Offset, 30px Bottom Offset ]]
    paneLeft:SetPoint("TOPLEFT", 15, -50)
    paneLeft:SetPoint("BOTTOMLEFT", 15, 30)
    paneLeft:SetWidth(500)
    SafeCreateBorder(paneLeft, 0.3, 0.3, 0.3, 1)
    SafeCreateBg(paneLeft, 0.08, 0.08, 0.08, 0.5)

    -- Header
    local hdrLeft = paneLeft:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    hdrLeft:SetPoint("TOPLEFT", 15, -15)
    hdrLeft:SetText("General Settings")

    -- UI Scale
    local lblScale = paneLeft:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    lblScale:SetPoint("TOPLEFT", 20, -60)
    lblScale:SetText("UI Scale")
    
    local valScale = paneLeft:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    valScale:SetPoint("LEFT", lblScale, "RIGHT", 10, 0)
    valScale:SetText(string.format("%.2f", self.db.scale or 1.0))

    local sliderScale = CreateFrame("Slider", "GRS_ScaleSlider", paneLeft, "OptionsSliderTemplate")
    sliderScale:SetPoint("TOPLEFT", 20, -85)
    sliderScale:SetWidth(460)
    sliderScale:SetMinMaxValues(0.6, 1.4)
    sliderScale:SetValueStep(0.05)
    sliderScale:SetObeyStepOnDrag(true)
    
    local sName = sliderScale:GetName()
    if _G[sName.."Low"] then _G[sName.."Low"]:SetText("") end
    if _G[sName.."High"] then _G[sName.."High"]:SetText("") end
    if _G[sName.."Text"] then _G[sName.."Text"]:SetText("") end

    sliderScale:SetValue(self.db.scale or 1.0)
    
    sliderScale:SetScript("OnValueChanged", function(s, val)
        local v = math.floor(val * 100 + 0.5) / 100
        valScale:SetText(string.format("%.2f", v))
    end)
    
    sliderScale:SetScript("OnMouseUp", function(s)
        local v = math.floor(s:GetValue() * 100 + 0.5) / 100
        if GR.db then GR.db.scale = v end
        GR:SetScale(v)
    end)

    -- [[ COMPACT MODE CONTROLS ]]
    local yOffset = -120

    -- Checkbox: Compact Mode
    local chkCompact = CreateFrame("CheckButton", nil, paneLeft, "UICheckButtonTemplate")
    chkCompact:SetPoint("TOPLEFT", 20, yOffset)
    chkCompact:SetSize(24, 24)
    chkCompact.text = chkCompact:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    chkCompact.text:SetPoint("LEFT", chkCompact, "RIGHT", 5, 1)
    chkCompact.text:SetText("Enable Compact Mode")
    chkCompact:SetChecked(self.db.compactMode or false)
    chkCompact:SetScript("OnClick", function(s)
        self.db.compactMode = s:GetChecked()
    end)

    yOffset = yOffset - 30

    -- Checkbox: Bypass Search Filter
    local chkBypass = CreateFrame("CheckButton", nil, paneLeft, "UICheckButtonTemplate")
    chkBypass:SetPoint("TOPLEFT", 20, yOffset)
    chkBypass:SetSize(24, 24)
    chkBypass.text = chkBypass:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    chkBypass.text:SetPoint("LEFT", chkBypass, "RIGHT", 5, 1)
    chkBypass.text:SetText("Bypass Search Filter")
    chkBypass:SetChecked(self.db.bypassFilter or false)
    chkBypass:SetScript("OnClick", function(s)
        self.db.bypassFilter = s:GetChecked()
    end)

    yOffset = yOffset - 35

    -- Button: Adjust (Triggers UI Rebuild)
    local btnAdjust = CreateFrame("Button", nil, paneLeft, "UIPanelButtonTemplate")
    btnAdjust:SetSize(120, 30)
    btnAdjust:SetPoint("TOPLEFT", 20, yOffset)
    btnAdjust:SetText("Adjust")
    btnAdjust:SetScript("OnClick", function()
        -- Calls logic defined in Compact_Mode.lua
        if GR.ToggleCompactMode then
            GR:ToggleCompactMode(GR.db.compactMode)
        else
            print("|cffff0000GRS:|r Compact Module not loaded.")
        end
    end)
    SafeSkinButton(btnAdjust)

    -- Reload Button (Pane 1 Bottom)
    local txtReload = paneLeft:CreateFontString(nil, "OVERLAY", "GameFontRedSmall")
    txtReload:SetPoint("BOTTOMLEFT", 20, 50)
    txtReload:SetText("Reload UI for scale/theme changes")

    local btnReload = CreateFrame("Button", nil, paneLeft, "UIPanelButtonTemplate")
    btnReload:SetSize(120, 30)
    btnReload:SetPoint("BOTTOMLEFT", 20, 15)
    btnReload:SetText("Reload UI")
    btnReload:SetScript("OnClick", function() C_UI.Reload() end)
    SafeSkinButton(btnReload)


    -- =========================================================
    -- PANE 2: MIDDLE (Vertical Stack) - Colors
    -- =========================================================
    local paneMid = CreateFrame("Frame", nil, canvas)
    -- Anchored to paneLeft, so it inherits the geometry (x offset + y offsets)
    paneMid:SetPoint("TOPLEFT", paneLeft, "TOPRIGHT", 0, 0)
    paneMid:SetPoint("BOTTOMLEFT", paneLeft, "BOTTOMRIGHT", 0, 0)
    paneMid:SetWidth(250)
    SafeCreateBorder(paneMid, 0.3, 0.3, 0.3, 1)

    local function CreateSubPane(relPoint, yOff, title, desc)
        local f = CreateFrame("Frame", nil, paneMid)
        if relPoint then
            f:SetPoint("TOPLEFT", relPoint, "BOTTOMLEFT", 0, yOff)
            f:SetPoint("TOPRIGHT", relPoint, "BOTTOMRIGHT", 0, yOff)
        else
            f:SetPoint("TOPLEFT", 0, 0)
            f:SetPoint("TOPRIGHT", 0, 0)
        end
        -- [[ GEOMETRY FIX: Calculate sub-pane height based on reduced parent height (-80px) ]]
        f:SetHeight((canvas:GetHeight() - 80) / 3)
        SafeCreateBorder(f, 0.2, 0.2, 0.2, 1)
        
        local t = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        t:SetPoint("TOP", 0, -10)
        t:SetText(title)

        if desc then
            local d = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
            d:SetPoint("TOPLEFT", 10, -30)
            d:SetWidth(230)
            d:SetJustifyH("LEFT")
            d:SetText(desc)
        end
        return f
    end

    local function MakeColorControls(parent, yStart, dbKey, useAlpha)
        local function GetCol(k) 
             local t = GR.db.theme[dbKey]
             return t and t[k] or (k == "a" and 1 or 0)
        end
        local function SetCol(k, v)
             if GR.db.theme[dbKey] then GR.db.theme[dbKey][k] = v; UpdateLiveTheme() end
        end

        local rS = CreateColorSlider(parent, "Red", function() return GetCol("r") end, function(v) SetCol("r", v) end)
        rS:SetPoint("TOP", 0, yStart)

        local gS = CreateColorSlider(parent, "Green", function() return GetCol("g") end, function(v) SetCol("g", v) end)
        gS:SetPoint("TOP", 0, yStart - 35)

        local bS = CreateColorSlider(parent, "Blue", function() return GetCol("b") end, function(v) SetCol("b", v) end)
        bS:SetPoint("TOP", 0, yStart - 70)
        
        if useAlpha then
            local aS = CreateColorSlider(parent, "Alpha", function() return GetCol("a") end, function(v) SetCol("a", v) end)
            aS:SetPoint("TOP", 0, yStart - 105)
        else
            if GR.db.theme[dbKey] then GR.db.theme[dbKey].a = 1 end
        end
    end

    -- SUB-PANE 1: HEADER
    local subTop = CreateSubPane(nil, 0, "Header / Sidebar", "Title Bar & Sidebar Colors")
    MakeColorControls(subTop, -50, "header", false)

    -- SUB-PANE 2: BACKGROUND
    local subMid = CreateSubPane(subTop, 0, "Background Pane", nil)
    MakeColorControls(subMid, -40, "background", true)

    -- SUB-PANE 3: BUTTONS
    local subBot = CreateSubPane(subMid, 0, "Buttons & Text", nil)
    MakeColorControls(subBot, -40, "buttons", false)

end

function GR:OpenSettings()
    self._settingsPrevTab = self.activeTab or 1
    self:SwitchView(7)
end

function GR:CloseSettings()
    local back = self._settingsPrevTab or 1
    if back == 7 then back = 1 end
    self:SwitchView(back)
end

-- =========================================================================
-- 2. RECOLOR / THEME ENGINE
-- =========================================================================

local function RecursiveColor(frame, theme, depth)
    if not frame then return end
    if depth > 20 then return end 

    local isButton = frame:IsObjectType("Button")
    
    -- Color Background
    if frame.bg and frame.bg.SetColorTexture then
        if isButton then
            frame.bg:SetColorTexture(theme.buttons.r, theme.buttons.g, theme.buttons.b, theme.buttons.a)
        else
            frame.bg:SetColorTexture(theme.background.r, theme.background.g, theme.background.b, theme.background.a)
        end
    end

    -- Color Border
    if frame.border and frame.border.SetColorTexture then
        if isButton then
            frame.border:SetColorTexture(0, 0, 0, 1)
        else
            frame.border:SetColorTexture(theme.buttons.r, theme.buttons.g, theme.buttons.b, 1) 
        end
    end
    
    -- Color Text
    if isButton and frame.GetFontString and frame:GetFontString() then
        frame:GetFontString():SetTextColor(1, 0.82, 0) 
    end

    -- Traverse Children
    local children = {frame:GetChildren()}
    for _, child in ipairs(children) do
        if not child:IsForbidden() then
            RecursiveColor(child, theme, depth + 1)
        end
    end
end

function GR:ApplyTheme(inputTheme)
    local t = inputTheme
    if not t and self.db and self.db.theme then
        t = self.db.theme
    end
    
    if not t or not t.header then
        t = {
            header = {r=0.1, g=0.1, b=0.2, a=1},
            background = {r=0.05, g=0.05, b=0.05, a=0.95},
            buttons = {r=0.2, g=0.2, b=0.2, a=1}
        }
    end

    -- 1. Main Window BG (Solid Only)
    if self.bg then
        self.bg:SetTexture(nil) 
        self.bg:SetBlendMode("BLEND")
        self.bg:SetColorTexture(t.background.r, t.background.g, t.background.b, t.background.a)
    end

    -- 2. Title Bar & Sidebar
    if self.TitleBar and self.TitleBar.bg then
        self.TitleBar.bg:SetColorTexture(t.header.r, t.header.g, t.header.b, t.header.a)
    end
    if self.SideBar and self.SideBar.bg then
        self.SideBar.bg:SetColorTexture(t.header.r, t.header.g, t.header.b, t.header.a)
    end
    
    -- 3. Recursive coloring
    if self.SettingsCanvas then
         RecursiveColor(self.SettingsCanvas, t, 0)
    end
end

-- =========================================================================
-- 3. INITIALIZATION & HOOKS
-- =========================================================================

hooksecurefunc(GR, "SwitchView", function(self, viewIndex)
    if not self.db or not self.db.theme then return end
    self:ApplyTheme(nil)
end)

hooksecurefunc(GR, "Initialize", function(self)
    C_Timer.After(0.2, function()
        if not self.db.theme then self.db.theme = {} end
        local d = self.db.theme
        if not d.header then d.header = {r=0.1, g=0.1, b=0.2, a=1} end
        if not d.background then d.background = {r=0.05, g=0.05, b=0.05, a=0.95} end
        if not d.buttons then d.buttons = {r=0.2, g=0.2, b=0.2, a=1} end

        self:ApplyTheme(nil)
        
        -- [[ COMPACT MODE INIT ]]
        -- If saved variable is true, apply compact mode on load
        if GR.db.compactMode and GR.ToggleCompactMode then
            GR:ToggleCompactMode(true)
        end
    end)
end)