--[[
    Cerebro - UISandbox EP/GP Settings Tab
    Extracted from UI/UISandbox.lua (Phase 2a decomposition)

    @module UI.Tabs.EPGPSettings
    @version 0.12.0
]]--

local AddonName = "Cerebro"
local Cerebro = LibStub("AceAddon-3.0"):GetAddon(AddonName)
local AceGUI = LibStub("AceGUI-3.0")
local UISandbox = Cerebro:GetModule("UISandbox")

--[[=============================================
	Officer Tab: EP/GP Settings (Combined)
===============================================]]

-- Track which sub-tab is selected (EP = default)
UISandbox.epgpSubTab = UISandbox.epgpSubTab or "EP"

function UISandbox:DrawEPGPSettingsTab(container)
	if not Cerebro:IsOfficer() then
		local label = AceGUI:Create("Label")
		label:SetText("|cffff4444Officer access required.|r")
		label:SetFullWidth(true)
		container:AddChild(label)
		return
	end

	-- Sub-tab button bar
	local buttonBar = AceGUI:Create("SimpleGroup")
	buttonBar:SetFullWidth(true)
	buttonBar:SetHeight(40)
	buttonBar:SetLayout("Flow")
	container:AddChild(buttonBar)

	-- Create native frame for buttons (need more control over styling)
	local barWrapper = AceGUI:Create("SimpleGroup")
	barWrapper:SetLayout("Fill")
	barWrapper:SetWidth(200)
	barWrapper:SetHeight(32)
	buttonBar:AddChild(barWrapper)

	local barFrame = self:TrackContentFrame(CreateFrame("Frame", nil, barWrapper.frame))
	barFrame:SetAllPoints()

	-- EP Button
	local epBtn = self:TrackContentFrame(CreateFrame("Button", nil, barFrame, "BackdropTemplate"))
	epBtn:SetSize(80, 28)
	epBtn:SetPoint("LEFT", 0, 0)
	epBtn:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		edgeSize = 10,
		insets = { left = 2, right = 2, top = 2, bottom = 2 }
	})

	local epText = epBtn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
	epText:SetPoint("CENTER")
	epText:SetText("EP")

	-- GP Button
	local gpBtn = self:TrackContentFrame(CreateFrame("Button", nil, barFrame, "BackdropTemplate"))
	gpBtn:SetSize(80, 28)
	gpBtn:SetPoint("LEFT", epBtn, "RIGHT", 4, 0)
	gpBtn:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		edgeSize = 10,
		insets = { left = 2, right = 2, top = 2, bottom = 2 }
	})

	local gpText = gpBtn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
	gpText:SetPoint("CENTER")
	gpText:SetText("GP")

	-- Content container (this is what gets refreshed on sub-tab switch)
	local contentContainer = AceGUI:Create("SimpleGroup")
	contentContainer:SetFullWidth(true)
	contentContainer:SetFullHeight(true)
	contentContainer:SetLayout("Fill")
	container:AddChild(contentContainer)

	-- Style buttons based on selection
	local function UpdateButtonStyles()
		if self.epgpSubTab == "EP" then
			epBtn:SetBackdropBorderColor(1, 0.82, 0, 1)     -- Gold = selected
			epBtn:SetBackdropColor(0.2, 0.15, 0, 0.8)
			epText:SetTextColor(1, 0.82, 0)
			gpBtn:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)  -- Gray = unselected
			gpBtn:SetBackdropColor(0.1, 0.1, 0.1, 0.8)
			gpText:SetTextColor(0.6, 0.6, 0.6)
		else
			gpBtn:SetBackdropBorderColor(1, 0.82, 0, 1)     -- Gold = selected
			gpBtn:SetBackdropColor(0.2, 0.15, 0, 0.8)
			gpText:SetTextColor(1, 0.82, 0)
			epBtn:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)  -- Gray = unselected
			epBtn:SetBackdropColor(0.1, 0.1, 0.1, 0.8)
			epText:SetTextColor(0.6, 0.6, 0.6)
		end
	end

	-- Function to refresh content only (not the buttons)
	local function RefreshContent()
		contentContainer:ReleaseChildren()
		UpdateButtonStyles()
		if self.epgpSubTab == "EP" then
			self:DrawEPSettingsContent(contentContainer)
		else
			self:DrawGPSettingsContent(contentContainer)
		end
	end

	UpdateButtonStyles()

	-- Button click handlers - only refresh content, not entire tab
	epBtn:SetScript("OnClick", function()
		if self.epgpSubTab ~= "EP" then
			self.epgpSubTab = "EP"
			RefreshContent()
		end
	end)

	gpBtn:SetScript("OnClick", function()
		if self.epgpSubTab ~= "GP" then
			self.epgpSubTab = "GP"
			RefreshContent()
		end
	end)

	-- Draw initial content based on selected sub-tab
	if self.epgpSubTab == "EP" then
		self:DrawEPSettingsContent(contentContainer)
	else
		self:DrawGPSettingsContent(contentContainer)
	end
