---@class SUI
local SUI = SUI
local logger = SUI:NewModule('Handler.Logger') ---@type SUI.Module
SUI.Handlers.Logger = logger
logger.description = 'SpartanUI Logging System'
----------------------------------------------------------------------------------------------------
local LogWindow = nil ---@type Frame
local LogMessages = {}
local ScrollListing = {}
local ActiveModule = nil

-- Log levels with colors, priorities, and display names
local LOG_LEVELS = {
	['debug'] = { color = '|cff888888', priority = 1, display = 'Debug' },
	['info'] = { color = '|cff00ff00', priority = 2, display = 'Info' },
	['warning'] = { color = '|cffffff00', priority = 3, display = 'Warning' },
	['error'] = { color = '|cffff0000', priority = 4, display = 'Error' },
	['critical'] = { color = '|cffff00ff', priority = 5, display = 'Critical' },
}

-- Global and per-module log level settings
local GlobalLogLevel = 2 -- Default to 'info' and above
local ModuleLogLevels = {} -- Per-module overrides

-- Search and UI state
local CurrentSearchTerm = ''
local SearchAllModules = false
local AutoScrollEnabled = true

-- Helper function to get log level by priority
local function GetLogLevelByPriority(priority)
	for level, data in pairs(LOG_LEVELS) do
		if data.priority == priority then return level, data end
	end
	return 'info', LOG_LEVELS['info'] -- Default fallback
end

