local addonName, SinsToolkit = ...

SinsToolkit.UI = SinsToolkit.UI or {}
SinsToolkit.UI.Pages = SinsToolkit.UI.Pages or {}

local PageBase = SinsToolkit.UI.Pages.Base or {}
local Helpers = SinsToolkit.UI.Pages.Helpers or {}
local Page = {}
setmetatable(Page, { __index = PageBase })
SinsToolkit.UI.Pages.CVars = Page
Page.density = Helpers.GetDefaultDensity and Helpers.GetDefaultDensity() or "compact"

function Page:Create(CreateScrollablePage, Window, CreateWrappedText)
    local Theme = Helpers.GetTheme and Helpers.GetTheme()
    local cvarsPage = Helpers.CreateContentPage(Window, "CVars")
    local cvHeader = Window:CreateSectionHeader(cvarsPage, "CVar Browser")

    CreateWrappedText(cvarsPage, {"TOPLEFT", cvHeader, "BOTTOMLEFT", 0, -8}, 720, "Browse live client CVars, compare current values against Blizzard defaults, filter modified values, edit supported CVars, and reset values when the client allows it. Modified CVars appear green in the list.", "GameFontHighlightSmall")

    local cvSearch = Window:CreateEditBox(cvarsPage, "Search CVars", 200, 24, function() return Window.cvarSearchString or "" end, function(v) Window.cvarSearchString = v; Window.RefreshCVarsList() end, "Search by CVar name, category, or client-provided description.")
    cvSearch:SetPoint("TOPLEFT", cvHeader, "BOTTOMLEFT", 0, -66)

    local cvModOnly = Window:CreateCheckbox(cvarsPage, "Modified Only", function() return Window.cvarModifiedOnly end, function(v) Window.cvarModifiedOnly = v; Window.RefreshCVarsList() end, "Only show CVars where the current value differs from the client default.")
    cvModOnly:SetPoint("LEFT", cvSearch, "RIGHT", 10, 0)

    local cvRefresh = Window:CreateButton(cvarsPage, "Refresh List", 100, 24, function() if SinsToolkit.CVars then SinsToolkit.CVars:Refresh(); Window.RefreshCVarsList() end end, "Refreshes the CVar list and current/default values from the WoW client.")
    cvRefresh:SetPoint("LEFT", cvModOnly, "RIGHT", 120, 0)

    local cvListBg = CreateFrame("Frame", nil, cvarsPage, "BackdropTemplate")
    cvListBg:SetPoint("TOPLEFT", cvSearch, "BOTTOMLEFT", -5, -15)
    cvListBg:SetPoint("BOTTOMLEFT", cvarsPage, "BOTTOMLEFT", 0, 0)
    cvListBg:SetWidth(250)
    Helpers.ApplyListBackdrop(cvListBg, 0.1, 0.1, 0.1, 0.8, 0.4, 0.4, 0.4, 1)

    local cvScroll = CreateFrame("ScrollFrame", nil, cvListBg, "UIPanelScrollFrameTemplate")
    cvScroll:SetPoint("TOPLEFT", 4, -4)
    cvScroll:SetPoint("BOTTOMRIGHT", -26, 4)
    local cvScrollChild = CreateFrame("Frame", nil, cvScroll)
    cvScrollChild:SetSize(220, 1)
    cvScroll:SetScrollChild(cvScrollChild)

    local cvDetails = cvarsPage:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    cvDetails:SetPoint("TOPLEFT", cvListBg, "TOPRIGHT", 20, 0)
    cvDetails:SetPoint("BOTTOMRIGHT", cvarsPage, "BOTTOMRIGHT", 0, 155)
    cvDetails:SetJustifyH("LEFT")
    cvDetails:SetJustifyV("TOP")
    if Theme and Theme.ApplyBodyFont then Theme.ApplyBodyFont(cvDetails) end

    local cvValBox = Window:CreateEditBox(cvarsPage, "New Value", 200, 24, function() return Window.cvarPendingValue or "" end, function(v) Window.cvarPendingValue = v end, "Enter the value to apply to the selected CVar.")
    cvValBox:SetPoint("BOTTOMLEFT", cvListBg, "BOTTOMRIGHT", 20, 10)

    local cvApply = Window:CreateButton(cvarsPage, "Apply", 80, 24, function()
        if SinsToolkit.CVars and Window.cvarSelected and Window.cvarPendingValue then
            local ok, msg = SinsToolkit.CVars:SetValue(Window.cvarSelected, Window.cvarPendingValue)
            print("|cff9b59b6[Sin's Toolkit: QOL]|r " .. (msg or (ok and "CVar updated." or "CVar update failed.")))
            Window.RefreshCVarsList()
        end
    end, "Applies the new value to the selected CVar.")
    cvApply:SetPoint("LEFT", cvValBox, "RIGHT", 10, 0)

    local cvReset = Window:CreateButton(cvarsPage, "Reset to Default", 120, 24, function()
        if SinsToolkit.CVars and Window.cvarSelected then
            local ok, msg = SinsToolkit.CVars:ResetToDefault(Window.cvarSelected)
            print("|cff9b59b6[Sin's Toolkit: QOL]|r " .. (msg or (ok and "CVar reset." or "CVar reset failed.")))
            Window.RefreshCVarsList()
        end
    end, "Sets the selected CVar back to the default value reported by the WoW client.")
    cvReset:SetPoint("LEFT", cvApply, "RIGHT", 10, 0)

    local cvModifiedSummary = cvarsPage:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    cvModifiedSummary:SetPoint("TOPLEFT", cvValBox, "BOTTOMLEFT", 0, -18)
    cvModifiedSummary:SetPoint("BOTTOMRIGHT", cvarsPage, "BOTTOMRIGHT", 0, 0)
    cvModifiedSummary:SetJustifyH("LEFT")
    cvModifiedSummary:SetJustifyV("TOP")
    if Theme and Theme.ApplySmallBodyFont then Theme.ApplySmallBodyFont(cvModifiedSummary) end

    local cvarButtons = {}
    function Window.RefreshCVarsList()
        for _, b in ipairs(cvarButtons) do b:Hide() end
        if not SinsToolkit.CVars then return end
        local vals = SinsToolkit.CVars:GetValues(Window.cvarSearchString, Window.cvarModifiedOnly)
        local res = {}
        for k in pairs(vals) do if k ~= "" and k ~= "Select a CVar" then table.insert(res, k) end end
        table.sort(res)

        local y = 0
        local hasSelection = false
        for i, cvarName in ipairs(res) do
            local b = cvarButtons[i]
            if not b then
                b = CreateFrame("Button", nil, cvScrollChild, "BackdropTemplate")
                b:SetSize(220, 24)
                b.text = b:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                b.text:SetPoint("LEFT", 4, 0)
                b.text:SetPoint("RIGHT", -4, 0)
                b.text:SetJustifyH("LEFT")
                if Theme and Theme.ApplySmallBodyFont then Theme.ApplySmallBodyFont(b.text) end
                b:SetScript("OnClick", function(self)
                    Window.cvarSelected = self.cvarName
                    local info = SinsToolkit.CVars:GetInfo(self.cvarName)
                    Window.cvarPendingValue = info and tostring(info.value or "") or ""
                    cvValBox:SetText(Window.cvarPendingValue)
                    Window.RefreshCVarsList()
                end)
                cvarButtons[i] = b
            end
            b.cvarName = cvarName
            b:SetPoint("TOPLEFT", 0, y)
            b.text:SetText(vals[cvarName])
            if Window.cvarSelected == cvarName then
                Helpers.ApplySelectionBackdrop(b)
                hasSelection = true
            else
                b:SetBackdrop(nil)
            end
            b:Show()
            y = y - 24
        end

        if not hasSelection then Window.cvarSelected = nil end
        cvScrollChild:SetHeight(math.max(1, -y))

        if Window.cvarSelected then
            cvDetails:SetText(SinsToolkit.CVars:GetSummary(Window.cvarSelected))
            cvValBox:Show()
            cvApply:Show()
            cvReset:Show()
        else
            cvDetails:SetText("Select a CVar from the list.")
            cvValBox:Hide()
            cvApply:Hide()
            cvReset:Hide()
        end
        cvModifiedSummary:SetText(SinsToolkit.CVars:GetModifiedSummary(10))
    end
    cvarsPage.OnShowCallback = Window.RefreshCVarsList

    self.frame = cvarsPage
    return cvarsPage
end

Page:Register("CVars")

return Page
