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.FrameTools = Page
Page.density = Helpers.GetDefaultDensity and Helpers.GetDefaultDensity() or "compact"

local POSITION_SAVE_OPTIONS = {
    { value = "permanent", text = "Permanent" },
    { value = "session", text = "Session" },
}

local SCALE_SAVE_OPTIONS = {
    { value = "permanent", text = "Permanent" },
    { value = "session", text = "Session" },
    { value = "off", text = "None" },
}

function Page:Create(CreateScrollablePage, Window, CreateWrappedText)
    local getGV = Helpers.GetGV
    local setGV = Helpers.SetGV
    local GetToolkitValue = Helpers.GetToolkitValue

    local page, content = CreateScrollablePage("Frame Tools")
    Helpers.CreatePageIntro(content, Window, "Frame Tools", "Move, scale, save, and reset supported Blizzard windows. Panel behavior options remain grouped here for frame-related workflows.", CreateWrappedText, 660)

    local grid = Helpers.CreateSettingsGrid(content, {
        leftX = 10,
        rightX = 350,
        topY = -92,
        cardWidth = 320,
        gap = 12,
        bottomPadding = 140,
    })
    local rowGap = 6

    local moverCard = grid:AddCard(1, "Frame Mover", 156)
    Helpers.SetCardDescription(moverCard, "Movement and scaling controls.")
    local cbMover = Helpers.AnchorFirstControl(Window:CreateCheckbox(moverCard, "Enable Frame Mover", getGV("frameMoverEnabled"), setGV("frameMoverEnabled"), "Globally enables or disables the Frame Mover feature."), moverCard, 12, -58)
    local requireShift = Helpers.AnchorBelow(Window:CreateCheckbox(moverCard, "Require Shift to Move", getGV("frameMoverRequireModifier"), setGV("frameMoverRequireModifier"), "If checked, you must hold Shift to move frames."), cbMover, 0, rowGap)
    Helpers.AnchorBelow(Window:CreateCheckbox(moverCard, "Ctrl + Mouse Wheel Scaling", getGV("frameMoverCtrlScrollScale"), setGV("frameMoverCtrlScrollScale"), "Allows Ctrl + mouse wheel over supported frames to adjust scale."), requireShift, 0, rowGap)

    local savingCard = grid:AddCard(1, "Saving", 184)
    Helpers.SetCardDescription(savingCard, "Position and scale persistence.")
    local posMode = Helpers.CreateOptionGroup(Window, savingCard, "Position Saving", POSITION_SAVE_OPTIONS, function()
        local value = GetToolkitValue("frameMoverPositionMode")
        return value == "permanent" and "permanent" or "session"
    end, setGV("frameMoverPositionMode"), "Session saves until logout/reload. Permanent saves across sessions.")
    posMode:SetPoint("TOPLEFT", savingCard, "TOPLEFT", 16, -58)

    local scaleMode = Helpers.CreateOptionGroup(Window, savingCard, "Scale Saving", SCALE_SAVE_OPTIONS, function()
        local value = GetToolkitValue("frameMoverScaleMode")
        if value == "off" or value == "permanent" then return value end
        return "session"
    end, setGV("frameMoverScaleMode"), "Session saves until logout/reload. Permanent saves across sessions. None disables scale saving.")
    scaleMode:SetPoint("TOPLEFT", posMode, "BOTTOMLEFT", 0, -8)

    local utilitiesCard = grid:AddCard(1, "Utilities", 96)
    Helpers.SetCardDescription(utilitiesCard, "Reset saved frame data.")
    local resetPos = Window:CreateButton(utilitiesCard, "Reset All Positions & Scales", 220, 26, function()
        if SinsToolkit.FrameMover and SinsToolkit.FrameMover.ResetAll then SinsToolkit.FrameMover:ResetAll() end
    end, "Clears all saved Frame Mover positions and scales.")
    resetPos:SetPoint("TOPLEFT", utilitiesCard, "TOPLEFT", 16, -56)

    local statusCard = Helpers.ClearCardBody(grid:AddCard(2, "Status", 176))
    local statusRows = Helpers.CreatePropertyRows(statusCard, {
        { label = "Mover", value = "Unknown" },
        { label = "Position Save", value = "session" },
        { label = "Scale Save", value = "session" },
        { label = "Modifier", value = "None" },
        { label = "Registered", value = "0" },
        { label = "Saved", value = "0 positions / 0 scales" },
    }, { x = 16, y = -42, labelWidth = 96, valueWidth = 174, rowHeight = 18 })

    local panelCard = grid:AddCard(2, "Panel Behavior", 132)
    Helpers.SetCardDescription(panelCard, "Additional options affecting panel behavior.")
    local cbNoAutoClose = Helpers.AnchorFirstControl(Window:CreateCheckbox(panelCard, "Keep Panels Open", getGV("keepPanelsOpen"), setGV("keepPanelsOpen"), "Keeps supported Blizzard panels open together. This is the same setting found on the UI Tweaks page. Reload after disabling."), panelCard, 12, -58)
    Helpers.AnchorBelow(Window:CreateCheckbox(panelCard, "Respect Excluded Frames", function()
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        return SinsToolkitDB and SinsToolkitDB.noAutoClose and SinsToolkitDB.noAutoClose.respectExcludedFrames ~= false
    end, function(value)
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        if SinsToolkitDB and SinsToolkitDB.noAutoClose then
            SinsToolkitDB.noAutoClose.respectExcludedFrames = value
        end
        if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end
    end, "Leaves sensitive frames such as cinematics, barbershop, and trading post under Blizzard control."), cbNoAutoClose, 0, rowGap)

    local defaultsCard = grid:AddCard(2, "Defaults", 270)
    Helpers.SetCardDescription(defaultsCard, "Default panel placement when no position is saved.")
    local anchor = Window:CreateCycleButton(defaultsCard, "Default Anchor", { TOPLEFT = "Top Left", TOP = "Top", TOPRIGHT = "Top Right", CENTER = "Center" }, function()
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        return SinsToolkitDB and SinsToolkitDB.noAutoClose and SinsToolkitDB.noAutoClose.defaultPosition and SinsToolkitDB.noAutoClose.defaultPosition.anchor or "TOPLEFT"
    end, function(value)
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        if SinsToolkitDB and SinsToolkitDB.noAutoClose and SinsToolkitDB.noAutoClose.defaultPosition then
            SinsToolkitDB.noAutoClose.defaultPosition.anchor = value
        end
        if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end
    end, "Default anchor used when a panel loses its Blizzard layout point.")
    anchor:SetPoint("TOPLEFT", defaultsCard, "TOPLEFT", 16, -62)

    local x = Window:CreateSlider(defaultsCard, "Default X Offset", function()
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        return SinsToolkitDB and SinsToolkitDB.noAutoClose and SinsToolkitDB.noAutoClose.defaultPosition and SinsToolkitDB.noAutoClose.defaultPosition.x or 50
    end, function(value)
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        if SinsToolkitDB and SinsToolkitDB.noAutoClose and SinsToolkitDB.noAutoClose.defaultPosition then
            SinsToolkitDB.noAutoClose.defaultPosition.x = value
        end
        if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end
    end, -900, 900, 1, "Default X offset for Keep Panels Open placement.")
    x:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", -4, -30)

    local y = Window:CreateSlider(defaultsCard, "Default Y Offset", function()
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        return SinsToolkitDB and SinsToolkitDB.noAutoClose and SinsToolkitDB.noAutoClose.defaultPosition and SinsToolkitDB.noAutoClose.defaultPosition.y or -50
    end, function(value)
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        if SinsToolkitDB and SinsToolkitDB.noAutoClose and SinsToolkitDB.noAutoClose.defaultPosition then
            SinsToolkitDB.noAutoClose.defaultPosition.y = value
        end
        if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end
    end, -900, 900, 1, "Default Y offset for Keep Panels Open placement.")
    y:SetPoint("TOPLEFT", x, "BOTTOMLEFT", 0, -42)

    page.OnShowCallback = function()
        if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
        local registered = 0
        local numPositions = 0
        local numScales = 0
        if SinsToolkitDB and SinsToolkitDB.frameMoverPositions then
            for _ in pairs(SinsToolkitDB.frameMoverPositions) do numPositions = numPositions + 1 end
        end
        if SinsToolkitDB and SinsToolkitDB.frameScales then
            for _ in pairs(SinsToolkitDB.frameScales) do numScales = numScales + 1 end
        end
        if SinsToolkit.FrameMover and SinsToolkit.FrameMover.GetRegisteredFrameCount then
            registered = SinsToolkit.FrameMover:GetRegisteredFrameCount()
        end
        local enabled = SinsToolkit.IsFeatureActive and SinsToolkit.IsFeatureActive("frameMoverEnabled")
        Helpers.UpdatePropertyRows(statusRows, {
            { label = "Mover", value = enabled and "|cff00ff00Enabled|r" or "|cffff4040Disabled|r" },
            { label = "Position Save", value = SinsToolkitDB and SinsToolkitDB.frameMoverPositionMode or "session" },
            { label = "Scale Save", value = SinsToolkitDB and SinsToolkitDB.frameMoverScaleMode or "session" },
            { label = "Modifier", value = SinsToolkitDB and SinsToolkitDB.frameMoverRequireModifier and "Shift" or "None" },
            { label = "Registered", value = tostring(registered) },
            { label = "Saved", value = ("%d positions / %d scales"):format(numPositions, numScales) },
        })
        if page.GetParent and page:GetParent().SetScrollVertical then
            page:GetParent():SetScrollVertical(0)
        end
    end

    Helpers.SetScrollChildHeight(content, grid, 650, 150)
    self.frame = page
    return page
end

Page:Register("Frame Tools")

return Page