-- Function to categorize modules like AuctionFrame categorizes items
local function CategorizeModule(moduleName)
	-- Define category rules (similar to AuctionFrame's item categorization)
	local categories = {
		['Core'] = { 'Core', 'Framework', 'Events', 'Options', 'Database', 'Profiles' },
		['UI Modules'] = { 'UnitFrames', 'Minimap', 'Artwork', 'ActionBars', 'ChatBox', 'Tooltips' },
		['External Addons'] = { 'LibsDataBar', 'LibsDisenchantAssist', 'Disenchant Assist', 'DataBar' },
		['Handlers'] = { 'Handler', 'Logger', 'ChatCommands', 'Compatibility' },
		['Development'] = { 'Debug', 'Test', 'Dev', 'Plugin' },
	}

	-- Check each category for module matches
	for category, keywords in pairs(categories) do
		for _, keyword in ipairs(keywords) do
			if moduleName:lower():find(keyword:lower()) then return category end
		end
	end

	-- Default category for unmatched modules
	return 'Other Modules'
end

-- Function to create hierarchical module tree (like AuctionFrame categories)
function CreateModuleCategories()
	if not LogWindow then return end

	-- Clear existing data
	LogWindow.Categories = {}
	ScrollListing = {}

	-- Organize modules into categories
	for moduleName, _ in pairs(logger.DB.modules) do
		local category = CategorizeModule(moduleName)

		if not LogWindow.Categories[category] then LogWindow.Categories[category] = {
			name = category,
			modules = {},
			expanded = false,
			button = nil,
		} end

		table.insert(LogWindow.Categories[category].modules, moduleName)
		table.insert(ScrollListing, { text = moduleName, value = moduleName, category = category })
	end

	-- Sort categories and modules within categories
	local sortedCategories = {}
	for categoryName, _ in pairs(LogWindow.Categories) do
		table.insert(sortedCategories, categoryName)
	end
	table.sort(sortedCategories)

	for _, categoryName in pairs(sortedCategories) do
		table.sort(LogWindow.Categories[categoryName].modules)
	end

	-- Create the visual tree structure
	CreateCategoryTree(sortedCategories)
end

-- Function to create the visual category tree (styled like AuctionFrame's category list)
function CreateCategoryTree(sortedCategories)
	if not LogWindow or not LogWindow.ModuleTree then return end

	-- Clear existing buttons
	for _, button in pairs(LogWindow.categoryButtons) do
		button:Hide()
		button:SetParent(nil)
	end
	for _, button in pairs(LogWindow.moduleButtons) do
		button:Hide()
		button:SetParent(nil)
	end
	LogWindow.categoryButtons = {}
	LogWindow.moduleButtons = {}

	local yOffset = 0
	local buttonHeight = 20
	local categoryHeight = 18
	local indentWidth = 15

	for _, categoryName in ipairs(sortedCategories) do
		local categoryData = LogWindow.Categories[categoryName]

		-- Create category button (styled like AuctionFrame's expandable categories)
		local categoryButton = CreateFrame('Button', nil, LogWindow.ModuleTree)
		categoryButton:SetSize(140, categoryHeight)
		categoryButton:SetPoint('TOPLEFT', LogWindow.ModuleTree, 'TOPLEFT', 0, yOffset)

		-- Category background (darker, like AuctionFrame headers)
		categoryButton.bg = categoryButton:CreateTexture(nil, 'BACKGROUND')
		categoryButton.bg:SetAllPoints()
		categoryButton.bg:SetColorTexture(0.1, 0.1, 0.1, 0.8)

		-- Expand/collapse indicator (using proper expand/collapse textures)
		categoryButton.indicator = categoryButton:CreateTexture(nil, 'OVERLAY')
		categoryButton.indicator:SetSize(16, 16)
		categoryButton.indicator:SetPoint('LEFT', categoryButton, 'LEFT', 3, 0)
		if categoryData.expanded then
			categoryButton.indicator:SetAtlas('ui-trees-collapsed')
		else
			categoryButton.indicator:SetAtlas('ui-trees-expanded')
		end

		-- Category text
		categoryButton.text = categoryButton:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall')
		categoryButton.text:SetPoint('LEFT', categoryButton.indicator, 'RIGHT', 5, 0)
		categoryButton.text:SetText(categoryName .. ' (' .. #categoryData.modules .. ')')
		categoryButton.text:SetTextColor(1, 0.82, 0) -- Gold like AuctionFrame headers

		-- Category button functionality
		categoryButton:SetScript('OnClick', function(self)
			categoryData.expanded = not categoryData.expanded
			if categoryData.expanded then
				self.indicator:SetAtlas('ui-trees-collapsed')
			else
				self.indicator:SetAtlas('ui-trees-expanded')
			end
			CreateCategoryTree(sortedCategories) -- Rebuild tree
		end)

		-- Hover effects like AuctionFrame
		categoryButton:SetScript('OnEnter', function(self)
			self.bg:SetColorTexture(0.2, 0.2, 0.2, 0.8)
		end)
		categoryButton:SetScript('OnLeave', function(self)
			self.bg:SetColorTexture(0.1, 0.1, 0.1, 0.8)
		end)

		categoryData.button = categoryButton
		table.insert(LogWindow.categoryButtons, categoryButton)
		yOffset = yOffset - (categoryHeight + 1)

		-- Create module buttons if category is expanded
		if categoryData.expanded then
			for _, moduleName in ipairs(categoryData.modules) do
				local moduleButton = CreateFrame('Button', nil, LogWindow.ModuleTree)
				moduleButton:SetSize(132, 21)
				moduleButton:SetPoint('TOPLEFT', LogWindow.ModuleTree, 'TOPLEFT', indentWidth, yOffset)

				-- Create textures to match AuctionHouse nav button style
				-- Normal texture (using secondary style for module buttons)
				moduleButton.NormalTexture = moduleButton:CreateTexture(nil, 'BACKGROUND')
				moduleButton.NormalTexture:SetAtlas('auctionhouse-nav-button-secondary', false)
				moduleButton.NormalTexture:SetAllPoints(moduleButton)

				-- Highlight texture
				moduleButton.HighlightTexture = moduleButton:CreateTexture(nil, 'BORDER')
				moduleButton.HighlightTexture:SetAtlas('auctionhouse-nav-button-highlight')
				moduleButton.HighlightTexture:SetAllPoints(moduleButton)
				moduleButton.HighlightTexture:Hide()

				-- Selected texture (using primary button for selected state)
				moduleButton.SelectedTexture = moduleButton:CreateTexture(nil, 'ARTWORK')
				moduleButton.SelectedTexture:SetAtlas('auctionhouse-nav-button')
				moduleButton.SelectedTexture:SetAllPoints(moduleButton)
				moduleButton.SelectedTexture:Hide()

				-- Button text
				moduleButton.Text = moduleButton:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall')
				moduleButton.Text:SetText(moduleName)
				moduleButton.Text:SetJustifyH('LEFT')
				moduleButton.Text:SetPoint('LEFT', moduleButton, 'LEFT', 4, 0)
				moduleButton.Text:SetPoint('RIGHT', moduleButton, 'RIGHT', -4, 0)
				moduleButton.Text:SetHeight(8)

				-- Hover effects
				moduleButton:SetScript('OnEnter', function(self)
					self.HighlightTexture:Show()
				end)
				moduleButton:SetScript('OnLeave', function(self)
					self.HighlightTexture:Hide()
				end)

				-- Module selection functionality
				moduleButton:SetScript('OnClick', function(self)
					-- Update button states (clear all selected states)
					for _, btn in pairs(LogWindow.moduleButtons) do
						btn.SelectedTexture:Hide()
						btn.Text:SetFontObject('GameFontNormalSmall')
					end
					-- Set this button as selected
					self.SelectedTexture:Show()
					self.Text:SetFontObject('GameFontHighlightSmall')

					ActiveModule = self.Text:GetText()
					UpdateLogDisplay()
				end)

				table.insert(LogWindow.moduleButtons, moduleButton)
				yOffset = yOffset - (buttonHeight + 1)
			end
		end
	end

	-- Update tree height
	local totalHeight = math.abs(yOffset) + 20
	LogWindow.ModuleTree:SetHeight(math.max(totalHeight, LogWindow.ModuleScrollFrame:GetHeight()))
end

local function CreateLogWindow()
	if LogWindow then return end

	-- Create main frame using PortraitFrameTemplate for proper skinning (AH window size: 800x538)
	LogWindow = CreateFrame('Frame', 'SpartanUI_LogWindow', UIParent, 'PortraitFrameTemplate')
	LogWindow:SetSize(800, 538)
	LogWindow:SetPoint('CENTER', UIParent, 'CENTER', 0, 0)
	LogWindow:SetFrameStrata('HIGH')
	LogWindow:Hide()

	-- Make the window movable
	LogWindow:SetMovable(true)
	LogWindow:EnableMouse(true)
	LogWindow:RegisterForDrag('LeftButton')
	LogWindow:SetScript('OnDragStart', LogWindow.StartMoving)
	LogWindow:SetScript('OnDragStop', function(self)
		self:StopMovingOrSizing()
	end)

	-- Set the portrait (with safety checks)
	if LogWindow.portrait then
		if LogWindow.portrait.SetTexture then LogWindow.portrait:SetTexture('Interface\\AddOns\\SpartanUI\\images\\LogoSpartanUI') end
	end

	-- Set title
	LogWindow:SetTitle('SpartanUI Logging')

	-- Create control frame positioned like AuctionHouse SearchBar (y=-29)
	LogWindow.ControlFrame = CreateFrame('Frame', nil, LogWindow)
	LogWindow.ControlFrame:SetPoint('TOPLEFT', LogWindow, 'TOPLEFT', 2, -33)
	LogWindow.ControlFrame:SetPoint('TOPRIGHT', LogWindow, 'TOPRIGHT', -2, -33)
	LogWindow.ControlFrame:SetHeight(28) -- Reduced height to match AH

	LogWindow.HeaderAnchor = CreateFrame('Frame', nil, LogWindow)
	LogWindow.HeaderAnchor:SetPoint('TOPLEFT', LogWindow.ControlFrame, 'TOPLEFT', 53, 0)
	LogWindow.HeaderAnchor:SetPoint('TOPRIGHT', LogWindow.ControlFrame, 'TOPRIGHT', -16, 0)
	LogWindow.HeaderAnchor:SetHeight(28) -- Reduced height to match AH

	-- All controls on same horizontal line, left to right: checkbox, search, logging level, gear
	-- Search all modules checkbox (leftmost)
	LogWindow.SearchAllModules = CreateFrame('CheckButton', 'SUI_SearchAllModules', LogWindow.HeaderAnchor, 'UICheckButtonTemplate')
	LogWindow.SearchAllModules:SetSize(18, 18)
	LogWindow.SearchAllModules:SetPoint('LEFT', LogWindow.HeaderAnchor, 'LEFT', 0, 0)
	LogWindow.SearchAllModules:SetScript('OnClick', function(self)
		SearchAllModules = self:GetChecked()
		UpdateLogDisplay()
	end)

	LogWindow.SearchAllModulesLabel = LogWindow.HeaderAnchor:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall')
	LogWindow.SearchAllModulesLabel:SetText('Search All Modules')
	LogWindow.SearchAllModulesLabel:SetPoint('LEFT', LogWindow.SearchAllModules, 'RIGHT', 2, 0)
	LogWindow.SearchAllModulesLabel:SetTextColor(1, 1, 1) -- White text

	-- Search box positioned after checkbox
	LogWindow.SearchBox = CreateFrame('EditBox', 'SUI_LogSearchBox', LogWindow.HeaderAnchor, 'SearchBoxTemplate')
	LogWindow.SearchBox:SetSize(241, 22)
	LogWindow.SearchBox:SetPoint('LEFT', LogWindow.SearchAllModulesLabel, 'RIGHT', 10, 0)
	LogWindow.SearchBox:SetAutoFocus(false)
	LogWindow.SearchBox:SetScript('OnTextChanged', function(self)
		CurrentSearchTerm = self:GetText()
		UpdateLogDisplay()
	end)
	LogWindow.SearchBox:SetScript('OnEscapePressed', function(self)
		self:SetText('')
		self:ClearFocus()
		CurrentSearchTerm = ''
		UpdateLogDisplay()
	end)

	-- Settings button (workshop icon, positioned after logging level dropdown)
	LogWindow.OpenSettings = CreateFrame('Button', nil, LogWindow.HeaderAnchor)
	LogWindow.OpenSettings:SetSize(24, 24)
	LogWindow.OpenSettings:SetPoint('RIGHT', LogWindow.HeaderAnchor, 'RIGHT', 0, 0)

	-- Set up texture states
	LogWindow.OpenSettings:SetNormalTexture('Interface\\AddOns\\SpartanUI\\images\\empty') -- Placeholder, will use atlas
	LogWindow.OpenSettings:SetHighlightTexture('Interface\\AddOns\\SpartanUI\\images\\empty') -- Placeholder, will use atlas
	LogWindow.OpenSettings:SetPushedTexture('Interface\\AddOns\\SpartanUI\\images\\empty') -- Placeholder, will use atlas

	-- Create texture layers using atlas
	LogWindow.OpenSettings.NormalTexture = LogWindow.OpenSettings:CreateTexture(nil, 'ARTWORK')
	LogWindow.OpenSettings.NormalTexture:SetAtlas('Warfronts-BaseMapIcons-Empty-Workshop')
	LogWindow.OpenSettings.NormalTexture:SetAllPoints()

	LogWindow.OpenSettings.HighlightTexture = LogWindow.OpenSettings:CreateTexture(nil, 'HIGHLIGHT')
	LogWindow.OpenSettings.HighlightTexture:SetAtlas('Warfronts-BaseMapIcons-Alliance-Workshop')
	LogWindow.OpenSettings.HighlightTexture:SetAllPoints()
	LogWindow.OpenSettings.HighlightTexture:SetAlpha(0)

	LogWindow.OpenSettings.PushedTexture = LogWindow.OpenSettings:CreateTexture(nil, 'ARTWORK')
	LogWindow.OpenSettings.PushedTexture:SetAtlas('Warfronts-BaseMapIcons-Horde-Workshop')
	LogWindow.OpenSettings.PushedTexture:SetAllPoints()
	LogWindow.OpenSettings.PushedTexture:SetAlpha(0)

	-- Set up hover and click effects
	LogWindow.OpenSettings:SetScript('OnEnter', function(self)
		self.HighlightTexture:SetAlpha(1)
	end)
	LogWindow.OpenSettings:SetScript('OnLeave', function(self)
		self.HighlightTexture:SetAlpha(0)
	end)
	LogWindow.OpenSettings:SetScript('OnMouseDown', function(self)
		self.PushedTexture:SetAlpha(1)
		self.NormalTexture:SetAlpha(0)
	end)
	LogWindow.OpenSettings:SetScript('OnMouseUp', function(self)
		self.PushedTexture:SetAlpha(0)
		self.NormalTexture:SetAlpha(1)
	end)
	LogWindow.OpenSettings:SetScript('OnClick', function()
		SUI.Options:ToggleOptions({ 'Help', 'Logging' })
	end)

	-- Logging Level dropdown positioned after search box
	LogWindow.LoggingLevelButton = CreateFrame('DropdownButton', 'SUI_LoggingLevelButton', LogWindow.HeaderAnchor, 'WowStyle1FilterDropdownTemplate')
	LogWindow.LoggingLevelButton:SetPoint('RIGHT', LogWindow.OpenSettings, 'LEFT', -10, 0)
	LogWindow.LoggingLevelButton:SetSize(120, 22)
	LogWindow.LoggingLevelButton:SetText('Logging Level')
	-- Set initial dropdown text based on current global level
	local _, globalLevelData = GetLogLevelByPriority(GlobalLogLevel)
	if globalLevelData then LogWindow.LoggingLevelButton:SetText('Logging Level') end

	-- Create main content area positioned like AuctionHouse panels (-4px from SearchBar bottom)
	LogWindow.MainContent = CreateFrame('Frame', nil, LogWindow)
	LogWindow.MainContent:SetPoint('TOPLEFT', LogWindow.ControlFrame, 'BOTTOMLEFT', -4, -4)
	LogWindow.MainContent:SetPoint('BOTTOMRIGHT', LogWindow, 'BOTTOMRIGHT', -20, 12)

	-- Left panel for module list (styled like AuctionFrame's category list)
	LogWindow.LeftPanel = CreateFrame('Frame', nil, LogWindow.MainContent)
	LogWindow.LeftPanel:SetPoint('TOPLEFT', LogWindow.MainContent, 'TOPLEFT', 10, 0)
	LogWindow.LeftPanel:SetPoint('BOTTOMLEFT', LogWindow.MainContent, 'BOTTOMLEFT', 10, 20)
	LogWindow.LeftPanel:SetWidth(160)

	-- Add AuctionHouse categories background
	LogWindow.LeftPanel.Background = LogWindow.LeftPanel:CreateTexture(nil, 'BACKGROUND')
	LogWindow.LeftPanel.Background:SetAtlas('auctionhouse-background-summarylist', true)
	-- LogWindow.LeftPanel.Background:SetPoint('TOPLEFT', LogWindow.LeftPanel, 'TOPLEFT', 3, -3)
	LogWindow.LeftPanel.Background:SetAllPoints(LogWindow.LeftPanel)

	-- Add nine slice border for left panel
	LogWindow.LeftPanel.NineSlice = CreateFrame('Frame', nil, LogWindow.LeftPanel, 'NineSlicePanelTemplate')
	LogWindow.LeftPanel.NineSlice:SetAllPoints()

	-- Right panel for log text (main display area like AuctionFrame's item list)
	LogWindow.RightPanel = CreateFrame('Frame', nil, LogWindow.MainContent)
	LogWindow.RightPanel:SetPoint('TOPLEFT', LogWindow.LeftPanel, 'TOPRIGHT', 20, 0)
	LogWindow.RightPanel:SetPoint('BOTTOMRIGHT', LogWindow.MainContent, 'BOTTOMRIGHT', -10, 20)

	-- Add AuctionHouse index background
	LogWindow.RightPanel.Background = LogWindow.RightPanel:CreateTexture(nil, 'BACKGROUND')
	LogWindow.RightPanel.Background:SetAtlas('auctionhouse-background-index', true)
	LogWindow.RightPanel.Background:SetAllPoints(LogWindow.RightPanel)
	-- LogWindow.RightPanel.Background:SetPoint('TOPLEFT', LogWindow.RightPanel, 'TOPLEFT', 3, -3)

	-- Add nine slice border for right panel
	LogWindow.RightPanel.NineSlice = CreateFrame('Frame', nil, LogWindow.RightPanel, 'NineSlicePanelTemplate')
	LogWindow.RightPanel.NineSlice:SetAllPoints()

	-- Action buttons positioned in bottom right like AH Cancel Auction button
	LogWindow.ClearButton = CreateFrame('Button', nil, LogWindow, 'UIPanelButtonTemplate')
	LogWindow.ClearButton:SetSize(70, 22)
	LogWindow.ClearButton:SetPoint('BOTTOMRIGHT', LogWindow, 'BOTTOMRIGHT', -3, 4)
	LogWindow.ClearButton:SetText('Clear')
	LogWindow.ClearButton:SetScript('OnClick', function()
		ClearCurrentLogs()
	end)

	LogWindow.ExportButton = CreateFrame('Button', nil, LogWindow, 'UIPanelButtonTemplate')
	LogWindow.ExportButton:SetSize(70, 22)
	LogWindow.ExportButton:SetPoint('RIGHT', LogWindow.ClearButton, 'LEFT', -5, 0)
	LogWindow.ExportButton:SetText('Export')
	LogWindow.ExportButton:SetScript('OnClick', function()
		ExportCurrentLogs()
	end)

	-- Create scroll frame for module tree in left panel with MinimalScrollBar
	LogWindow.ModuleScrollFrame = CreateFrame('ScrollFrame', nil, LogWindow.LeftPanel)
	LogWindow.ModuleScrollFrame:SetPoint('TOPLEFT', LogWindow.LeftPanel, 'TOPLEFT', 2, -7)
	LogWindow.ModuleScrollFrame:SetPoint('BOTTOMRIGHT', LogWindow.LeftPanel, 'BOTTOMRIGHT', -8, 2)

	-- Create minimal scrollbar for left panel
	LogWindow.ModuleScrollFrame.ScrollBar = CreateFrame('EventFrame', nil, LogWindow.ModuleScrollFrame, 'MinimalScrollBar')
	LogWindow.ModuleScrollFrame.ScrollBar:SetPoint('TOPLEFT', LogWindow.ModuleScrollFrame, 'TOPRIGHT', 2, 0)
	LogWindow.ModuleScrollFrame.ScrollBar:SetPoint('BOTTOMLEFT', LogWindow.ModuleScrollFrame, 'BOTTOMRIGHT', 2, 0)
	ScrollUtil.InitScrollFrameWithScrollBar(LogWindow.ModuleScrollFrame, LogWindow.ModuleScrollFrame.ScrollBar)

	LogWindow.ModuleTree = CreateFrame('Frame', nil, LogWindow.ModuleScrollFrame)
	LogWindow.ModuleScrollFrame:SetScrollChild(LogWindow.ModuleTree)
	LogWindow.ModuleTree:SetSize(140, 1)

	-- Create log text display in right panel with MinimalScrollBar
	LogWindow.TextPanel = CreateFrame('ScrollFrame', nil, LogWindow.RightPanel)
	LogWindow.TextPanel:SetPoint('TOPLEFT', LogWindow.RightPanel, 'TOPLEFT', 6, -6)
	LogWindow.TextPanel:SetPoint('BOTTOMRIGHT', LogWindow.RightPanel, 'BOTTOMRIGHT', 0, 2)

	-- Create minimal scrollbar for right panel
	LogWindow.TextPanel.ScrollBar = CreateFrame('EventFrame', nil, LogWindow.TextPanel, 'MinimalScrollBar')
	LogWindow.TextPanel.ScrollBar:SetPoint('TOPLEFT', LogWindow.TextPanel, 'TOPRIGHT', 0, 0)
	LogWindow.TextPanel.ScrollBar:SetPoint('BOTTOMLEFT', LogWindow.TextPanel, 'BOTTOMRIGHT', 0, 0)
	ScrollUtil.InitScrollFrameWithScrollBar(LogWindow.TextPanel, LogWindow.TextPanel.ScrollBar)

	-- Create the text display area
	LogWindow.EditBox = CreateFrame('EditBox', nil, LogWindow.TextPanel)
	LogWindow.EditBox:SetMultiLine(true)
	LogWindow.EditBox:SetFontObject('GameFontHighlight') -- Increased font size by 2 from GameFontHighlightSmall
	LogWindow.EditBox:SetText('No logs active - select a module from the left or enable "Search All Modules"')
	LogWindow.EditBox:SetWidth(LogWindow.TextPanel:GetWidth() - 20)
	LogWindow.EditBox:SetScript('OnTextChanged', function(self)
		ScrollingEdit_OnTextChanged(self, self:GetParent())
	end)
	LogWindow.EditBox:SetScript('OnCursorChanged', function(self, x, y, w, h)
		ScrollingEdit_OnCursorChanged(self, x, y - 10, w, h)
	end)
	LogWindow.EditBox:SetAutoFocus(false)
	LogWindow.EditBox:EnableMouse(true) -- Allow selection for copying
	LogWindow.EditBox:SetTextColor(1, 1, 1) -- White text for better readability
	LogWindow.TextPanel:SetScrollChild(LogWindow.EditBox)

	-- Auto-scroll checkbox centered under right panel
	LogWindow.AutoScroll = CreateFrame('CheckButton', 'SUI_AutoScroll', LogWindow, 'UICheckButtonTemplate')
	LogWindow.AutoScroll:SetSize(18, 18)
	LogWindow.AutoScroll:SetPoint('CENTER', LogWindow.RightPanel, 'BOTTOM', 0, -15)
	LogWindow.AutoScroll:SetChecked(AutoScrollEnabled)

	LogWindow.AutoScrollLabel = LogWindow:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall')
	LogWindow.AutoScrollLabel:SetText('Auto-scroll')
	LogWindow.AutoScrollLabel:SetPoint('LEFT', LogWindow.AutoScroll, 'RIGHT', 2, 0)
	LogWindow.AutoScrollLabel:SetTextColor(1, 1, 1) -- White text

	-- Initialize data structures
	LogWindow.Categories = {}
	LogWindow.categoryButtons = {}
	LogWindow.moduleButtons = {}

	-- Build module categories (like AuctionFrame's item categories)
	CreateModuleCategories()

	-- Setup dropdown functionality
	SetupLogLevelDropdowns()

	-- Store references for compatibility
	LogWindow.NamespaceListings = LogWindow.ModuleScrollFrame
	LogWindow.OutputSelect = LogWindow.LeftPanel
end

-- Function to highlight search terms in text
local function HighlightSearchTerm(text, searchTerm)
	if not searchTerm or searchTerm == '' then return text end

	-- Case-insensitive search and replace with highlighting
	local highlightColor = '|cffff00ff' -- Bright magenta for search highlights
	local resetColor = '|r'

	-- Escape special characters in search term for pattern matching
	local escapedTerm = searchTerm:gsub('([%^%$%(%)%%%.%[%]%*%+%-%?])', '%%%1')

	-- For case-insensitive highlighting, we need to find and replace manually
	-- since Lua patterns don't support case-insensitive flags
	local result = text
	local searchLower = escapedTerm:lower()
	local pos = 1

	while pos <= #result do
		-- Find the next occurrence (case-insensitive)
		local textLower = result:lower()
		local startPos, endPos = textLower:find(searchLower, pos, true)

		if not startPos then break end

		-- Extract the actual text with original case
		local actualMatch = result:sub(startPos, endPos)
		local highlightedMatch = highlightColor .. actualMatch .. resetColor

		-- Replace this occurrence
		result = result:sub(1, startPos - 1) .. highlightedMatch .. result:sub(endPos + 1)

		-- Move past this replacement
		pos = startPos + #highlightedMatch
	end

	return result
end

-- Function to check if a log entry matches the search criteria
local function MatchesSearchCriteria(logEntry, searchTerm, logLevel)
	-- Check log level first
	local entryLogLevel = LOG_LEVELS[logEntry.level]
	if not entryLogLevel or entryLogLevel.priority < logLevel then return false end

	-- Check search term
	if searchTerm and searchTerm ~= '' then return logEntry.message:lower():find(searchTerm:lower(), 1, true) ~= nil end

	return true
end

-- Function to update the log display based on current module and filter settings
function UpdateLogDisplay()
	if not LogWindow or not LogWindow.EditBox then return end

	local logText = ''
	local totalEntries = 0
	local filteredCount = 0
	local searchedCount = 0

	if SearchAllModules then
		-- Search across all modules
		logText = 'Search Results Across All Modules:\n\n'

		for moduleName, logs in pairs(LogMessages) do
			local moduleLogLevel = ModuleLogLevels[moduleName] or 0
			local effectiveLogLevel = moduleLogLevel > 0 and moduleLogLevel or GlobalLogLevel

			local moduleMatches = {}
			for _, logEntry in ipairs(logs) do
				totalEntries = totalEntries + 1
				if MatchesSearchCriteria(logEntry, CurrentSearchTerm, effectiveLogLevel) then
					table.insert(moduleMatches, logEntry)
					filteredCount = filteredCount + 1
				end
			end

			if #moduleMatches > 0 then
				logText = logText .. '=== ' .. moduleName .. ' (' .. #moduleMatches .. ' entries) ===\n'
				for _, logEntry in ipairs(moduleMatches) do
					local highlightedText = HighlightSearchTerm(logEntry.formattedMessage, CurrentSearchTerm)
					logText = logText .. highlightedText .. '\n'
					searchedCount = searchedCount + 1
				end
				logText = logText .. '\n'
			end
		end

		if searchedCount == 0 then
			logText = logText .. 'No logs match the current search and filter criteria.'
		else
			logText = 'Search Results: ' .. searchedCount .. ' matches across all modules\n' .. 'Total entries: ' .. totalEntries .. ' | Filtered: ' .. filteredCount .. '\n\n' .. logText
		end
	else
		-- Single module display
		if not ActiveModule then
			LogWindow.EditBox:SetText('No module selected - choose a module from the left or enable "Search All Modules"')
			return
		end

		local logs = LogMessages[ActiveModule] or {}
		totalEntries = #logs

		if totalEntries == 0 then
			LogWindow.EditBox:SetText('No logs for module: ' .. ActiveModule)
			return
		end

		-- Get current module log level for filtering
		local moduleLogLevel = ModuleLogLevels[ActiveModule] or 0
		local effectiveLogLevel = moduleLogLevel > 0 and moduleLogLevel or GlobalLogLevel

		local matchingEntries = {}
		for _, logEntry in ipairs(logs) do
			if MatchesSearchCriteria(logEntry, CurrentSearchTerm, effectiveLogLevel) then
				table.insert(matchingEntries, logEntry)
				filteredCount = filteredCount + 1
			end
		end

		-- Build the display text
		local searchInfo = ''
		if CurrentSearchTerm and CurrentSearchTerm ~= '' then searchInfo = ' | Search: "' .. CurrentSearchTerm .. '"' end

		logText = 'Logs for ' .. ActiveModule .. ' (' .. totalEntries .. ' total, ' .. filteredCount .. ' shown' .. searchInfo .. '):\n\n'

		if #matchingEntries > 0 then
			for _, logEntry in ipairs(matchingEntries) do
				local highlightedText = HighlightSearchTerm(logEntry.formattedMessage, CurrentSearchTerm)
				logText = logText .. highlightedText .. '\n'
			end
		else
			logText = logText .. 'No logs match current filter and search criteria.'
		end
	end

	LogWindow.EditBox:SetText(logText)

	-- Auto-scroll to bottom if enabled
	if LogWindow.AutoScroll and LogWindow.AutoScroll:GetChecked() and LogWindow.EditBox then LogWindow.EditBox:SetCursorPosition(string.len(logText)) end

	-- Update logging level button text with color
	if LogWindow.LoggingLevelButton then
		local _, globalLevelData = GetLogLevelByPriority(GlobalLogLevel)
		if globalLevelData then
			local coloredButtonText = 'Log Level: ' .. globalLevelData.color .. globalLevelData.display .. '|r'
			LogWindow.LoggingLevelButton:SetText(coloredButtonText)
		end
	end
end

-- Function to clear logs for the current module or all modules
function ClearCurrentLogs()
	if SearchAllModules then
		-- Clear all logs
		for moduleName in pairs(LogMessages) do
			LogMessages[moduleName] = {}
		end
		print('|cFF00FF00SpartanUI Logging:|r All logs cleared.')
	else
		-- Clear current module logs
		if ActiveModule and LogMessages[ActiveModule] then
			LogMessages[ActiveModule] = {}
			print('|cFF00FF00SpartanUI Logging:|r Logs cleared for module: ' .. ActiveModule)
		else
			print('|cFFFFFF00SpartanUI Logging:|r No active module selected.')
		end
	end

	UpdateLogDisplay()
end

-- Function to export current logs to a copyable format
function ExportCurrentLogs()
	if not LogWindow then return end

	-- Create export frame if it doesn't exist
	if not LogWindow.ExportFrame then
		LogWindow.ExportFrame = CreateFrame('Frame', 'SUI_LogExportFrame', UIParent, 'PortraitFrameTemplate')
		LogWindow.ExportFrame:SetSize(500, 400)
		LogWindow.ExportFrame:SetPoint('CENTER', UIParent, 'CENTER', 0, 0)
		LogWindow.ExportFrame:SetFrameStrata('DIALOG')
		LogWindow.ExportFrame:Hide()

		-- Set the portrait (with safety checks)
		if LogWindow.ExportFrame.portrait then
			if LogWindow.ExportFrame.portrait.SetTexture then LogWindow.ExportFrame.portrait:SetTexture('Interface\\AddOns\\SpartanUI\\images\\LogoSpartanUI') end
		end

		-- Set title
		LogWindow.ExportFrame:SetTitle('Export Logs')

		-- Scroll frame for export text (properly styled)
		LogWindow.ExportFrame.ScrollFrame = CreateFrame('ScrollFrame', nil, LogWindow.ExportFrame, 'UIPanelScrollFrameTemplate')
		LogWindow.ExportFrame.ScrollFrame:SetPoint('TOPLEFT', LogWindow.ExportFrame.TitleBar, 'BOTTOMLEFT', 0, -10)
		LogWindow.ExportFrame.ScrollFrame:SetPoint('BOTTOMRIGHT', LogWindow.ExportFrame, 'BOTTOMRIGHT', -26, 40)

		LogWindow.ExportFrame.EditBox = CreateFrame('EditBox', nil, LogWindow.ExportFrame.ScrollFrame)
		LogWindow.ExportFrame.EditBox:SetMultiLine(true)
		LogWindow.ExportFrame.EditBox:SetFontObject('GameFontHighlightSmall')
		LogWindow.ExportFrame.EditBox:SetWidth(LogWindow.ExportFrame.ScrollFrame:GetWidth() - 20)
		LogWindow.ExportFrame.EditBox:SetAutoFocus(false)
		LogWindow.ExportFrame.EditBox:SetTextColor(1, 1, 1) -- White text
		LogWindow.ExportFrame.EditBox:SetScript('OnTextChanged', function(self)
			ScrollingEdit_OnTextChanged(self, self:GetParent())
		end)
		LogWindow.ExportFrame.EditBox:SetScript('OnCursorChanged', function(self, x, y, w, h)
			ScrollingEdit_OnCursorChanged(self, x, y - 10, w, h)
		end)
		LogWindow.ExportFrame.ScrollFrame:SetScrollChild(LogWindow.ExportFrame.EditBox)

		-- Instructions (styled like Blizzard help text)
		LogWindow.ExportFrame.Instructions = LogWindow.ExportFrame:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall')
		LogWindow.ExportFrame.Instructions:SetText('Select all text (Ctrl+A) and copy (Ctrl+C) to export logs')
		LogWindow.ExportFrame.Instructions:SetPoint('BOTTOM', LogWindow.ExportFrame, 'BOTTOM', 0, 15)
		LogWindow.ExportFrame.Instructions:SetTextColor(1, 0.82, 0) -- Gold color like other instructions
	end

	-- Generate export text
	local exportText = '=== SpartanUI Log Export ===\n'
	exportText = exportText .. 'Generated: ' .. date('%Y-%m-%d %H:%M:%S') .. '\n'
	exportText = exportText .. 'Global Log Level: ' .. (GetLogLevelByPriority(GlobalLogLevel) or 'Unknown') .. '\n\n'

	if SearchAllModules then
		exportText = exportText .. '=== ALL MODULES ===\n\n'
		for moduleName, logs in pairs(LogMessages) do
			if #logs > 0 then
				exportText = exportText .. '--- Module: ' .. moduleName .. ' (' .. #logs .. ' entries) ---\n'

				local moduleLogLevel = ModuleLogLevels[moduleName] or 0
				local effectiveLogLevel = moduleLogLevel > 0 and moduleLogLevel or GlobalLogLevel

				for _, logEntry in ipairs(logs) do
					local entryLogLevel = LOG_LEVELS[logEntry.level]
					if entryLogLevel and entryLogLevel.priority >= effectiveLogLevel then
						-- Remove color codes for export
						local cleanMessage = logEntry.formattedMessage:gsub('|c%x%x%x%x%x%x%x%x', ''):gsub('|r', '')
						exportText = exportText .. cleanMessage .. '\n'
					end
				end
				exportText = exportText .. '\n'
			end
		end
	else
		if ActiveModule and LogMessages[ActiveModule] then
			exportText = exportText .. '=== Module: ' .. ActiveModule .. ' ===\n\n'

			local logs = LogMessages[ActiveModule]
			local moduleLogLevel = ModuleLogLevels[ActiveModule] or 0
			local effectiveLogLevel = moduleLogLevel > 0 and moduleLogLevel or GlobalLogLevel

			for _, logEntry in ipairs(logs) do
				local entryLogLevel = LOG_LEVELS[logEntry.level]
				if entryLogLevel and entryLogLevel.priority >= effectiveLogLevel then
					-- Apply search filtering if active
					if not CurrentSearchTerm or CurrentSearchTerm == '' or logEntry.message:lower():find(CurrentSearchTerm:lower(), 1, true) then
						-- Remove color codes for export
						local cleanMessage = logEntry.formattedMessage:gsub('|c%x%x%x%x%x%x%x%x', ''):gsub('|r', '')
						exportText = exportText .. cleanMessage .. '\n'
					end
				end
			end
		else
			exportText = exportText .. 'No active module selected.\n'
		end
	end

	exportText = exportText .. '\n=== End of Export ==='

	-- Set text and show frame
	LogWindow.ExportFrame.EditBox:SetText(exportText)
	LogWindow.ExportFrame:Show()

	-- Select all text for easy copying
	LogWindow.ExportFrame.EditBox:SetFocus()
	LogWindow.ExportFrame.EditBox:HighlightText()

	print('|cFF00FF00SpartanUI Logging:|r Logs exported. Use Ctrl+A and Ctrl+C to copy.')
end

-- Setup the log level dropdown functionality
function SetupLogLevelDropdowns()
	-- Create ordered list of log levels by priority
	local orderedLevels = {}
	for logLevel, data in pairs(LOG_LEVELS) do
		table.insert(orderedLevels, { level = logLevel, data = data })
	end
	table.sort(orderedLevels, function(a, b)
		return a.data.priority < b.data.priority
	end)

	-- Setup logging level filter button (AH style)
	LogWindow.LoggingLevelButton:SetupMenu(function(dropdown, rootDescription)
		-- Add log levels in priority order with colored text
		for _, levelData in ipairs(orderedLevels) do
			-- Create colored display text
			local coloredText = levelData.data.color .. levelData.data.display .. '|r'
			local button = rootDescription:CreateButton(coloredText, function()
				GlobalLogLevel = levelData.data.priority
				logger.DB.globalLogLevel = GlobalLogLevel
				-- Update button text with colored level name
				local coloredButtonText = 'Level: ' .. levelData.data.color .. levelData.data.display .. '|r'
				LogWindow.LoggingLevelButton:SetText(coloredButtonText)
				UpdateLogDisplay() -- Refresh current view
			end)
			-- Add tooltip
			button:SetTooltip(function(tooltip, elementDescription)
				GameTooltip_SetTitle(tooltip, levelData.data.display .. ' Level')
				GameTooltip_AddNormalLine(tooltip, 'Shows ' .. levelData.data.display:lower() .. ' messages and higher priority')
			end)
			-- Check current selection
			if GlobalLogLevel == levelData.data.priority then button:SetRadio(true) end
		end
	end)
end

---Enhanced logging function with log levels
---@param debugText string The message to log
---@param module string The module name
---@param level? string Log level (debug, info, warning, error, critical) - defaults to 'info'
function SUI.Log(debugText, module, level)
	level = level or 'info'

	-- Initialize module if it doesn't exist
	if not LogMessages[module] then
		LogMessages[module] = {}

		-- Add new module to category system if log window exists
		if LogWindow and LogWindow.Categories then
			-- Determine category and add module
			local category = CategorizeModule(module)

			if not LogWindow.Categories[category] then LogWindow.Categories[category] = {
				name = category,
				modules = {},
				expanded = false,
				button = nil,
			} end

			-- Add module to category if not already present
			local moduleExists = false
			for _, existingModule in ipairs(LogWindow.Categories[category].modules) do
				if existingModule == module then
					moduleExists = true
					break
				end
			end

			if not moduleExists then
				table.insert(LogWindow.Categories[category].modules, module)
				table.sort(LogWindow.Categories[category].modules)

				-- Rebuild the category tree to include new module
				local sortedCategories = {}
				for categoryName, _ in pairs(LogWindow.Categories) do
					table.insert(sortedCategories, categoryName)
				end
				table.sort(sortedCategories)
				CreateCategoryTree(sortedCategories)
			end
		end

		logger.DB.modules[module] = true -- Default to enabled for logging approach
		if logger.options then logger.options.args[module] = {
			name = module,
			type = 'toggle',
			order = (#logger.options.args + 1),
		} end
	end

	-- Validate log level
	local logLevel = LOG_LEVELS[level]
	if not logLevel then
		level = 'info'
		logLevel = LOG_LEVELS[level]
	end

	-- LOGGING APPROACH: Always capture all messages, filter during display
	-- This allows dynamic log level changes without losing historical data

	-- Create log entry with timestamp and level
	local timestamp = date('%H:%M:%S')
	local coloredLevel = logLevel.color .. '[' .. logLevel.display:upper() .. ']|r'
	local formattedMessage = timestamp .. ' ' .. coloredLevel .. ' ' .. tostring(debugText)

	-- Store the log entry
	local logEntry = {
		timestamp = GetTime(),
		level = level,
		message = tostring(debugText),
		formattedMessage = formattedMessage,
	}

	table.insert(LogMessages[module], logEntry)

	-- Maintain maximum log history
	local maxHistory = logger.DB.maxLogHistory or 1000
	if #LogMessages[module] > maxHistory then table.remove(LogMessages[module], 1) end

	-- Initialize log window if needed
	if not LogWindow then CreateLogWindow() end

	-- Update display if this module is currently active
	if ActiveModule and ActiveModule == module then UpdateLogDisplay() end
end

-- Compatibility function to maintain existing SUI.Debug calls
---@param debugText string The message to log
---@param module string The module name
---@param level? string Log level (debug, info, warning, error, critical) - defaults to 'info'
function SUI.Debug(debugText, module, level)
	-- Redirect to the new logging function
	SUI.Log(debugText, module, level)
end

local function AddOptions()
	---@type AceConfig.OptionsTable
	local options = {
		name = 'Logging',
		type = 'group',
		get = function(info)
			return logger.DB.modules[info[#info]]
		end,
		set = function(info, val)
			logger.DB.modules[info[#info]] = val
		end,
		args = {
			Description = {
				name = 'SpartanUI uses a comprehensive logging system that captures all messages and filters by log level.\nModules can be individually disabled to stop collection entirely.',
				type = 'description',
				order = 0,
			},
			GlobalLogLevel = {
				name = 'Global Log Level',
				desc = 'Minimum log level to display globally. Individual modules can override this.',
				type = 'select',
				values = function()
					local values = {}
					-- Create ordered list to ensure proper display order
					local orderedLevels = {}
					for level, data in pairs(LOG_LEVELS) do
						table.insert(orderedLevels, { level = level, data = data })
					end
					table.sort(orderedLevels, function(a, b)
						return a.data.priority < b.data.priority
					end)

					for _, levelData in ipairs(orderedLevels) do
						values[levelData.data.priority] = levelData.data.display
					end
					return values
				end,
				sorting = function()
					-- Return sorted order for dropdown
					local sorted = {}
					local orderedLevels = {}
					for level, data in pairs(LOG_LEVELS) do
						table.insert(orderedLevels, { level = level, data = data })
					end
					table.sort(orderedLevels, function(a, b)
						return a.data.priority < b.data.priority
					end)

					for _, levelData in ipairs(orderedLevels) do
						table.insert(sorted, levelData.data.priority)
					end
					return sorted
				end,
				get = function(info)
					return logger.DB.globalLogLevel
				end,
				set = function(info, val)
					logger.DB.globalLogLevel = val
					GlobalLogLevel = val
					if LogWindow then UpdateLogDisplay() end
				end,
				order = 1,
			},
			CaptureWarningsErrors = {
				name = 'Always Capture Warnings/Errors',
				desc = 'Always capture warning, error, and critical messages regardless of log level settings.',
				type = 'toggle',
				get = function(info)
					return logger.DB.captureWarningsErrors
				end,
				set = function(info, val)
					logger.DB.captureWarningsErrors = val
				end,
				order = 2,
			},
			MaxLogHistory = {
				name = 'Maximum Log History',
				desc = 'Maximum number of log entries to keep per module.',
				type = 'range',
				min = 100,
				max = 5000,
				step = 100,
				get = function(info)
					return logger.DB.maxLogHistory
				end,
				set = function(info, val)
					logger.DB.maxLogHistory = val
				end,
				order = 3,
			},
			ModuleHeader = {
				name = 'Module Logging Control',
				type = 'header',
				order = 10,
			},
			EnableAll = {
				name = 'Enable All Modules',
				desc = 'Enable or disable logging for all modules at once.',
				type = 'toggle',
				order = 11,
				get = function(info)
					-- Check if all modules are enabled
					for _, enabled in pairs(logger.DB.modules) do
						if not enabled then return false end
					end
					return true
				end,
				set = function(info, val)
					for k, _ in pairs(logger.DB.modules) do
						logger.DB.modules[k] = val
					end
				end,
			},
		},
	}

	for k, _ in pairs(logger.DB.modules) do
		options.args[k] = {
			name = k,
			desc = 'Enable logging for the ' .. k .. ' module.',
			type = 'toggle',
			order = (#options.args + 1),
		}
	end
	logger.options = options
	SUI.Options:AddOptions(options, 'Logging', 'Help')
end

function logger:OnInitialize()
	local defaults = {
		globalLogLevel = 2, -- Default to 'info' and above
		captureWarningsErrors = true, -- Always capture warnings and errors
		maxLogHistory = 1000, -- Maximum log entries per module
		window = {
			width = 800,
			height = 538,
			point = 'CENTER',
			relativeTo = 'UIParent',
			relativePoint = 'CENTER',
			x = 0,
			y = 0,
		},
		modules = {
			['*'] = true, -- Default to enabled for logging approach
			Core = true,
		},
		moduleLogLevels = {
			['*'] = 0, -- Use global level by default
		},
	}
	logger.Database = SUI.SpartanUIDB:RegisterNamespace('Logger', { profile = defaults })
	logger.DB = logger.Database.profile

	-- Initialize log structures
	for k, _ in pairs(logger.DB.modules) do
		LogMessages[k] = {}
	end

	-- Load settings
	GlobalLogLevel = logger.DB.globalLogLevel or 2
	ModuleLogLevels = logger.DB.moduleLogLevels or {}

	if SUI:IsModuleEnabled('Chatbox') then logger:RegisterEvent('ADDON_LOADED') end
end

function logger:OnEnable()
	CreateLogWindow()

	local function ToggleLogWindow(comp)
		if not LogWindow then CreateLogWindow() end
		if LogWindow:IsVisible() then
			LogWindow:Hide()
		else
			LogWindow:Show()
		end
	end

	SUI:AddChatCommand('debug', ToggleLogWindow, 'Toggles the SpartanUI Logging window display')
	SUI:AddChatCommand('logs', ToggleLogWindow, 'Toggles the SpartanUI Logging window display')
	AddOptions()
end

local function RefreshData(self)
	local function OnMouseDown(line, button)
		local text = line.Text:GetText()
		if button == 'RightButton' then
			SUI.Chat:SetEditBoxMessage(text)
		elseif button == 'MiddleButton' then
			local rawData = line:GetParent():GetAttributeData().rawValue
			if rawData.IsObjectType and rawData:IsObjectType('Texture') then
				-- _G.TEX = rawData
				SUI:Print('_G.TEX set to: ', text)
			else
				-- _G.FRAME = rawData
				SUI:Print('_G.FRAME set to: ', text)
			end
		else
			TableAttributeDisplayValueButton_OnMouseDown(line)
		end
	end

	local scrollFrame = self.LinesScrollFrame or TableAttributeDisplay.LinesScrollFrame
	if not scrollFrame then return end
	for _, child in next, { scrollFrame.LinesContainer:GetChildren() } do
		if child.ValueButton and child.ValueButton:GetScript('OnMouseDown') ~= OnMouseDown then child.ValueButton:SetScript('OnMouseDown', OnMouseDown) end
	end
end

function logger:ADDON_LOADED(_, addon)
	if addon == 'Blizzard_DebugTools' then
		hooksecurefunc(TableInspectorMixin, 'RefreshAllData', RefreshData)
		hooksecurefunc(TableAttributeDisplay.dataProviders[2], 'RefreshData', RefreshData)
		logger:UnregisterEvent('ADDON_LOADED')
	end
end