end

--[[=============================================
	Officer Tab: EP Settings (Content Only)
===============================================]]

function UISandbox:DrawEPSettingsContent(container)

	-- Create scrolling container
	local scroll = AceGUI:Create("ScrollFrame")
	scroll:SetLayout("Flow")
	scroll:SetFullWidth(true)
	scroll:SetFullHeight(true)
	container:AddChild(scroll)

	-- Helper: Create a slider row for a config item
	local function CreateSliderRow(parent, item)
		local group = AceGUI:Create("SimpleGroup")
		group:SetFullWidth(true)
		group:SetLayout("Flow")
		parent:AddChild(group)

		-- Label with unit suffix if specified
		local labelText = item.label
		local label = AceGUI:Create("Label")
		label:SetText(labelText)
		label:SetWidth(160)
		group:AddChild(label)

		local slider = AceGUI:Create("Slider")
		local sliderMin = item.min or 0
		local sliderMax = item.max or 100
		slider:SetSliderValues(sliderMin, sliderMax, item.step or 1)
		slider:SetWidth(200)
		-- Don't use SetIsPercent - we handle display with unit suffixes instead

		-- Get current value and convert for display
		local currentValue = _G.UI_ConfigSchema:GetValue(item.key) or 0
		local displayValue = currentValue

		-- Handle percent display for normalized storage (stored 0-1, display 0-100)
		if item.isPercent and item.percentStorage == "normalized" then
			displayValue = currentValue * 100
		end

		-- Clamp to slider range (defensive against corrupted stored values)
		displayValue = math.max(sliderMin, math.min(sliderMax, displayValue))
		slider:SetValue(displayValue)

		-- Helper to convert slider value to storage value
		local function toStorageValue(sliderValue)
			if item.isPercent and item.percentStorage == "normalized" then
				return sliderValue / 100
			end
			return sliderValue
		end

		-- Save on mouse release (for slider drag)
		slider:SetCallback("OnMouseUp", function(widget, event)
			local sliderValue = widget:GetValue()
			_G.UI_ConfigSchema:SetValue(item.key, toStorageValue(sliderValue))
		end)

		-- Save on enter pressed (for manual editbox input)
		slider:SetCallback("OnEnterPressed", function(widget, event, value)
			_G.UI_ConfigSchema:SetValue(item.key, toStorageValue(value))
		end)
		group:AddChild(slider)

		-- Unit suffix label (e.g., "%", "EP", "min")
		if item.unit then
			local unitLabel = AceGUI:Create("Label")
			unitLabel:SetText(" " .. item.unit)
			unitLabel:SetWidth(40)
			group:AddChild(unitLabel)
		end

		-- Description tooltip
		if item.desc then
			local desc = AceGUI:Create("Label")
			desc:SetText("|cff888888" .. item.desc .. "|r")
			desc:SetFullWidth(true)
			parent:AddChild(desc)
		end
	end

	-- ============================================
	-- SECTION: General Settings
	-- ============================================
	local generalHeader = AceGUI:Create("Heading")
	generalHeader:SetText("General Settings")
	generalHeader:SetFullWidth(true)
	scroll:AddChild(generalHeader)

	CreateSliderRow(scroll, {
		key = "config.epgp.decayRate",
		label = "Weekly Decay Rate",
		desc = "Percentage to decay EP and GP each week",
		min = 0, max = 50, step = 1,
		isPercent = true, percentStorage = "normalized",
		unit = "%"
	})

	-- Spacer
	local spacer1 = AceGUI:Create("Label")
	spacer1:SetText(" ")
	spacer1:SetFullWidth(true)
	scroll:AddChild(spacer1)

	-- ============================================
	-- SECTION: Raid EP Awards
	-- ============================================
	local raidHeader = AceGUI:Create("Heading")
	raidHeader:SetText("Raid EP Awards")
	raidHeader:SetFullWidth(true)
	scroll:AddChild(raidHeader)

	CreateSliderRow(scroll, {
		key = "config.epgp.epFarmBoss",
		label = "Farm Boss EP",
		desc = "EP awarded per farm boss kill",
		min = 0, max = 1000, step = 10,
		unit = "EP"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.epProgBoss",
		label = "Prog Boss EP",
		desc = "EP awarded per progression boss kill",
		min = 0, max = 1000, step = 10,
		unit = "EP"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.epOnTime",
		label = "Raid Start EP",
		desc = "EP awarded at session start (after grace period)",
		min = 0, max = 1000, step = 10,
		unit = "EP"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.onTimeGracePeriod",
		label = "Grace Period",
		desc = "Minutes after session start where arrivals count as on-time",
		min = 0, max = 30, step = 1,
		unit = "min"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.epFullAttendance",
		label = "Full Attendance",
		desc = "EP awarded for full raid attendance",
		min = 0, max = 1000, step = 10,
		unit = "EP"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.epProgressionHourly",
		label = "Progression (30 min)",
		desc = "EP awarded every 30 minutes of progression",
		min = 0, max = 1000, step = 10,
		unit = "EP"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.benchMultiplier",
		label = "Bench Multiplier",
		desc = "EP multiplier for benched raiders (0% = no EP, 100% = full EP)",
		min = 0, max = 100, step = 5,
		isPercent = true, percentStorage = "normalized",
		unit = "%"
	})

	-- Spacer
	local spacer2 = AceGUI:Create("Label")
	spacer2:SetText(" ")
	spacer2:SetFullWidth(true)
	scroll:AddChild(spacer2)

	-- ============================================
	-- SECTION: Mythic+ EP Settings
	-- ============================================
	local mplusHeader = AceGUI:Create("Heading")
	mplusHeader:SetText("Mythic+ EP Settings")
	mplusHeader:SetFullWidth(true)
	scroll:AddChild(mplusHeader)

	CreateSliderRow(scroll, {
		key = "config.epgp.mplusBase",
		label = "M+ Base",
		desc = "Base EP for completing a Mythic+ dungeon",
		min = 0, max = 1000, step = 10,
		unit = "EP"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.mplusPerLevel",
		label = "Per Level",
		desc = "Additional EP per keystone level",
		min = 0, max = 100, step = 1,
		unit = "EP"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.mplusMaxLevel",
		label = "Max Level Cap",
		desc = "Maximum keystone level for EP scaling",
		min = 1, max = 50, step = 1,
		unit = "+"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.mplusGuildBonus",
		label = "Guild Bonus",
		desc = "Bonus EP for all-guild groups",
		min = 0, max = 100, step = 5,
		unit = "EP"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.readinessCap",
		label = "Readiness Cap",
		desc = "Maximum readiness EP per week",
		min = 0, max = 10000, step = 100,
		unit = "EP"
	})

	-- Spacer
	local spacer3 = AceGUI:Create("Label")
	spacer3:SetText(" ")
	spacer3:SetFullWidth(true)
	scroll:AddChild(spacer3)

	-- ============================================
	-- SECTION: Preparation EP
	-- ============================================
	local prepHeader = AceGUI:Create("Heading")
	prepHeader:SetText("Preparation")
	prepHeader:SetFullWidth(true)
	scroll:AddChild(prepHeader)

	CreateSliderRow(scroll, {
		key = "config.prep.prepAwardAmount",
		label = "Prep Award",
		desc = "EP awarded for passing prep check",
		min = 0, max = 500, step = 10,
		unit = "EP"
	})
