--[[
    Cerebro - UISandbox Guild M+ History Tab
    Extracted from UI/UISandbox.lua (Phase 2a decomposition)

    @module UI.Tabs.GuildMPlusHistory
    @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: Guild M+ History
===============================================]]

function UISandbox:DrawGuildMPlusHistoryTab(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

	-- Cleanup native frames from previous render
	self.guildMplusNativeFrames = self.guildMplusNativeFrames or {}
	for _, frame in ipairs(self.guildMplusNativeFrames) do
		if frame and frame.Hide then
			frame:Hide()
			frame:SetParent(nil)
		end
	end
	self.guildMplusNativeFrames = {}

	local function TrackFrame(frame)
		if frame then table.insert(self.guildMplusNativeFrames, frame) end
		return frame
	end

	local ROW_HEIGHT = 36

	-- Dungeon lookup table
	local DUNGEON_NAMES = {
		[2660] = "Ara-Kara", [2662] = "Dawnbreaker", [2651] = "Stonevault",
		[2649] = "Priory", [2669] = "Floodgate", [2773] = "Eco-Dome",
		[2287] = "Halls of Atonement", [2441] = "Tazavesh: Streets",
	}

	local function GetDungeonName(run)
		if run.mapName and run.mapName ~= "" then return run.mapName end
		if run.mapID and DUNGEON_NAMES[run.mapID] then return DUNGEON_NAMES[run.mapID] end
		if run.mapID then
			local name = C_ChallengeMode.GetMapUIInfo(run.mapID)
			if name then return name end
		end
		return "Unknown"
	end

	local runs = Cerebro.db.global.guildMplusRuns or {}

	-- Initialize filter state
	self.guildMplusFilters = self.guildMplusFilters or { player = "", dungeon = "", level = "", result = "" }

	-- Build unique values for dropdowns
	local players = { [""] = "All Players" }
	local dungeons = { [""] = "All Dungeons" }
	local levels = { [""] = "All Levels" }
	local results = { [""] = "All Results", ["success"] = "Timed", ["fail"] = "Untimed" }

	for _, run in ipairs(runs) do
		local p = Cerebro:GetFullPlayerName(run.uploadedBy or "Unknown")
		players[p] = p
		local d = GetDungeonName(run)
		dungeons[d] = d
		local l = "+" .. (run.level or 0)
		levels[l] = l
	end

	-- Filter bar
	local filterGroup = AceGUI:Create("SimpleGroup")
	filterGroup:SetFullWidth(true)
	filterGroup:SetLayout("Flow")
	container:AddChild(filterGroup)

	local playerDD = AceGUI:Create("Dropdown")
	playerDD:SetLabel("")
	playerDD:SetWidth(150)
	playerDD:SetList(players)
	playerDD:SetValue(self.guildMplusFilters.player or "")
	playerDD:SetCallback("OnValueChanged", function(_, _, val)
		self.guildMplusFilters.player = val
		container:ReleaseChildren()
		self:DrawGuildMPlusHistoryTab(container)
	end)
	filterGroup:AddChild(playerDD)

	local dungeonDD = AceGUI:Create("Dropdown")
	dungeonDD:SetLabel("")
	dungeonDD:SetWidth(120)
	dungeonDD:SetList(dungeons)
	dungeonDD:SetValue(self.guildMplusFilters.dungeon or "")
	dungeonDD:SetCallback("OnValueChanged", function(_, _, val)
		self.guildMplusFilters.dungeon = val
		container:ReleaseChildren()
		self:DrawGuildMPlusHistoryTab(container)
	end)
	filterGroup:AddChild(dungeonDD)

	local levelDD = AceGUI:Create("Dropdown")
	levelDD:SetLabel("")
	levelDD:SetWidth(70)
	levelDD:SetList(levels)
	levelDD:SetValue(self.guildMplusFilters.level or "")
	levelDD:SetCallback("OnValueChanged", function(_, _, val)
		self.guildMplusFilters.level = val
		container:ReleaseChildren()
		self:DrawGuildMPlusHistoryTab(container)
	end)
	filterGroup:AddChild(levelDD)

	local resultDD = AceGUI:Create("Dropdown")
	resultDD:SetLabel("")
	resultDD:SetWidth(90)
	resultDD:SetList(results)
	resultDD:SetValue(self.guildMplusFilters.result or "")
	resultDD:SetCallback("OnValueChanged", function(_, _, val)
		self.guildMplusFilters.result = val
		container:ReleaseChildren()
		self:DrawGuildMPlusHistoryTab(container)
	end)
	filterGroup:AddChild(resultDD)

	-- Apply filters
	local filtered = {}
	for _, run in ipairs(runs) do
		local pass = true
		if self.guildMplusFilters.player ~= "" then
			local p = Cerebro:GetFullPlayerName(run.uploadedBy or "Unknown")
			if p ~= self.guildMplusFilters.player then pass = false end
		end
		if pass and self.guildMplusFilters.dungeon ~= "" then
			if GetDungeonName(run) ~= self.guildMplusFilters.dungeon then pass = false end
		end
		if pass and self.guildMplusFilters.level ~= "" then
			if "+" .. (run.level or 0) ~= self.guildMplusFilters.level then pass = false end
		end
		if pass and self.guildMplusFilters.result ~= "" then
			if self.guildMplusFilters.result == "success" and not run.success then pass = false end
			if self.guildMplusFilters.result == "fail" and run.success then pass = false end
		end
		if pass then table.insert(filtered, run) end
	end

	-- Main content area
	local mainGroup = AceGUI:Create("InlineGroup")
	mainGroup:SetTitle("")
	mainGroup:SetFullWidth(true)
	mainGroup:SetFullHeight(true)
	mainGroup:SetLayout("Fill")
	container:AddChild(mainGroup)

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

	-- Empty state
	if #filtered == 0 then
		local lbl = AceGUI:Create("Label")
		if #runs == 0 then
			lbl:SetText("\n\nNo guild M+ runs recorded yet.\n\nRuns will appear here as guild members complete M+ dungeons.")
		else
			lbl:SetText("\n\nNo runs match the selected filters.")
		end
		lbl:SetColor(0.5, 0.5, 0.5)
		lbl:SetFullWidth(true)
		scroll:AddChild(lbl)
		return
	end

	-- Sort by timestamp descending
	table.sort(filtered, function(a, b)
		return (a.timestamp or 0) > (b.timestamp or 0)
	end)

	-- Header row
	local headerWrapper = AceGUI:Create("SimpleGroup")
	headerWrapper:SetLayout("Fill")
	headerWrapper:SetFullWidth(true)
	headerWrapper:SetHeight(24)
	scroll:AddChild(headerWrapper)

	local hf = TrackFrame(CreateFrame("Frame", nil, headerWrapper.frame))
	hf:SetAllPoints()

	local fsPlayer = hf:CreateFontString(nil, "OVERLAY", "GameFontNormal")
	fsPlayer:SetPoint("LEFT", 10, 0)
	fsPlayer:SetText("|cffFFD700Player|r")

	local fsLevel = hf:CreateFontString(nil, "OVERLAY", "GameFontNormal")
	fsLevel:SetPoint("LEFT", 180, 0)
	fsLevel:SetText("|cffFFD700Level / Dungeon|r")

	local fsParty = hf:CreateFontString(nil, "OVERLAY", "GameFontNormal")
	fsParty:SetPoint("LEFT", 380, 0)
	fsParty:SetText("|cffFFD700Party|r")

	local fsResult = hf:CreateFontString(nil, "OVERLAY", "GameFontNormal")
	fsResult:SetPoint("RIGHT", -10, 0)
	fsResult:SetText("|cffFFD700Result|r")

	-- Data rows (max 100)
	local displayCount = math.min(#filtered, 100)
	local roleOrder = { TANK = 1, HEALER = 2, HEALS = 2, DAMAGER = 3, DPS = 3, DMG = 3 }

	for i = 1, displayCount do
		local run = filtered[i]
		local isStripe = (i % 2 == 0)

		local wrapper = AceGUI:Create("SimpleGroup")
		wrapper:SetLayout("Fill")
		wrapper:SetFullWidth(true)
		wrapper:SetHeight(ROW_HEIGHT)
		scroll:AddChild(wrapper)

		local f = TrackFrame(CreateFrame("Frame", nil, wrapper.frame, "BackdropTemplate"))
		f:SetAllPoints()

		if isStripe then
			local bg = f:CreateTexture(nil, "BACKGROUND")
			bg:SetAllPoints()
			bg:SetColorTexture(1, 1, 1, 0.05)
		end

		-- A. Player Name (class-colored)
		local fullName = Cerebro:GetFullPlayerName(run.uploadedBy or "Unknown")
		local playerClass = nil
		if run.group then
			for _, member in ipairs(run.group) do
				if (member.name or ""):find("^" .. (run.uploadedBy or "")) then
					playerClass = member.class and string.upper(member.class)
					break
				end
			end
		end
		if not playerClass then
			local playerData = Cerebro.db.global.players and Cerebro.db.global.players[fullName]
			playerClass = playerData and playerData.class
		end

		local classColor = "|cffFFFFFF"
		if playerClass and RAID_CLASS_COLORS and RAID_CLASS_COLORS[playerClass] then
			classColor = "|c" .. RAID_CLASS_COLORS[playerClass].colorStr
		end

		local playerFS = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
		playerFS:SetPoint("LEFT", 10, 0)
		playerFS:SetWidth(160)
		playerFS:SetText(classColor .. fullName .. "|r")
		playerFS:SetJustifyH("LEFT")

		-- B. Level Badge
		local level = run.level or 0
		local levelColor = level >= 20 and "|cffFF8000" or level >= 15 and "|cffA335EE" or level >= 10 and "|cff0070DD" or "|cffFFFFFF"
		local lvlFS = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
		lvlFS:SetPoint("LEFT", 180, 0)
		lvlFS:SetText(levelColor .. "+" .. level .. "|r")

		-- C. Dungeon Name
		local nameFS = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
		nameFS:SetPoint("LEFT", 225, 0)
		nameFS:SetWidth(140)
		nameFS:SetText(GetDungeonName(run))
		nameFS:SetJustifyH("LEFT")
		nameFS:SetWordWrap(false)

		-- D. Party Icons
		local startX = 380
		local iconSize = 24
		local sortedGroup = {}
		for _, m in ipairs(run.group or {}) do table.insert(sortedGroup, m) end
		table.sort(sortedGroup, function(a, b)
			return (roleOrder[a.role] or 4) < (roleOrder[b.role] or 4)
		end)

		for j, member in ipairs(sortedGroup) do
			local iframe = TrackFrame(CreateFrame("Frame", nil, f))
			iframe:SetSize(iconSize, iconSize)
			iframe:SetPoint("LEFT", startX + ((j - 1) * (iconSize + 4)), 0)

			local bgCircle = iframe:CreateTexture(nil, "BACKGROUND")
			bgCircle:SetAllPoints()
			bgCircle:SetTexture("Interface\\CharacterFrame\\TempPortraitAlphaMask")

			local classKey = string.upper(member.class or "PRIEST")
			local cc = RAID_CLASS_COLORS and RAID_CLASS_COLORS[classKey]
			if cc then bgCircle:SetVertexColor(cc.r, cc.g, cc.b, 1)
			else bgCircle:SetVertexColor(0.5, 0.5, 0.5, 1) end

			local roleIcon = iframe:CreateTexture(nil, "ARTWORK")
			roleIcon:SetSize(15, 15)
			roleIcon:SetPoint("CENTER")

			local role = member.role
			if role == "TANK" then roleIcon:SetAtlas("roleicon-tiny-tank")
			elseif role == "HEALER" or role == "HEALS" then roleIcon:SetAtlas("roleicon-tiny-healer")
			else roleIcon:SetAtlas("roleicon-tiny-dps") end

			iframe:SetScript("OnEnter", function(self)
				GameTooltip:SetOwner(self, "ANCHOR_TOP")
				local cStr = member.class and RAID_CLASS_COLORS and RAID_CLASS_COLORS[string.upper(member.class)]
					and "|c" .. RAID_CLASS_COLORS[string.upper(member.class)].colorStr or "|cffFFFFFF"
				GameTooltip:AddLine(cStr .. (member.name or "Unknown") .. "|r")
				GameTooltip:Show()
			end)
			iframe:SetScript("OnLeave", function() GameTooltip:Hide() end)
		end

		-- E. Result
		local statusIcon = run.success
			and "|TInterface\\RaidFrame\\ReadyCheck-Ready:20|t"
			or "|TInterface\\RaidFrame\\ReadyCheck-NotReady:20|t"

		local statusFS = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
		statusFS:SetPoint("RIGHT", -10, 0)
		statusFS:SetText(statusIcon)

		-- F. EP Award
		local epFS = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
		epFS:SetPoint("RIGHT", statusFS, "LEFT", -10, 0)
		epFS:SetText("|cff00ff00+" .. (run.totalEP or 0) .. " EP|r")

		-- G. Time
		local mins = math.floor((run.duration or 0) / 60)
		local secs = (run.duration or 0) % 60
		local timeStr = string.format("%d:%02d", mins, secs)
		if run.upgrade and run.upgrade > 0 then
			timeStr = timeStr .. " |cff00ff00(+" .. run.upgrade .. ")|r"
		end

		local timeFS = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
		timeFS:SetPoint("RIGHT", epFS, "LEFT", -20, 0)
		timeFS:SetText(timeStr)
	end

	if #filtered > displayCount then
		local moreLabel = AceGUI:Create("Label")
		moreLabel:SetText(string.format("\n|cff888888Showing %d of %d runs.|r", displayCount, #filtered))
		moreLabel:SetFullWidth(true)
		scroll:AddChild(moreLabel)
	end
end
