-- MarketWatch Config.lua
-- WotLK 3.3.5a / Lua 5.1 / Ace3
-- Pass 2: wider/easier sliders and centered config title.

MW = MW or {}
MW.UI = MW.UI or {}

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

local APP_NAME = "MarketWatchConfig"
local registered = false

local function GetDB()
	return MarketWatch.db.profile
end

local function BuildCategoryToggles()
	local args = {}
	local order = 1

	for _, catKey in ipairs(MW.categoryOrder) do
		args[catKey] = {
			type = "toggle",
			name = MW.categoryLabels[catKey],
			order = order,
			get = function()
				return GetDB().categoriesEnabled[catKey]
			end,
			set = function(_, val)
				GetDB().categoriesEnabled[catKey] = val
			end,
		}
		order = order + 1
	end

	args.Uncategorized = {
		type = "toggle",
		name = "Uncategorized",
		order = order,
		get = function()
			return GetDB().categoriesEnabled.Uncategorized
		end,
		set = function(_, val)
			GetDB().categoriesEnabled.Uncategorized = val
		end,
	}

	return args
end

local function BuildOptions()
	return {
		type = "group",
		name = "MarketWatch Settings",
		args = {
			general = {
				type = "group",
				name = "General",
				inline = true,
				order = 1,
				args = {
					enabled = {
						type = "toggle",
						name = "Enable MarketWatch",
						desc = "Enable or disable message detection.",
						order = 1,
						width = "full",
						get = function()
							return GetDB().enabled
						end,
						set = function(_, val)
							GetDB().enabled = val
						end,
					},

					expiryMinutes = {
						type = "range",
						name = "Message Lifetime",
						desc = "How long captured listings remain visible.",
						min = 1,
						max = 10,
						step = 1,
						order = 2,
						width = "full",
						get = function()
							return GetDB().expiryMinutes
						end,
						set = function(_, val)
							GetDB().expiryMinutes = val
							if MW.UI and MW.UI.RefreshActive then
								MW.UI.RefreshActive()
							end
						end,
					},

					scale = {
						type = "range",
						name = "Main UI Scale",
						desc = "Scales the MarketWatcher tracker windows. The configuration window remains stable while dragging.",
						min = 60,
						max = 150,
						step = 5,
						order = 3,
						width = "full",
						get = function()
							return tonumber(GetDB().scalePercent) or 100
						end,
						set = function(_, val)
							val = math.floor(tonumber(val) + 0.5)

							if val < 60 then val = 60 end
							if val > 150 then val = 150 end

							GetDB().scalePercent = val

							if MW.UI and MW.UI.ApplyScale then
								MW.UI.ApplyScale(val / 100)
							end
						end,
					},

					maxEntries = {
						type = "range",
						name = "Max Entries / Category",
						desc = "Maximum number of listings stored in each category.",
						min = 20,
						max = 500,
						step = 10,
						order = 4,
						width = "full",
						get = function()
							return GetDB().maxEntriesPerCategory
						end,
						set = function(_, val)
							GetDB().maxEntriesPerCategory = val
						end,
					},
				},
			},

			channels = {
				type = "group",
				name = "Chat Sources",
				inline = true,
				order = 2,
				args = {
					chanTrade = {
						type = "toggle",
						name = "Trade",
						order = 1,
						get = function()
							return GetDB().channels.trade
						end,
						set = function(_, val)
							GetDB().channels.trade = val
						end,
					},

					chanGeneral = {
						type = "toggle",
						name = "General / World / Global",
						order = 2,
						get = function()
							return GetDB().channels.general
						end,
						set = function(_, val)
							GetDB().channels.general = val
						end,
					},

					chanYell = {
						type = "toggle",
						name = "Yell",
						order = 3,
						get = function()
							return GetDB().channels.yell
						end,
						set = function(_, val)
							GetDB().channels.yell = val
						end,
					},

					chanSay = {
						type = "toggle",
						name = "Say",
						order = 4,
						get = function()
							return GetDB().channels.say
						end,
						set = function(_, val)
							GetDB().channels.say = val
						end,
					},
				},
			},

			categories = {
				type = "group",
				name = "Tracked Categories",
				inline = true,
				order = 3,
				args = BuildCategoryToggles(),
			},

			dealAlerts = {
				type = "group",
				name = "Deal Alerts",
				inline = true,
				order = 4,
				args = {
					desc = {
						type = "description",
						name = "Flags BoE/Mount/Transmog listings priced well under Auctionator/TSM market value. Requires Auctionator and/or TSM installed with scanned AH data - no data means no flags, silently.",
						order = 1,
					},
					enabled = {
						type = "toggle",
						name = "Enable Deal Alerts",
						order = 2,
						width = "full",
						get = function() return GetDB().dealAlerts.enabled end,
						set = function(_, val) GetDB().dealAlerts.enabled = val end,
					},
					thresholdMode = {
						type = "select",
						name = "Threshold Type",
						order = 3,
						width = "full",
						values = { percent = "Percent under market", gold = "Flat gold amount" },
						get = function() return GetDB().dealAlerts.thresholdMode end,
						set = function(_, val) GetDB().dealAlerts.thresholdMode = val end,
					},
					minDiscountPercent = {
						type = "range",
						name = "Minimum Discount %",
						desc = "Flag listings at least this much cheaper than market. A listing more than 50% under market is never flagged, regardless of this setting - more likely a bad item match or a scam than a real bargain.",
						min = 5,
						max = 50,
						step = 1,
						order = 4,
						width = "full",
						get = function() return GetDB().dealAlerts.minDiscountPercent end,
						set = function(_, val) GetDB().dealAlerts.minDiscountPercent = val end,
					},
					minGoldSaved = {
						type = "range",
						name = "Minimum Gold Saved",
						desc = "Only used when Threshold Type is set to flat gold amount.",
						min = 10,
						max = 5000,
						step = 10,
						order = 5,
						width = "full",
						get = function() return GetDB().dealAlerts.minGoldSaved end,
						set = function(_, val) GetDB().dealAlerts.minGoldSaved = val end,
					},
					sound = {
						type = "toggle",
						name = "Play Sound on New Deal",
						desc = "Plays once when a listing first becomes a deal - won't replay on every repost of the same still-live deal.",
						order = 6,
						width = "full",
						get = function() return GetDB().dealAlerts.sound end,
						set = function(_, val) GetDB().dealAlerts.sound = val end,
					},
				},
			},

			danger = {
				type = "group",
				name = "Danger Zone",
				inline = true,
				order = 5,
				args = {
					resetDesc = {
						type = "description",
						name = "This wipes ALL settings, the blacklist, keywords, saved listings, and re-locks the addon (the tutorial must be completed again). Use this if the addon is broken and nothing else fixes it.",
						order = 1,
					},
					resetBtn = {
						type = "execute",
						name = "Restore to Defaults",
						order = 2,
						confirm = true,
						confirmText = "This will reset ALL settings and re-lock the addon, requiring the tutorial again. This cannot be undone. Continue?",
						func = function()
							MW.FactoryReset()
						end,
					},
				},
			},
		},
	}
end

function MW.UI.ToggleConfig()
	if not registered then
		AceConfig:RegisterOptionsTable(APP_NAME, BuildOptions)
		registered = true
	end

	if AceConfigDialog.OpenFrames[APP_NAME] then
		AceConfigDialog:Close(APP_NAME)
		return
	end

	AceConfigDialog:Open(APP_NAME)

	-- The standard AceConfig slider already has a generous mouse hitbox.
	-- Using full width gives it a much longer, easier-to-adjust track.
	local frame = AceConfigDialog.OpenFrames[APP_NAME]
	if frame then
		if frame.titletext then
			frame.titletext:SetJustifyH("CENTER")
		end

		-- Make the config window wide enough for the full-width sliders.
		local currentWidth = frame.frame:GetWidth() or 0
		if currentWidth < 650 then
			frame:SetWidth(650)
		end
	end
end
