local addonName, SinsToolkit = ...

local OWNER_VALUES = {
    SINS = "Sin's Toolkit",
    ORIGINAL = "Original addon",
}

local MODE_VALUES = {
    off = "Off",
    session = "Session",
    permanent = "Permanent",
}

local function EnsureDB()
    if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
end

local function GetValue(key)
    EnsureDB()
    return SinsToolkitDB and SinsToolkitDB[key]
end

local function SetValue(key, value)
    EnsureDB()
    SinsToolkitDB[key] = value
    if SinsToolkit.TriggerUpdate then SinsToolkit.TriggerUpdate(key) end
end

local function GetOwner(featureKey)
    return SinsToolkit.GetFeatureOwner and SinsToolkit.GetFeatureOwner(featureKey) or "SINS"
end

local function SetOwner(featureKey, value)
    if SinsToolkit.SetFeatureOwner then SinsToolkit.SetFeatureOwner(featureKey, value) end
    if featureKey == "frameMoverEnabled" and SinsToolkit.ApplyFrameMover then SinsToolkit.ApplyFrameMover() end
    if featureKey == "keepPanelsOpen" and SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end
end

local function ConflictLine(featureKey)
    local text = SinsToolkit.GetFeatureConflictText and SinsToolkit.GetFeatureConflictText(featureKey)
    return text or "No matching external addon loaded."
end

function SinsToolkit.GetFrameToolsElvUIOptions(GradientText, PageIntro)
    return {
        type = "group",
        name = GradientText and GradientText("Frame Tools") or "Frame Tools",
        order = 5.2,
        args = {
            intro = PageIntro and PageIntro("Frame Tools", "Toolkit-owned No Auto Close and frame moving/scaling controls. If the original addons are installed, choose which addon owns each feature.") or nil,
            conflictHeader = { type = "header", name = "Conflict Ownership", order = 1 },
            noAutoCloseOwner = {
                type = "select",
                name = "No Auto Close Owner",
                desc = "Choose whether Sin's Toolkit or the original NoAutoClose addon owns no-auto-close behavior when both are installed.",
                values = OWNER_VALUES,
                order = 2,
                get = function() return GetOwner("keepPanelsOpen") end,
                set = function(_, value) SetOwner("keepPanelsOpen", value) end,
            },
            noAutoCloseConflict = { type = "description", name = function() return ConflictLine("keepPanelsOpen") end, fontSize = "medium", order = 3 },
            blizzMoveOwner = {
                type = "select",
                name = "Frame Mover Owner",
                desc = "Choose whether Sin's Toolkit or BlizzMove owns frame moving/scaling when both are installed.",
                values = OWNER_VALUES,
                order = 4,
                get = function() return GetOwner("frameMoverEnabled") end,
                set = function(_, value) SetOwner("frameMoverEnabled", value) end,
            },
            blizzMoveConflict = { type = "description", name = function() return ConflictLine("frameMoverEnabled") end, fontSize = "medium", order = 5 },
            noAutoCloseHeader = { type = "header", name = "No Auto Close", order = 10 },
            keepPanelsOpen = {
                type = "toggle",
                name = "No Auto Close Panels",
                desc = "Keeps supported Blizzard panels open together. Reload after disabling because Blizzard panel layout hooks are persistent for the session.",
                order = 11,
                get = function() return GetValue("keepPanelsOpen") end,
                set = function(_, value) SetValue("keepPanelsOpen", value) end,
            },
            respectExcludedFrames = {
                type = "toggle",
                name = "Respect Excluded Frames",
                desc = "Leaves sensitive frames such as cinematics, barbershop, communities, player housing editor, and trading post under Blizzard control.",
                order = 12,
                get = function() EnsureDB(); return SinsToolkitDB.noAutoClose.respectExcludedFrames ~= false end,
                set = function(_, value) EnsureDB(); SinsToolkitDB.noAutoClose.respectExcludedFrames = value; if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end end,
            },
            defaultAnchor = {
                type = "select",
                name = "Default Position Anchor",
                desc = "Default anchor used when a Blizzard panel loses its layout point after No Auto Close removes it from Blizzard's UIPanel layout system.",
                values = { TOPLEFT = "Top Left", TOP = "Top", TOPRIGHT = "Top Right", CENTER = "Center" },
                order = 13,
                get = function() EnsureDB(); return SinsToolkitDB.noAutoClose.defaultPosition.anchor or "TOPLEFT" end,
                set = function(_, value) EnsureDB(); SinsToolkitDB.noAutoClose.defaultPosition.anchor = value; if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end end,
            },
            defaultX = {
                type = "range", name = "Default X", order = 14, min = -900, max = 900, step = 1,
                get = function() EnsureDB(); return SinsToolkitDB.noAutoClose.defaultPosition.x or 50 end,
                set = function(_, value) EnsureDB(); SinsToolkitDB.noAutoClose.defaultPosition.x = value; if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end end,
            },
            defaultY = {
                type = "range", name = "Default Y", order = 15, min = -900, max = 900, step = 1,
                get = function() EnsureDB(); return SinsToolkitDB.noAutoClose.defaultPosition.y or -50 end,
                set = function(_, value) EnsureDB(); SinsToolkitDB.noAutoClose.defaultPosition.y = value; if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end end,
            },
            moverHeader = { type = "header", name = "Frame Mover", order = 20 },
            frameMoverEnabled = {
                type = "toggle",
                name = "Enable Frame Mover",
                desc = "Lets Sin's Toolkit move supported Blizzard frames with left-drag and optionally scale them with Ctrl + mouse wheel.",
                order = 21,
                get = function() return GetValue("frameMoverEnabled") end,
                set = function(_, value) SetValue("frameMoverEnabled", value) end,
            },
            requireModifier = {
                type = "toggle",
                name = "Require Shift to Move",
                desc = "Requires Shift while left-dragging to move frames. This prevents accidental movement.",
                order = 22,
                get = function() return GetValue("frameMoverRequireModifier") end,
                set = function(_, value) SetValue("frameMoverRequireModifier", value) end,
            },
            ctrlScrollScale = {
                type = "toggle",
                name = "Ctrl + Mouse Wheel Scaling",
                desc = "Allows Ctrl + mouse wheel over supported frames to scale them between 50% and 200%.",
                order = 23,
                get = function() return GetValue("frameMoverCtrlScrollScale") end,
                set = function(_, value) SetValue("frameMoverCtrlScrollScale", value) end,
            },
            positionMode = {
                type = "select",
                name = "Position Saving",
                desc = "Off does not save moved frames. Session keeps positions until reload. Permanent saves positions in SinsToolkitDB.",
                values = MODE_VALUES,
                order = 24,
                get = function() return GetValue("frameMoverPositionMode") or "session" end,
                set = function(_, value) SetValue("frameMoverPositionMode", value) end,
            },
            scaleMode = {
                type = "select",
                name = "Scale Saving",
                desc = "Off does not save scale changes. Session keeps scales until reload. Permanent saves scales in SinsToolkitDB.",
                values = MODE_VALUES,
                order = 25,
                get = function() return GetValue("frameMoverScaleMode") or "session" end,
                set = function(_, value) SetValue("frameMoverScaleMode", value) end,
            },
            resetMover = {
                type = "execute",
                name = "Reset Saved Positions and Scales",
                desc = "Clears all saved Frame Mover positions and scales. Reload UI afterward if a frame is already open.",
                order = 26,
                func = function() if SinsToolkit.FrameMover then SinsToolkit.FrameMover:ResetAll() end end,
            },
        },
    }
