local addonName, addon = ...
local L = LibStub('AceLocale-3.0'):GetLocale('SpartanUI', true)

addon.BugWindow = {}

local window, currentErrorIndex, currentErrorList, currentSession
local countLabel, sessionLabel, textArea, nextButton, prevButton, tabs
local searchBox, filterButton
local categoryButtons = {}

local function updateDisplay(forceRefresh)
	if forceRefresh or not currentErrorIndex then currentErrorIndex = #currentErrorList end

	local err = currentErrorList[currentErrorIndex]
	if err then
		countLabel:SetText(string.format('%d/%d', currentErrorIndex, #currentErrorList))
		sessionLabel:SetText(string.format(L['Session: %d'], err.session))
		textArea:SetText(addon.ErrorHandler:FormatError(err))

		nextButton:SetEnabled(currentErrorIndex < #currentErrorList)
		prevButton:SetEnabled(currentErrorIndex > 1)
	else
		countLabel:SetText('0/0')
		sessionLabel:SetText(L['No errors'])
		textArea:SetText(L['You have no errors, yay!'])

		nextButton:SetEnabled(false)
		prevButton:SetEnabled(false)
	end
end

local function setActiveCategory(button)
	-- Update button visuals
	for _, btn in ipairs(categoryButtons) do
		btn:SetNormalAtlas('auctionhouse-nav-button')
		btn.Text:SetTextColor(0.6, 0.6, 0.6)
	end
	button:SetNormalAtlas('auctionhouse-nav-button-secondary-select')
	button.Text:SetTextColor(1, 1, 1)

	-- Set current error list based on selected category
	if button:GetID() == 1 then -- All errors
		currentErrorList = addon.ErrorHandler:GetErrors()
	elseif button:GetID() == 2 then -- Current session
		currentErrorList = addon.ErrorHandler:GetErrors(addon.ErrorHandler:GetCurrentSession())
	elseif button:GetID() == 3 then -- Previous session
		local sessionList = addon.ErrorHandler:GetSessionList()
		local prevSession = sessionList[#sessionList - 1]
		currentErrorList = addon.ErrorHandler:GetErrors(prevSession)
	end

	updateDisplay(true)
end

local function createCategoryButton(parent, id, text, point)
	local button = CreateFrame('Button', nil, parent)
	button:SetSize(120, 30)
	button:SetID(id)
	button:SetPoint(unpack(point))

	button:SetNormalAtlas('auctionhouse-nav-button')
	button:SetHighlightAtlas('auctionhouse-nav-button-highlight')

	button.Text = button:CreateFontString(nil, 'OVERLAY', 'GameFontNormal')
	button.Text:SetPoint('CENTER')
	button.Text:SetText(text)
	button.Text:SetTextColor(0.6, 0.6, 0.6)

	button:SetScript('OnClick', function(self)
		setActiveCategory(self)
	end)

	button:SetScript('OnEnter', function(self)
		if self:GetNormalAtlas() ~= 'auctionhouse-nav-button-secondary-select' then self.Text:SetTextColor(1, 1, 1) end
	end)

	button:SetScript('OnLeave', function(self)
		if self:GetNormalAtlas() ~= 'auctionhouse-nav-button-secondary-select' then self.Text:SetTextColor(0.6, 0.6, 0.6) end
	end)

	return button
end

local function filterErrors()
	local searchText = searchBox:GetText():lower()
	if searchText == '' then
		currentErrorList = addon.ErrorHandler:GetErrors()
	else
		currentErrorList = {}
		for _, err in ipairs(addon.ErrorHandler:GetErrors()) do
			if err.message:lower():find(searchText) or err.stack:lower():find(searchText) or (err.locals and err.locals:lower():find(searchText)) then table.insert(currentErrorList, err) end
		end
	end
	updateDisplay(true)
end

function addon.BugWindow.Create()
	window = CreateFrame('Frame', 'SUIErrorWindow', UIParent, 'SettingsFrameTemplate')
	window:SetFrameStrata('DIALOG')
	window:SetSize(920, 724)
	window:SetPoint('CENTER')
	window:SetMovable(true)
	window:SetResizable(true)
	window:EnableMouse(true)
	window:SetClampedToScreen(true)
	window:SetDontSavePosition(true)

	local title = window:CreateFontString(nil, 'OVERLAY', 'GameFontNormalLarge')
	title:SetPoint('TOPLEFT', 32, -27)
	title:SetText(L['SpartanUI Error Display'])

	countLabel = window:CreateFontString(nil, 'OVERLAY', 'GameFontNormal')
	countLabel:SetPoint('TOPRIGHT', -15, -27)

	sessionLabel = window:CreateFontString(nil, 'OVERLAY', 'GameFontNormal')
	sessionLabel:SetPoint('TOP', 0, -27)

	-- Create category buttons
	local buttonNames = { L['All Errors'], L['Current Session'], L['Previous Session'] }
	for i, name in ipairs(buttonNames) do
		local point = { 'TOPLEFT', window, 'TOPLEFT', 32 + (i - 1) * 125, -64 }
		local button = createCategoryButton(window, i, name, point)
		table.insert(categoryButtons, button)
	end

	local innerFrame = window:CreateTexture(nil, 'OVERLAY', nil, 2)
	innerFrame:SetAtlas('auctionhouse-background-index')
	innerFrame:SetPoint('TOPLEFT', 17, -96)
	innerFrame:SetPoint('BOTTOMRIGHT', -17, 17)

	local scrollFrame = CreateFrame('ScrollFrame', nil, window, 'UIPanelScrollFrameTemplate')
	scrollFrame:SetPoint('TOPLEFT', innerFrame)
	scrollFrame:SetPoint('BOTTOMRIGHT', innerFrame)

	textArea = CreateFrame('EditBox', nil, scrollFrame)
	textArea:SetMultiLine(true)
	textArea:SetFontObject(GameFontHighlight)
	textArea:SetWidth(scrollFrame:GetWidth())
	textArea:SetAutoFocus(false)
	textArea:SetScript('OnEscapePressed', textArea.ClearFocus)
	scrollFrame:SetScrollChild(textArea)

	prevButton = CreateFrame('Button', nil, window, 'UIPanelButtonTemplate')
	prevButton:SetSize(100, 22)
	prevButton:SetPoint('BOTTOMLEFT', 16, 16)
	prevButton:SetText(L['< Previous'])
	prevButton:SetScript('OnClick', function()
		if currentErrorIndex > 1 then
			currentErrorIndex = currentErrorIndex - 1
			updateDisplay()
		end
	end)

	nextButton = CreateFrame('Button', nil, window, 'UIPanelButtonTemplate')
	nextButton:SetSize(100, 22)
	nextButton:SetPoint('BOTTOMRIGHT', -16, 16)
	nextButton:SetText(L['Next >'])
	nextButton:SetScript('OnClick', function()
		if currentErrorIndex < #currentErrorList then
			currentErrorIndex = currentErrorIndex + 1
			updateDisplay()
		end
	end)

	local copyAllButton = CreateFrame('Button', nil, window, 'UIPanelButtonTemplate')
	copyAllButton:SetSize(120, 22)
	copyAllButton:SetPoint('BOTTOM', 0, 16)
	copyAllButton:SetText(L['Easy Copy All'])
	copyAllButton:SetScript('OnClick', function()
		local allErrors = ''
		for _, err in ipairs(currentErrorList) do
			allErrors = allErrors .. addon.ErrorHandler:FormatError(err) .. '\n\n---\n\n'
		end
		addon.Utils:CopyToClipboard(allErrors)
	end)

	local closeButton = CreateFrame('Button', nil, window, 'UIPanelCloseButton')
	closeButton:SetPoint('TOPRIGHT', -4, -4)
	closeButton:SetScript('OnClick', function()
		addon.BugWindow:CloseErrorWindow()
	end)

	searchBox = CreateFrame('EditBox', nil, window, 'SearchBoxTemplate')
	searchBox:SetSize(200, 20)
	searchBox:SetPoint('TOPLEFT', 32, -76)
	searchBox:SetAutoFocus(false)
	searchBox:SetScript('OnEnterPressed', filterErrors)

	filterButton = CreateFrame('Button', nil, window, 'UIPanelButtonTemplate')
	filterButton:SetSize(60, 22)
	filterButton:SetPoint('LEFT', searchBox, 'RIGHT', 5, 0)
	filterButton:SetText(L['Filter'])
	filterButton:SetScript('OnClick', filterErrors)

	window.currentErrorList = currentErrorList
	window:Hide()

	-- Add resize functionality
	window:SetResizable(true)
	window:SetMinResize(600, 400)

	local sizer = CreateFrame('Button', nil, window)
	sizer:SetPoint('BOTTOMRIGHT', -6, 7)
	sizer:SetSize(16, 16)
	sizer:SetNormalTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Up]])
	sizer:SetHighlightTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Highlight]])
	sizer:SetPushedTexture([[Interface\ChatFrame\UI-ChatIM-SizeGrabber-Down]])
	sizer:SetScript('OnMouseDown', function(_, button)
		if button == 'LeftButton' then window:StartSizing('BOTTOMRIGHT') end
	end)
	sizer:SetScript('OnMouseUp', function()
		window:StopMovingOrSizing()
	end)

	-- Set the first button as active
	setActiveCategory(categoryButtons[1])
end

function addon.BugWindow:OpenErrorWindow()
	if not window then addon.BugWindow.Create() end

	if not window:IsShown() then
		currentErrorList = addon.ErrorHandler:GetErrors()
		currentSession = addon.ErrorHandler:GetCurrentSession()
		currentErrorIndex = #currentErrorList
		updateDisplay(true)
		window:Show()
	else
		updateDisplay()
	end
end

function addon.BugWindow:CloseErrorWindow()
	if window then window:Hide() end
end

function addon.BugWindow:UpdateFontSize()
	if textArea then textArea:SetFontObject(_G[addon.Config.fontSize] or GameFontHighlight) end
end

function addon.BugWindow:IsShown()
	return window and window:IsShown()
end
