local DR = select(2, ...)
local OpenLegacyOptions = rawget(_G, "InterfaceOptionsFrame_OpenToCategory")

local Config = {
	registered = false,
	frame = nil,
	categoryID = nil,
	options = nil,
}

local function DBGet(info)
	return DR.db.profile[info[#info]]
end

local function DBSet(info, value)
	DR.db.profile[info[#info]] = value
	DR:OnProfileUpdated()
end

function Config:OpenOptions()
	if not self.registered then
		return
	end

	-- The embedded Blizzard Settings panel squishes our option groups, so
	-- open the standalone AceConfigDialog window: scrollable and resizable.
	local AceConfigDialog = LibStub("AceConfigDialog-3.0")
	AceConfigDialog:SetDefaultSize("DetentionRolls", 720, 640)
	AceConfigDialog:Open("DetentionRolls")
end

--- Kept for anyone navigating via ESC > Options > AddOns.
function Config:OpenBlizzardPanel()
	if Settings and Settings.OpenToCategory and self.categoryID then
		Settings.OpenToCategory(self.categoryID)
	elseif OpenLegacyOptions and self.frame then
		OpenLegacyOptions(self.frame)
		OpenLegacyOptions(self.frame)
	end
end

function Config:RegisterOptions()
	if self.registered then
		return
	end

	local AceConfig = LibStub("AceConfig-3.0")
	local AceConfigDialog = LibStub("AceConfigDialog-3.0")
	local AceDBOptions = LibStub("AceDBOptions-3.0")

	self.options = {
		type = "group",
		name = "DetentionRolls",
		args = {
			rolling = {
				order = 10,
				type = "group",
				name = "Rolling",
				inline = true,
				args = {
					winnerPenaltyFactor = {
						order = 1,
						type = "range",
						name = "Winner Penalty Factor",
						min = 0.10,
						max = 0.90,
						step = 0.01,
						get = DBGet,
						set = DBSet,
					},
					bossRegain = {
						order = 2,
						type = "range",
						name = "Boss Regain (raiders)",
						desc = "Roll power restored per boss kill for players in the designated raid.",
						min = 0,
						max = 25,
						step = 0.5,
						get = DBGet,
						set = DBSet,
					},
					benchBossRegain = {
						order = 3,
						type = "range",
						name = "Boss Regain (bench)",
						desc = "Roll power restored per boss kill for roster players flagged Bench who are sitting out. Default 12.5 (a full 8-boss clear grants +100).",
						min = 0,
						max = 25,
						step = 0.5,
						get = DBGet,
						set = DBSet,
					},
					weeklyRegain = {
						order = 4,
						type = "range",
						name = "Weekly Regain",
						desc = "Roll power restored at the weekly reset (Tuesday). 0 disables (default) - boss kills gate the credit instead.",
						min = 0,
						max = 50,
						step = 1,
						get = DBGet,
						set = DBSet,
					},
					startingWeight = {
						order = 5,
						type = "range",
						name = "Starting Power",
						desc = "Roll power for players new to the roster.",
						min = 10,
						max = 200,
						step = 5,
						get = DBGet,
						set = DBSet,
					},
					minWeight = {
						order = 6,
						type = "range",
						name = "Minimum Power",
						min = 1,
						max = 100,
						step = 1,
						get = DBGet,
						set = DBSet,
					},
					maxWeight = {
						order = 7,
						type = "range",
						name = "Power Cap",
						desc = "Uniform cap on roll power for everyone. Default 200.",
						min = 100,
						max = 300,
						step = 5,
						get = DBGet,
						set = DBSet,
					},
				},
			},
			interface = {
				order = 12,
				type = "group",
				name = "Interface",
				inline = true,
				args = {
					toolbarShown = {
						order = 1,
						type = "toggle",
						name = "Show Status Toolbar",
						desc = "Slim bar with raid-mode status, the raid leader, your roll power and quick-open buttons.",
						get = function()
							return DR.db.profile.ui.toolbarShown
						end,
						set = function(_, value)
							DR.db.profile.ui.toolbarShown = value
							DR:Require("Modules.Toolbar"):Refresh()
						end,
					},
					toolbarLocked = {
						order = 2,
						type = "toggle",
						name = "Lock Toolbar",
						desc = "Locked bars can't be dragged.",
						get = function()
							return DR.db.profile.ui.toolbarLocked
						end,
						set = function(_, value)
							DR.db.profile.ui.toolbarLocked = value
							DR:Require("Modules.Toolbar"):Refresh()
						end,
					},
					showRollOffModal = {
						order = 3,
						type = "toggle",
						name = "Show Roll-Off Popup",
						get = function()
							return DR.db.profile.ui.showRollOffModal
						end,
						set = function(_, value)
							DR.db.profile.ui.showRollOffModal = value
						end,
					},
				},
			},
			automation = {
				order = 15,
				type = "group",
				name = "Automation",
				inline = true,
				args = {
					autoPassEnabled = {
						order = 1,
						type = "toggle",
						name = "Auto-Pass Group Loot (leader needs)",
						desc = "Raiders automatically pass on all Blizzard group-loot rolls while the raid leader automatically needs everything, funneling items to the leader for distribution via roll sessions and trades. Raiders only auto-pass when the leader is confirmed to run DetentionRolls.",
						get = DBGet,
						set = DBSet,
					},
					autoAddLoot = {
						order = 2,
						type = "toggle",
						name = "Auto-Add Loot to Sessions",
						desc = "When the raid leader opens a loot window, items at or above the quality threshold automatically get a roll session.",
						get = DBGet,
						set = DBSet,
					},
					autoAddLootMinQuality = {
						order = 3,
						type = "select",
						name = "Auto-Add Quality Threshold",
						values = {
							[2] = "Uncommon",
							[3] = "Rare",
							[4] = "Epic",
							[5] = "Legendary",
						},
						get = DBGet,
						set = DBSet,
					},
					autoTradeItems = {
						order = 4,
						type = "toggle",
						name = "Auto-Add Items to Trade Window",
						desc = "When you open a trade with a session winner, their pending item(s) are placed into the trade window automatically.",
						get = DBGet,
						set = DBSet,
					},
					autoAcceptTrade = {
						order = 5,
						type = "toggle",
						name = "Auto-Accept After Adding Items",
						desc = "Attempts to press Trade for you once the items are placed. Blizzard hardware protection may block this; if the trade doesn't confirm, click Trade manually.",
						get = DBGet,
						set = DBSet,
					},
					sessionTimeoutSeconds = {
						order = 6,
						type = "range",
						name = "Roll Window (seconds)",
						desc = "How long raiders have to roll before the session auto-resolves.",
						min = 15,
						max = 300,
						step = 5,
						get = DBGet,
						set = DBSet,
					},
				},
			},
			communication = {
				order = 20,
				type = "group",
				name = "Communication",
				inline = true,
				args = {
					versionGateStrict = {
						order = 1,
						type = "toggle",
						name = "Hard Block Outdated Raiders",
						get = DBGet,
						set = DBSet,
					},
					fallbackChatEnabled = {
						order = 2,
						type = "toggle",
						name = "Enable Fallback Chat Announcements",
						get = DBGet,
						set = DBSet,
					},
					autoMarkTradedFromTrade = {
						order = 3,
						type = "toggle",
						name = "Auto-Mark Traded on Trade Complete",
						desc = "Automatically marks deferred trades as traded when a matching successful trade completes.",
						get = DBGet,
						set = DBSet,
					},
					autoTimeoutDeferredTrades = {
						order = 4,
						type = "toggle",
						name = "Auto-Timeout Deferred Trades",
						desc = "Automatically moves stale To Trade entries to Timeout after the configured age.",
						get = DBGet,
						set = DBSet,
					},
					deferredTradeTimeoutMinutes = {
						order = 5,
						type = "range",
						name = "Deferred Trade Timeout (minutes)",
						min = 5,
						max = 1440,
						step = 5,
						get = DBGet,
						set = DBSet,
					},
				},
			},
			debug = {
				order = 30,
				type = "group",
				name = "Debug",
				inline = true,
				args = {
					debugEnabled = {
						order = 1,
						type = "toggle",
						name = "Enable Debug Logs",
						get = DBGet,
						set = DBSet,
					},
					exportAudit = {
						order = 2,
						type = "execute",
						name = "Export Last 100 Audit Events",
						func = function()
							DR:ChatCommand("export")
						end,
					},
				},
			},
		},
	}

	self.options.args.profiles = AceDBOptions:GetOptionsTable(DR.db)
	self.options.args.profiles.order = 100

	AceConfig:RegisterOptionsTable("DetentionRolls", self.options)
	self.frame, self.categoryID = AceConfigDialog:AddToBlizOptions("DetentionRolls", "DetentionRolls")
	self.registered = true
end

DR:RegisterModule("Modules.Config", Config)