end

function SinsToolkit.BuildStandaloneFrameToolsPages(Window, contentPanel, CreateWrappedText, getGV, setGV)
    local frameTools = CreateFrame("Frame", nil, contentPanel)
    frameTools:SetAllPoints()
    frameTools:Hide()
    Window.pages["Frame Tools"] = frameTools

    local header = Window:CreateSectionHeader(frameTools, "Frame Tools")
    CreateWrappedText(frameTools, {"TOPLEFT", header, "BOTTOMLEFT", 0, -8}, 720, "No Auto Close keeps supported Blizzard panels open. Frame Mover lets Toolkit-owned supported frames be moved with left-drag and scaled with Ctrl + mouse wheel. If the original addons are installed, choose which addon owns each feature.", "GameFontHighlightSmall")

    local cbNoAutoClose = Window:CreateCheckbox(frameTools, "No Auto Close Panels", getGV("keepPanelsOpen"), setGV("keepPanelsOpen"), "Keeps supported Blizzard panels open together. Reload after disabling because Blizzard panel layout hooks are persistent for the current session.")
    cbNoAutoClose:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -54)

    local ownerNoAutoClose = Window:CreateCycleButton(frameTools, "No Auto Close Owner", OWNER_VALUES, function() return GetOwner("keepPanelsOpen") end, function(value) SetOwner("keepPanelsOpen", value) end, "Choose whether Sin's Toolkit or the original NoAutoClose addon owns this behavior.")
    ownerNoAutoClose:SetPoint("TOPLEFT", cbNoAutoClose, "BOTTOMLEFT", 4, -24)

    local exclude = Window:CreateCheckbox(frameTools, "Respect Excluded Frames", function() EnsureDB(); return SinsToolkitDB.noAutoClose.respectExcludedFrames ~= false end, function(value) EnsureDB(); SinsToolkitDB.noAutoClose.respectExcludedFrames = value; if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end end, "Leaves sensitive frames such as cinematics, barbershop, communities, player housing editor, and trading post under Blizzard control.")
    exclude:SetPoint("TOPLEFT", ownerNoAutoClose, "BOTTOMLEFT", -4, -28)

    local anchor = Window:CreateCycleButton(frameTools, "Default Position Anchor", { TOPLEFT = "Top Left", TOP = "Top", TOPRIGHT = "Top Right", CENTER = "Center" }, function() EnsureDB(); return SinsToolkitDB.noAutoClose.defaultPosition.anchor or "TOPLEFT" end, function(value) EnsureDB(); SinsToolkitDB.noAutoClose.defaultPosition.anchor = value; if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end end, "Default anchor used when a panel loses its Blizzard layout point.")
    anchor:SetPoint("TOPLEFT", exclude, "BOTTOMLEFT", 4, -24)

    local x = Window:CreateSlider(frameTools, "Default X", function() EnsureDB(); return SinsToolkitDB.noAutoClose.defaultPosition.x or 50 end, function(value) EnsureDB(); SinsToolkitDB.noAutoClose.defaultPosition.x = value; if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end end, -900, 900, 1, "Default X offset for No Auto Close panel placement.")
    x:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", -4, -26)

    local y = Window:CreateSlider(frameTools, "Default Y", function() EnsureDB(); return SinsToolkitDB.noAutoClose.defaultPosition.y or -50 end, function(value) EnsureDB(); SinsToolkitDB.noAutoClose.defaultPosition.y = value; if SinsToolkit.ApplyNoAutoClosePanels then SinsToolkit.ApplyNoAutoClosePanels() end end, -900, 900, 1, "Default Y offset for No Auto Close panel placement.")
    y:SetPoint("LEFT", x, "RIGHT", 56, 0)

    local moverHeader = frameTools:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    moverHeader:SetPoint("TOPLEFT", x, "BOTTOMLEFT", -4, -36)
    moverHeader:SetText("Frame Mover")

    local cbMover = Window:CreateCheckbox(frameTools, "Enable Frame Mover", getGV("frameMoverEnabled"), setGV("frameMoverEnabled"), "Move supported frames with left-drag. Enable Shift requirement below if you want protection from accidental dragging.")
    cbMover:SetPoint("TOPLEFT", moverHeader, "BOTTOMLEFT", -4, -10)

    local ownerMover = Window:CreateCycleButton(frameTools, "Frame Mover Owner", OWNER_VALUES, function() return GetOwner("frameMoverEnabled") end, function(value) SetOwner("frameMoverEnabled", value) end, "Choose whether Sin's Toolkit or BlizzMove owns frame movement when both are installed.")
    ownerMover:SetPoint("LEFT", cbMover, "RIGHT", 180, 0)

    local requireShift = Window:CreateCheckbox(frameTools, "Require Shift to Move", getGV("frameMoverRequireModifier"), setGV("frameMoverRequireModifier"), "Requires Shift while left-dragging to move frames.")
    requireShift:SetPoint("TOPLEFT", cbMover, "BOTTOMLEFT", 0, -8)

    local ctrlScale = Window:CreateCheckbox(frameTools, "Ctrl + Mouse Wheel Scaling", getGV("frameMoverCtrlScrollScale"), setGV("frameMoverCtrlScrollScale"), "Allows Ctrl + mouse wheel over supported frames to adjust scale.")
    ctrlScale:SetPoint("TOPLEFT", requireShift, "BOTTOMLEFT", 0, -8)

    local posMode = Window:CreateCycleButton(frameTools, "Position Saving", MODE_VALUES, getGV("frameMoverPositionMode"), setGV("frameMoverPositionMode"), "Off does not save moved frames. Session keeps positions until reload. Permanent saves positions in SinsToolkitDB.")
    posMode:SetPoint("TOPLEFT", ctrlScale, "BOTTOMLEFT", 4, -24)

    local scaleMode = Window:CreateCycleButton(frameTools, "Scale Saving", MODE_VALUES, getGV("frameMoverScaleMode"), setGV("frameMoverScaleMode"), "Off does not save scale changes. Session keeps scales until reload. Permanent saves scales in SinsToolkitDB.")
    scaleMode:SetPoint("LEFT", posMode, "RIGHT", 24, 0)

    local reset = Window:CreateButton(frameTools, "Reset Positions and Scales", 190, 26, function() if SinsToolkit.FrameMover then SinsToolkit.FrameMover:ResetAll() end end, "Clears saved Frame Mover positions and scales.")
    reset:SetPoint("TOPLEFT", posMode, "BOTTOMLEFT", -4, -22)

    local status = frameTools:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    status:SetPoint("TOPLEFT", reset, "BOTTOMLEFT", 0, -18)
    status:SetWidth(720)
    status:SetJustifyH("LEFT")
    frameTools.OnShowCallback = function()
        status:SetText((SinsToolkit.FrameMover and SinsToolkit.FrameMover:GetStatusText() or "") .. "\n" .. ConflictLine("keepPanelsOpen"))
    end
end