end

--[[=============================================
	Officer Tab: GP Settings (Content Only)
===============================================]]

function UISandbox:DrawGPSettingsContent(container)

	-- Create scrolling container
	local scroll = AceGUI:Create("ScrollFrame")
	scroll:SetLayout("Flow")
	scroll:SetFullWidth(true)
	scroll:SetFullHeight(true)
	container:AddChild(scroll)

	-- Helper: Create a slider row for a config item (same as EP Settings)
	local function CreateSliderRow(parent, item)
		local group = AceGUI:Create("SimpleGroup")
		group:SetFullWidth(true)
		group:SetLayout("Flow")
		parent:AddChild(group)

		local labelText = item.label
		local label = AceGUI:Create("Label")
		label:SetText(labelText)
		label:SetWidth(180)
		group:AddChild(label)

		local slider = AceGUI:Create("Slider")
		local sliderMin = item.min or 0
		local sliderMax = item.max or 100
		slider:SetSliderValues(sliderMin, sliderMax, item.step or 1)
		slider:SetWidth(180)

		-- Get current value and convert for display
		local currentValue = _G.UI_ConfigSchema:GetValue(item.key) or 0
		local displayValue = currentValue

		if item.isPercent and item.percentStorage == "normalized" then
			displayValue = currentValue * 100
		end

		displayValue = math.max(sliderMin, math.min(sliderMax, displayValue))
		slider:SetValue(displayValue)

		-- Helper to convert slider value to storage value
		local function toStorageValue(sliderValue)
			if item.isPercent and item.percentStorage == "normalized" then
				return sliderValue / 100
			end
			return sliderValue
		end

		slider:SetCallback("OnMouseUp", function(widget, event)
			local sliderValue = widget:GetValue()
			_G.UI_ConfigSchema:SetValue(item.key, toStorageValue(sliderValue))
		end)

		slider:SetCallback("OnEnterPressed", function(widget, event, value)
			_G.UI_ConfigSchema:SetValue(item.key, toStorageValue(value))
		end)
		group:AddChild(slider)

		-- Unit suffix
		if item.unit then
			local unitLabel = AceGUI:Create("Label")
			unitLabel:SetText(" " .. item.unit)
			unitLabel:SetWidth(40)
			group:AddChild(unitLabel)
		end

		-- Description
		if item.desc then
			local desc = AceGUI:Create("Label")
			desc:SetText("|cff888888" .. item.desc .. "|r")
			desc:SetFullWidth(true)
			parent:AddChild(desc)
		end
	end

	-- ============================================
	-- SECTION: General GP Settings
	-- ============================================
	local generalHeader = AceGUI:Create("Heading")
	generalHeader:SetText("General GP Settings")
	generalHeader:SetFullWidth(true)
	scroll:AddChild(generalHeader)

	CreateSliderRow(scroll, {
		key = "config.epgp.baseGP",
		label = "Base GP",
		desc = "Minimum GP floor for all players (prevents division issues)",
		min = 0, max = 10000, step = 10,
		unit = "GP"
	})

	-- Spacer
	local spacer1 = AceGUI:Create("Label")
	spacer1:SetText(" ")
	spacer1:SetFullWidth(true)
	scroll:AddChild(spacer1)

	-- ============================================
	-- SECTION: GP Modifiers
	-- ============================================
	local modifiersHeader = AceGUI:Create("Heading")
	modifiersHeader:SetText("GP Modifiers")
	modifiersHeader:SetFullWidth(true)
	scroll:AddChild(modifiersHeader)

	CreateSliderRow(scroll, {
		key = "config.epgp.offspecMultiplier",
		label = "Off-Spec Multiplier",
		desc = "GP multiplier for off-spec items (50% means half GP cost)",
		min = 0, max = 100, step = 5,
		isPercent = true, percentStorage = "normalized",
		unit = "%"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.minorUpgradeMultiplier",
		label = "Minor Upgrade Multiplier",
		desc = "GP multiplier for minor upgrades",
		min = 0, max = 100, step = 5,
		isPercent = true, percentStorage = "normalized",
		unit = "%"
	})

	CreateSliderRow(scroll, {
		key = "config.epgp.minorUpgradeIlvlDelta",
		label = "Minor Upgrade iLvl Delta",
		desc = "Max iLvl difference to consider as minor upgrade",
		min = 0, max = 50, step = 1,
		unit = "iLvl"
	})

	-- Spacer
	local spacer2 = AceGUI:Create("Label")
	spacer2:SetText(" ")
	spacer2:SetFullWidth(true)
	scroll:AddChild(spacer2)

	-- ============================================
	-- SECTION: GP Base Values Configuration (Paper Doll)
	-- ============================================
	local slotHeader = AceGUI:Create("Heading")
	slotHeader:SetText("GP Base Values Configuration")
	slotHeader:SetFullWidth(true)
	scroll:AddChild(slotHeader)

	-- Description
	local slotDesc = AceGUI:Create("Label")
	slotDesc:SetText("|cff888888Set the default GP cost for each item slot. Press Enter to save.|r")
	slotDesc:SetFullWidth(true)
	scroll:AddChild(slotDesc)

	-- Paper doll container (native frame for precise positioning)
	local dollWrapper = AceGUI:Create("SimpleGroup")
	dollWrapper:SetFullWidth(true)
	dollWrapper:SetHeight(340)
	dollWrapper:SetLayout("Fill")
	scroll:AddChild(dollWrapper)

	local dollFrame = self:TrackContentFrame(CreateFrame("Frame", nil, dollWrapper.frame, "BackdropTemplate"))
	dollFrame:SetAllPoints()
	dollFrame:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		edgeSize = 12,
		insets = { left = 2, right = 2, top = 2, bottom = 2 }
	})
	dollFrame:SetBackdropColor(0.05, 0.05, 0.05, 0.8)
	dollFrame:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)

	-- Get slot weights from config
	local config = Cerebro.db.global.config.epgp.slotWeights or {}

	-- Slot icon atlas mappings (use WoW's paper doll slot textures)
	local slotAtlas = {
		INVTYPE_HEAD = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Head",
		INVTYPE_NECK = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Neck",
		INVTYPE_SHOULDER = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Shoulder",
		INVTYPE_CLOAK = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Chest",  -- No cloak slot icon
		INVTYPE_CHEST = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Chest",
		INVTYPE_WRIST = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Wrists",
		INVTYPE_HAND = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Hands",
		INVTYPE_WAIST = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Waist",
		INVTYPE_LEGS = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Legs",
		INVTYPE_FEET = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Feet",
		INVTYPE_FINGER = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Finger",
		INVTYPE_TRINKET = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Trinket",
		INVTYPE_WEAPON = "Interface\\PaperDoll\\UI-PaperDoll-Slot-MainHand",
		INVTYPE_SHIELD = "Interface\\PaperDoll\\UI-PaperDoll-Slot-SecondaryHand",
		INVTYPE_RANGED = "Interface\\PaperDoll\\UI-PaperDoll-Slot-Ranged",
		INVTYPE_2HWEAPON = "Interface\\PaperDoll\\UI-PaperDoll-Slot-MainHand",
		INVTYPE_WEAPONMAINHAND = "Interface\\PaperDoll\\UI-PaperDoll-Slot-MainHand",
		INVTYPE_WEAPONOFFHAND = "Interface\\PaperDoll\\UI-PaperDoll-Slot-SecondaryHand",
		INVTYPE_HOLDABLE = "Interface\\PaperDoll\\UI-PaperDoll-Slot-SecondaryHand",
	}

	-- Slot size
	local SLOT_SIZE = 30
	local SLOT_GAP = 6
	local EDIT_WIDTH = 40
	local EDIT_HEIGHT = 18
	local SLOT_TOTAL_HEIGHT = SLOT_SIZE + SLOT_GAP

	-- Helper: Create left-side slot (edit box on LEFT of icon)
	local function CreateLeftSlot(parent, slotKey, slotLabel, x, y)
		local slotFrame = self:TrackContentFrame(CreateFrame("Frame", nil, parent))
		slotFrame:SetSize(EDIT_WIDTH + SLOT_SIZE + 10, SLOT_SIZE)
		slotFrame:SetPoint("TOPLEFT", x, -y)

		-- Edit box on left
		local editFrame = self:TrackContentFrame(CreateFrame("EditBox", nil, slotFrame, "BackdropTemplate"))
		editFrame:SetSize(EDIT_WIDTH, EDIT_HEIGHT)
		editFrame:SetPoint("LEFT", 0, 0)
		editFrame:SetBackdrop({
			bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
			edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
			edgeSize = 8,
			insets = { left = 2, right = 2, top = 2, bottom = 2 }
		})
		editFrame:SetBackdropColor(0.1, 0.1, 0.1, 0.9)
		editFrame:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
		editFrame:SetFontObject("GameFontHighlightSmall")
		editFrame:SetJustifyH("CENTER")
		editFrame:SetAutoFocus(false)
		editFrame:SetText(tostring(config[slotKey] or 0))

		-- Icon on right of edit
		local icon = slotFrame:CreateTexture(nil, "ARTWORK")
		icon:SetSize(SLOT_SIZE, SLOT_SIZE)
		icon:SetPoint("LEFT", editFrame, "RIGHT", 4, 0)
		icon:SetTexture(slotAtlas[slotKey] or "Interface\\PaperDoll\\UI-PaperDoll-Slot-Chest")

		-- Border around icon
		local border = self:TrackContentFrame(CreateFrame("Frame", nil, slotFrame, "BackdropTemplate"))
		border:SetSize(SLOT_SIZE + 4, SLOT_SIZE + 4)
		border:SetPoint("CENTER", icon, "CENTER", 0, 0)
		border:SetBackdrop({ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 8 })
		border:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)

		-- Save handlers
		editFrame:SetScript("OnEnterPressed", function(self)
			local val = tonumber(self:GetText())
			if val and val >= 0 then
				if not Cerebro.db.global.config.epgp.slotWeights then Cerebro.db.global.config.epgp.slotWeights = {} end
				Cerebro.db.global.config.epgp.slotWeights[slotKey] = val
				Cerebro.Ledger:AddAuditLog("GP_CONFIG", string.format("Updated %s GP to %d", slotLabel, val))
				Cerebro:Print(string.format("Updated %s GP to %d", slotLabel, val))
				border:SetBackdropBorderColor(0, 1, 0, 1)
				C_Timer.After(0.5, function() border:SetBackdropBorderColor(0.4, 0.4, 0.4, 1) end)
			else
				self:SetText(tostring(config[slotKey] or 0))
			end
			self:ClearFocus()
		end)
		editFrame:SetScript("OnEscapePressed", function(self) self:SetText(tostring(config[slotKey] or 0)); self:ClearFocus() end)

		-- Tooltip
		slotFrame:EnableMouse(true)
		slotFrame:SetScript("OnEnter", function() GameTooltip:SetOwner(slotFrame, "ANCHOR_RIGHT"); GameTooltip:AddLine(slotLabel, 1, 0.82, 0); GameTooltip:Show() end)
		slotFrame:SetScript("OnLeave", function() GameTooltip:Hide() end)
		icon:EnableMouse(true)
		icon:SetScript("OnEnter", function() GameTooltip:SetOwner(slotFrame, "ANCHOR_RIGHT"); GameTooltip:AddLine(slotLabel, 1, 0.82, 0); GameTooltip:Show() end)
		icon:SetScript("OnLeave", function() GameTooltip:Hide() end)

		return slotFrame
	end

	-- Helper: Create right-side slot (edit box on RIGHT of icon)
	local function CreateRightSlot(parent, slotKey, slotLabel, x, y)
		local slotFrame = self:TrackContentFrame(CreateFrame("Frame", nil, parent))
		slotFrame:SetSize(EDIT_WIDTH + SLOT_SIZE + 10, SLOT_SIZE)
		slotFrame:SetPoint("TOPRIGHT", x, -y)

		-- Icon on left
		local icon = slotFrame:CreateTexture(nil, "ARTWORK")
		icon:SetSize(SLOT_SIZE, SLOT_SIZE)
		icon:SetPoint("LEFT", 0, 0)
		icon:SetTexture(slotAtlas[slotKey] or "Interface\\PaperDoll\\UI-PaperDoll-Slot-Chest")

		-- Border around icon
		local border = self:TrackContentFrame(CreateFrame("Frame", nil, slotFrame, "BackdropTemplate"))
		border:SetSize(SLOT_SIZE + 4, SLOT_SIZE + 4)
		border:SetPoint("CENTER", icon, "CENTER", 0, 0)
		border:SetBackdrop({ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 8 })
		border:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)

		-- Edit box on right of icon
		local editFrame = self:TrackContentFrame(CreateFrame("EditBox", nil, slotFrame, "BackdropTemplate"))
		editFrame:SetSize(EDIT_WIDTH, EDIT_HEIGHT)
		editFrame:SetPoint("LEFT", icon, "RIGHT", 4, 0)
		editFrame:SetBackdrop({
			bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
			edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
			edgeSize = 8,
			insets = { left = 2, right = 2, top = 2, bottom = 2 }
		})
		editFrame:SetBackdropColor(0.1, 0.1, 0.1, 0.9)
		editFrame:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
		editFrame:SetFontObject("GameFontHighlightSmall")
		editFrame:SetJustifyH("CENTER")
		editFrame:SetAutoFocus(false)
		editFrame:SetText(tostring(config[slotKey] or 0))

		-- Save handlers
		editFrame:SetScript("OnEnterPressed", function(self)
			local val = tonumber(self:GetText())
			if val and val >= 0 then
				if not Cerebro.db.global.config.epgp.slotWeights then Cerebro.db.global.config.epgp.slotWeights = {} end
				Cerebro.db.global.config.epgp.slotWeights[slotKey] = val
				Cerebro.Ledger:AddAuditLog("GP_CONFIG", string.format("Updated %s GP to %d", slotLabel, val))
				Cerebro:Print(string.format("Updated %s GP to %d", slotLabel, val))
				border:SetBackdropBorderColor(0, 1, 0, 1)
				C_Timer.After(0.5, function() border:SetBackdropBorderColor(0.4, 0.4, 0.4, 1) end)
			else
				self:SetText(tostring(config[slotKey] or 0))
			end
			self:ClearFocus()
		end)
		editFrame:SetScript("OnEscapePressed", function(self) self:SetText(tostring(config[slotKey] or 0)); self:ClearFocus() end)

		-- Tooltip
		slotFrame:EnableMouse(true)
		slotFrame:SetScript("OnEnter", function() GameTooltip:SetOwner(slotFrame, "ANCHOR_RIGHT"); GameTooltip:AddLine(slotLabel, 1, 0.82, 0); GameTooltip:Show() end)
		slotFrame:SetScript("OnLeave", function() GameTooltip:Hide() end)
		icon:EnableMouse(true)
		icon:SetScript("OnEnter", function() GameTooltip:SetOwner(slotFrame, "ANCHOR_RIGHT"); GameTooltip:AddLine(slotLabel, 1, 0.82, 0); GameTooltip:Show() end)
		icon:SetScript("OnLeave", function() GameTooltip:Hide() end)

		return slotFrame
	end

	-- Helper: Create weapon slot (icon with overlay text + edit below)
	local function CreateWeaponSlot(parent, slotKey, slotLabel, overlay, x, y)
		local slotFrame = self:TrackContentFrame(CreateFrame("Frame", nil, parent))
		slotFrame:SetSize(SLOT_SIZE + 4, SLOT_SIZE + EDIT_HEIGHT + 4)
		slotFrame:SetPoint("TOPLEFT", x, -y)

		-- Icon
		local icon = slotFrame:CreateTexture(nil, "ARTWORK")
		icon:SetSize(SLOT_SIZE, SLOT_SIZE)
		icon:SetPoint("TOP", 0, 0)
		icon:SetTexture(slotAtlas[slotKey] or "Interface\\PaperDoll\\UI-PaperDoll-Slot-MainHand")

		-- Overlay text (1H, 2H, MH, etc.)
		local overlayText = slotFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
		overlayText:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -2, 2)
		overlayText:SetText("|cffFFD700" .. overlay .. "|r")

		-- Border
		local border = self:TrackContentFrame(CreateFrame("Frame", nil, slotFrame, "BackdropTemplate"))
		border:SetSize(SLOT_SIZE + 4, SLOT_SIZE + 4)
		border:SetPoint("CENTER", icon, "CENTER", 0, 0)
		border:SetBackdrop({ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 8 })
		border:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)

		-- Edit box below
		local editFrame = self:TrackContentFrame(CreateFrame("EditBox", nil, slotFrame, "BackdropTemplate"))
		editFrame:SetSize(SLOT_SIZE + 4, EDIT_HEIGHT)
		editFrame:SetPoint("TOP", icon, "BOTTOM", 0, -2)
		editFrame:SetBackdrop({
			bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
			edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
			edgeSize = 8,
			insets = { left = 2, right = 2, top = 2, bottom = 2 }
		})
		editFrame:SetBackdropColor(0.1, 0.1, 0.1, 0.9)
		editFrame:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
		editFrame:SetFontObject("GameFontHighlightSmall")
		editFrame:SetJustifyH("CENTER")
		editFrame:SetAutoFocus(false)
		editFrame:SetText(tostring(config[slotKey] or 0))

		-- Save handlers
		editFrame:SetScript("OnEnterPressed", function(self)
			local val = tonumber(self:GetText())
			if val and val >= 0 then
				if not Cerebro.db.global.config.epgp.slotWeights then Cerebro.db.global.config.epgp.slotWeights = {} end
				Cerebro.db.global.config.epgp.slotWeights[slotKey] = val
				Cerebro.Ledger:AddAuditLog("GP_CONFIG", string.format("Updated %s GP to %d", slotLabel, val))
				Cerebro:Print(string.format("Updated %s GP to %d", slotLabel, val))
				border:SetBackdropBorderColor(0, 1, 0, 1)
				C_Timer.After(0.5, function() border:SetBackdropBorderColor(0.4, 0.4, 0.4, 1) end)
			else
				self:SetText(tostring(config[slotKey] or 0))
			end
			self:ClearFocus()
		end)
		editFrame:SetScript("OnEscapePressed", function(self) self:SetText(tostring(config[slotKey] or 0)); self:ClearFocus() end)

		-- Tooltip
		slotFrame:EnableMouse(true)
		slotFrame:SetScript("OnEnter", function() GameTooltip:SetOwner(slotFrame, "ANCHOR_TOP"); GameTooltip:AddLine(slotLabel, 1, 0.82, 0); GameTooltip:Show() end)
		slotFrame:SetScript("OnLeave", function() GameTooltip:Hide() end)

		return slotFrame
	end

	-- Layout constants
	local LEFT_X = 10
	local RIGHT_X = -10
	local TOP_Y = 10

	-- LEFT COLUMN: Matches WoW character frame (Head → Wrist, top to bottom)
	local leftSlots = {
		{ key = "INVTYPE_HEAD", label = "Head" },
		{ key = "INVTYPE_NECK", label = "Neck" },
		{ key = "INVTYPE_SHOULDER", label = "Shoulder" },
		{ key = "INVTYPE_CLOAK", label = "Back" },
		{ key = "INVTYPE_CHEST", label = "Chest" },
		{ key = "INVTYPE_WRIST", label = "Wrist" },
	}

	for i, slot in ipairs(leftSlots) do
		CreateLeftSlot(dollFrame, slot.key, slot.label, LEFT_X, TOP_Y + (i-1) * SLOT_TOTAL_HEIGHT)
	end

	-- RIGHT COLUMN: Matches WoW character frame (Hands → Trinket, top to bottom)
	local rightSlots = {
		{ key = "INVTYPE_HAND", label = "Hands" },
		{ key = "INVTYPE_WAIST", label = "Waist" },
		{ key = "INVTYPE_LEGS", label = "Legs" },
		{ key = "INVTYPE_FEET", label = "Feet" },
		{ key = "INVTYPE_FINGER", label = "Ring" },
		{ key = "INVTYPE_TRINKET", label = "Trinket" },
	}

	for i, slot in ipairs(rightSlots) do
		CreateRightSlot(dollFrame, slot.key, slot.label, RIGHT_X, TOP_Y + (i-1) * SLOT_TOTAL_HEIGHT)
	end

	-- CENTER: 3D Character Model (fill the space between columns)
	local modelWidth = 140
	local modelHeight = 180  -- Taller to fill vertical space
	local modelFrame = self:TrackContentFrame(CreateFrame("PlayerModel", nil, dollFrame))
	modelFrame:SetSize(modelWidth, modelHeight)
	modelFrame:SetPoint("CENTER", dollFrame, "CENTER", 0, 60)  -- Move higher
	modelFrame:SetUnit("player")
	modelFrame:SetCamDistanceScale(0.8)  -- Zoom in
	modelFrame:SetPosition(0, 0, -0.3)   -- Raise model in frame
	modelFrame:SetRotation(math.rad(15))
	modelFrame:SetAnimation(0)  -- Idle (prevents drift)

	-- BOTTOM ROW: Weapons with overlays (in-line with 6th slot row)
	local bottomY = TOP_Y + 5 * SLOT_TOTAL_HEIGHT  -- Same Y as 6th slot row
	local weaponSlots = {
		{ key = "INVTYPE_WEAPON", label = "Weapon (1H)", overlay = "1H" },
		{ key = "INVTYPE_2HWEAPON", label = "Weapon (2H)", overlay = "2H" },
		{ key = "INVTYPE_WEAPONMAINHAND", label = "Main Hand", overlay = "MH" },
		{ key = "INVTYPE_WEAPONOFFHAND", label = "Off Hand", overlay = "OH" },
		{ key = "INVTYPE_SHIELD", label = "Shield", overlay = "SH" },
		{ key = "INVTYPE_RANGED", label = "Ranged", overlay = "RD" },
		{ key = "INVTYPE_HOLDABLE", label = "Off Hand (Frill)", overlay = "FR" },
	}

	local weaponWidth = SLOT_SIZE + 8
	local totalWeaponsWidth = #weaponSlots * weaponWidth
	-- Create a container frame for weapons, centered in dollFrame
	local weaponContainer = self:TrackContentFrame(CreateFrame("Frame", nil, dollFrame))
	weaponContainer:SetSize(totalWeaponsWidth, SLOT_SIZE + EDIT_HEIGHT + 4)
	weaponContainer:SetPoint("TOP", dollFrame, "TOP", 0, -bottomY)

	for i, slot in ipairs(weaponSlots) do
		CreateWeaponSlot(weaponContainer, slot.key, slot.label, slot.overlay, (i-1) * weaponWidth, 0)
	end
end
