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

local slotValues = {
    { INVSLOT_HEAD, HEADSLOT or "Head" },
    { INVSLOT_NECK, NECKSLOT or "Neck" },
    { INVSLOT_SHOULDER, SHOULDERSLOT or "Shoulders" },
    { INVSLOT_BACK, BACKSLOT or "Back" },
    { INVSLOT_CHEST, CHESTSLOT or "Chest" },
    { INVSLOT_WRIST, WRISTSLOT or "Wrist" },
    { INVSLOT_HAND, HANDSSLOT or "Hands" },
    { INVSLOT_WAIST, WAISTSLOT or "Waist" },
    { INVSLOT_LEGS, LEGSSLOT or "Legs" },
    { INVSLOT_FEET, FEETSLOT or "Feet" },
    { INVSLOT_FINGER1, FINGER0SLOT or "Finger 1" },
    { INVSLOT_FINGER2, FINGER1SLOT or "Finger 2" },
    { INVSLOT_TRINKET1, TRINKET0SLOT or "Trinket 1" },
    { INVSLOT_TRINKET2, TRINKET1SLOT or "Trinket 2" },
    { INVSLOT_MAINHAND, MAINHANDSLOT or "Main Hand" },
    { INVSLOT_OFFHAND, SECONDARYHANDSLOT or "Off Hand" },
}

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

    local gearPage, content = CreateScrollablePage("Gear")
    Helpers.CreatePageIntro(content, Window, "Gear Scanner", "Scans bag gear for upgrades. Pawn is preferred when installed; otherwise Gear Scanner falls back to ClassCodex stat priorities.", CreateWrappedText, 700)

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

    local statusCard = Helpers.ClearCardBody(grid:AddCard(1, "Status", 220))
    local function CreateStatusPair(labelText, yOffset, valueHeight)
        local label = statusCard:CreateFontString(nil, "OVERLAY", Theme and Theme.GetFont and Theme.GetFont("label") or "GameFontNormalSmall")
        local value = statusCard:CreateFontString(nil, "OVERLAY", Theme and Theme.GetFont and Theme.GetFont("status_text") or "GameFontHighlightSmall")
        label:SetWidth(78)
        label:SetJustifyH("LEFT")
        label:SetText(labelText)
        value:SetWidth(206)
        value:SetJustifyH("LEFT")
        value:SetJustifyV("TOP")
        value:SetWordWrap(true)
        if value.SetMaxLines then value:SetMaxLines(valueHeight and 2 or 1) end
        label:SetPoint("TOPLEFT", statusCard, "TOPLEFT", 16, yOffset or -42)
        value:SetPoint("TOPLEFT", label, "TOPRIGHT", 8, 0)
        if Theme and Theme.ApplyLabelFont then Theme.ApplyLabelFont(label) end
        if Theme and Theme.ApplyStatusText then Theme.ApplyStatusText(value) end
        return label, value
    end

    local featureLabel, featureValue = CreateStatusPair("Feature", -42)
    local providersLabel, providersValue = CreateStatusPair("Scoring Sources", -66)
    local modeLabel, modeValue = CreateStatusPair("Mode", -90, 2)
    local lastScanLabel, lastScanValue = CreateStatusPair("Last Scan", -132)
    featureValue:SetText("Unknown")
    providersValue:SetText("Unknown")
    modeValue:SetText("Unknown")
    lastScanValue:SetText("Never")

    local gBtnScan2 = Window:CreateButton(statusCard, "Force Gear Scan", 150, 24, function()
        if SinsToolkit.ForceGearScan then
            SinsToolkit.ForceGearScan()
            Window.lastGearScanTime = date("%Y-%m-%d %H:%M:%S")
            featureValue:SetText(GetToolkitValue("gearScannerEnabled") and "|cff00ff00Enabled|r" or "|cffff4040Disabled|r")
            lastScanValue:SetText(Window.lastGearScanTime)
        end
    end, "Runs an immediate bag scan using the current Gear Scanner settings. This is the same action as /stk scan.")
    gBtnScan2:SetPoint("BOTTOMRIGHT", statusCard, "BOTTOMRIGHT", -14, 12)

    local scannerCard = Helpers.ClearCardBody(grid:AddCard(1, "Scanner Options", 366))
    local gEnable = Helpers.AnchorFirstControl(Window:CreateCheckbox(scannerCard, "Enable Gear Scanner", getGV("gearScannerEnabled"), setGV("gearScannerEnabled"), "Master switch for Gear Scanner. When enabled, Sin's Toolkit can scan bag items, compare them against equipped gear, and equip upgrades."), scannerCard, 12, -42)
    local gMaxLevel = Helpers.AnchorBelow(Window:CreateCheckbox(scannerCard, "Disable at Max Level", getGV("gearScannerMaxLevelDisable"), setGV("gearScannerMaxLevelDisable"), "Turns Gear Scanner off automatically when your character reaches the current expansion level cap."), gEnable, 0, rowGap)
    local gSilent = Helpers.AnchorBelow(Window:CreateCheckbox(scannerCard, "Silent Mode", getGV("gearScannerSilent"), setGV("gearScannerSilent"), "Suppresses Gear Scanner chat messages when items are equipped, scans are run, or loot-roll actions are taken."), gMaxLevel, 0, rowGap)
    local gScanOnLoot = Helpers.AnchorBelow(Window:CreateCheckbox(scannerCard, "Scan When Bags Change", getGV("gearScannerScanOnLoot"), setGV("gearScannerScanOnLoot"), "Automatically scans your bags after loot or bag changes. Turn this off if you only want manual scans."), gSilent, 0, rowGap)
    local gAllowUnbound = Helpers.AnchorBelow(Window:CreateCheckbox(scannerCard, "Allow Unbound Upgrades", getGV("gearScannerAllowUnbound"), setGV("gearScannerAllowUnbound"), "Allows Gear Scanner to equip unbound upgrades from your bags. Leave this off if you want BoE items left untouched."), gScanOnLoot, 0, rowGap)
    local gUsePawn = Helpers.AnchorBelow(Window:CreateCheckbox(scannerCard, "Use Pawn When Installed", getGV("gearScannerUsePawn"), setGV("gearScannerUsePawn"), "When Pawn is installed, Sin's Toolkit asks Pawn's upgrade advisor first. If Pawn is still evaluating an item, Gear Scanner retries shortly instead of falling back immediately."), gAllowUnbound, 0, rowGap)
    local gScoreTooltips = Helpers.AnchorBelow(Window:CreateCheckbox(scannerCard, "Show Item Score", getGV("gearScannerScoreTooltips"), setGV("gearScannerScoreTooltips"), "Adds a Sin's Toolkit gear score line to item tooltips."), gUsePawn, 0, rowGap)
    local gReasonsTooltips = Helpers.AnchorBelow(Window:CreateCheckbox(scannerCard, "Show Won't-Equip Reasons", getGV("gearScannerReasonsTooltips"), setGV("gearScannerReasonsTooltips"), "Adds a tooltip note explaining why an item will or will not equip, such as locked slots, no upgrade, unbound protection, or scoring fallback behavior."), gScoreTooltips, 0, rowGap)
    local gMinUpgrade = Window:CreateSlider(scannerCard, "Minimum Upgrade Score", getGV("gearScannerMinimumUpgrade"), setGV("gearScannerMinimumUpgrade"), 0, 500, 5, "Requires a new item to beat your equipped item by at least this many score points before it is equipped.")
    gMinUpgrade:SetPoint("TOPLEFT", gReasonsTooltips, "BOTTOMLEFT", 8, -20)

    local lootCard = Helpers.ClearCardBody(grid:AddCard(2, "Loot Roll Behavior", 190))
    local gRollGreens = Helpers.AnchorFirstControl(Window:CreateCheckbox(lootCard, "Roll on greens and BoP blues", getGV("gearScannerAutoRollGreensBopBlues"), setGV("gearScannerAutoRollGreensBopBlues"), "Automatically handles green gear and blue bind-on-pickup gear loot rolls using your Gear Scanner rules."), lootCard, 12, -42)
    local gRollBoeBlues = Helpers.AnchorBelow(Window:CreateCheckbox(lootCard, "Roll on BoE blues", getGV("gearScannerAutoRollBoeBlues"), setGV("gearScannerAutoRollBoeBlues"), "Automatically handles blue bind-on-equip gear loot rolls. Use carefully if you prefer to sell or trade BoE blues."), gRollGreens, 0, rowGap)
    local gRollEpics = Helpers.AnchorBelow(Window:CreateCheckbox(lootCard, "Roll on epics", getGV("gearScannerAutoRollEpics"), setGV("gearScannerAutoRollEpics"), "Automatically handles epic gear loot rolls. This is off by default because many players want manual control over epic loot."), gRollBoeBlues, 0, rowGap)
    local gRollNonGear = Helpers.AnchorBelow(Window:CreateCheckbox(lootCard, "Roll on non-gear loot", getGV("gearScannerRollNonGearLoot"), setGV("gearScannerRollNonGearLoot"), "Automatically rolls Greed on handled non-gear loot. This does not evaluate upgrades because the item is not equippable gear."), gRollEpics, 0, rowGap)
    Helpers.AnchorBelow(Window:CreateCheckbox(lootCard, "Never auto-need; only greed", getGV("gearScannerNeverAutoNeed"), setGV("gearScannerNeverAutoNeed"), "Prevents Sin's Toolkit from rolling Need automatically. Upgrade candidates will roll Greed instead when Greed is available."), gRollNonGear, 0, rowGap)

    local bindCard = Helpers.ClearCardBody(grid:AddCard(2, "Soulbind Confirmations", 130))
    local gBindOther = Helpers.AnchorFirstControl(Window:CreateCheckbox(bindCard, "Confirm non-blue/non-epic binds", getGV("gearScannerAutoConfirmBindOther"), setGV("gearScannerAutoConfirmBindOther"), "Automatically confirms the soulbind popup when Gear Scanner equips an upgrade below blue quality."), bindCard, 12, -42)
    local gBindBlues = Helpers.AnchorBelow(Window:CreateCheckbox(bindCard, "Confirm blue binds", getGV("gearScannerAutoConfirmBindBlues"), setGV("gearScannerAutoConfirmBindBlues"), "Automatically confirms the soulbind popup when Gear Scanner equips a blue upgrade."), gBindOther, 0, rowGap)
    Helpers.AnchorBelow(Window:CreateCheckbox(bindCard, "Confirm epic binds", getGV("gearScannerAutoConfirmBindEpics"), setGV("gearScannerAutoConfirmBindEpics"), "Automatically confirms the soulbind popup when Gear Scanner equips an epic upgrade. This is off by default because epic items are usually worth reviewing manually."), gBindBlues, 0, rowGap)

    local lockCard = Helpers.ClearCardBody(grid:AddCard(2, "Locked Slots", 292))
    local gLockSlots = Helpers.AnchorFirstControl(Window:CreateCheckbox(lockCard, "Enable locked gear slots", getGV("gearScannerLockSlots"), setGV("gearScannerLockSlots"), "Enables the locked slot list below. Locked slots are still scored, but Gear Scanner will not replace items in those slots."), lockCard, 12, -42)
    for i, slot in ipairs(slotValues) do
        local slotID, slotName = slot[1], slot[2]
        local slotCheck = Window:CreateCheckbox(lockCard, slotName, function()
            return SinsToolkitDB and SinsToolkitDB.gearScannerLockedSlots and SinsToolkitDB.gearScannerLockedSlots[slotID] == true
        end, function(value)
            if SinsToolkit.EnsureDB then SinsToolkit.EnsureDB() end
            SinsToolkitDB.gearScannerLockedSlots = SinsToolkitDB.gearScannerLockedSlots or {}
            SinsToolkitDB.gearScannerLockedSlots[slotID] = value or nil
            if SinsToolkit.TriggerUpdate then SinsToolkit.TriggerUpdate("gearScannerLockedSlots") end
        end)
        local col = (i - 1) % 2
        local row = math.floor((i - 1) / 2)
        slotCheck:SetPoint("TOPLEFT", gLockSlots, "BOTTOMLEFT", col * 145, -10 - (row * 24))
        slot.checkbox = slotCheck
    end

    gearPage.OnShowCallback = function()
        local pawnActive = SinsToolkit.IsPawnAvailable and SinsToolkit.IsPawnAvailable()
        local classCodexActive = SinsToolkit.IsClassCodexAvailable and SinsToolkit.IsClassCodexAvailable()
        featureValue:SetText(GetToolkitValue("gearScannerEnabled") and "|cff00ff00Enabled|r" or "|cffff4040Disabled|r")
        providersValue:SetText((pawnActive and "|cff00ff00Pawn|r" or "|cffff4040Pawn|r") .. " / " .. (classCodexActive and "|cff00ff00ClassCodex|r" or "|cffff4040ClassCodex|r"))
        modeValue:SetText(SinsToolkit.GetGearProviderModeText and SinsToolkit.GetGearProviderModeText() or "Unavailable")
        lastScanValue:SetText(Window.lastGearScanTime or "Never")
    end

    Helpers.SetScrollChildHeight(content, grid, 760, 150)
    self.frame = gearPage
    return gearPage
end

Page:Register("Gear")

return Page
