---@class AddonPrivate
local Private = select(2, ...)

local expandedAchievements = {}

------------------------------------------------------------
-- Progress Notifier
------------------------------------------------------------
local function NotifyAchievementProgress()
    local totalCriteria, completedCriteria = 0, 0

    for _, achievement in ipairs(DrustWaypoints) do
        for _, criterion in ipairs(achievement.criteria or {}) do
            local criteriaIndex = criterion.criteriaIndex or 0
            local success, _, _, isComplete = pcall(GetAchievementCriteriaInfo, achievement.achievementID, criteriaIndex)

            if success then
                totalCriteria = totalCriteria + 1
                if isComplete then
                    completedCriteria = completedCriteria + 1
                end
            end
        end
    end

    -- Print progress summary to chat
    print(string.format("Meta-Track: Farewell to Arms Progress: %.2f%% (%d/%d)",
        (completedCriteria / math.max(totalCriteria, 1)) * 100, completedCriteria, totalCriteria))
end

------------------------------------------------------------
-- Helper Functions
------------------------------------------------------------
local function AddTooltip(frame, lines)
    frame:SetScript("OnEnter", function()
        GameTooltip:SetOwner(frame, "ANCHOR_RIGHT")

        GameTooltip:ClearLines() -- Clear existing content
        local maxWidth = 0 -- Track the maximum width of the tooltip
        
        for _, line in ipairs(lines) do
            if type(line) == "table" then
                -- Handle special entries like the guide
                GameTooltip:AddLine(line.label, 1, 0.84, 0, false) -- Golden label
                GameTooltip:AddLine(line.text, 1, 1, 1, true)     -- Wrapping-enabled text
                
                -- Track maximum width for label and text
                local labelWidth = GameTooltipTextLeft1:GetStringWidth() or 0
                local textWidth = GameTooltipTextLeft2:GetStringWidth() or 0
                maxWidth = math.max(maxWidth, labelWidth, textWidth)
            elseif line then
                -- Simple string lines
                GameTooltip:AddLine(line, 1, 1, 1, true) -- Wrapping text
                
                -- Track maximum width for the line
                local lineWidth = GameTooltipTextLeft1:GetStringWidth() or 0
                maxWidth = math.max(maxWidth, lineWidth)
            end
        end

        -- Set a minimum width for better appearance
        maxWidth = math.max(maxWidth + 20, 200) -- Add padding and ensure a minimum width

        -- Apply the dynamic width and height scaling
        GameTooltip:SetMinimumWidth(maxWidth)
        GameTooltip:Show()
    end)

    frame:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)
end




local function UpdateProgressSummary()
    if not progressSummary then return end
    local totalCriteria, completedCriteria = 0, 0

    for _, achievement in ipairs(DrustWaypoints) do
        for _, criterion in ipairs(achievement.criteria or {}) do
            local criteriaIndex = criterion.criteriaIndex or 0
            local success, _, _, isComplete = pcall(GetAchievementCriteriaInfo, achievement.achievementID, criteriaIndex)

            if success then
                totalCriteria = totalCriteria + 1
                if isComplete then
                    completedCriteria = completedCriteria + 1
                end
            end
        end
    end

    progressSummary:SetText(string.format("Progress: %.2f%% (%d/%d)",
        (completedCriteria / math.max(totalCriteria, 1)) * 100, completedCriteria, totalCriteria))
end

-- Table to track active pins
local activePins = {}

-- Clear existing pins
local function ClearCustomPins()
    for _, pin in ipairs(activePins) do
        pin:Hide()
        pin:SetParent(nil)
    end
    wipe(activePins)
end

-- Normalize coordinates to be between 0 and 1
local function NormalizeCoordinates(x, y)
    return x / 100, y / 100
end

-- De-normalize coordinates back to percentages
local function DenormalizeCoordinates(x, y)
    return x * 100, y * 100
end

local function DebugTomTomWaypoint(waypoint)
    if not TomTom then
        print("TomTom addon is not available. Please install or enable it.")
        return
    end

    if not waypoint or not waypoint.mapID or not waypoint.x or not waypoint.y then
        print("Invalid waypoint data provided for debugging.")
        return
    end

    -- Add TomTom waypoint using normalized data
    local normalizedX = waypoint.x / 100
    local normalizedY = waypoint.y / 100

    TomTom:AddWaypoint(waypoint.mapID, normalizedX, normalizedY, {
        title = waypoint.description or "Debug Waypoint",
    })

    print(string.format("Debug TomTom Waypoint: MapID = %d, X = %.2f, Y = %.2f", waypoint.mapID, normalizedX, normalizedY))
end


-- Function to add custom map pins
-- Function to add pins to the map
local function AddCustomPins(achievement, criterion)
    ClearCustomPins()
	
	local waypoints = criterion.waypoints
	
	if not achievement or not waypoints or #waypoints == 0 then
		print("No achievement or waypoints available")
		return
	end


    if not waypoints or #waypoints == 0 then
        print("No waypoints available for this criteria.")
        return
    end

    -- Pre-defined MapID-to-ZoneID and ZoneID-to-MapID mappings
    local mapIDToZoneID = {
        [826] = 8499, -- Example: MapID 826 maps to ZoneID 8499 (Zuldazar)
        -- Add more mappings as needed
    }

    local zoneIDToMapID = {
        [8499] = 862, -- Example: ZoneID 8499 resolves back to Zuldazar's correct MapID
        -- Add more mappings as needed
    }

    -- Helper function to get ZoneID from MapID
    local function GetCorrectedZoneID(mapID)
        return mapIDToZoneID[mapID] or mapID
    end

    -- Helper function to get MapID from ZoneID
    local function GetCorrectedMapID(zoneID)
        return zoneIDToMapID[zoneID] or zoneID
    end

    -- Resolve the target ZoneID and MapID
    --local targetZoneID = GetCorrectedZoneID(waypoints[1].mapID)
	local targetZoneID = GetCorrectedZoneID(waypoints[1].mapID)
    local targetMapID = GetCorrectedMapID(targetZoneID)

    if not targetZoneID or not targetMapID then
        print("Error: Invalid or missing ZoneID or MapID.")
        return
    end

    -- Debugging resolved zone and map
    local zoneInfo = C_Map.GetMapInfo(targetMapID)
    if not zoneInfo then
        print(string.format("Error: MapID %d does not exist or is invalid.", targetMapID))
        return
    end
    --print(string.format("Resolved Zone: %s (ZoneID: %d, MapID: %d)", zoneInfo.name, targetZoneID, targetMapID))

    local function AddPinsToMap()
        for _, waypoint in ipairs(waypoints) do
            local correctedZoneID = GetCorrectedZoneID(waypoint.mapID)
            local correctedMapID = GetCorrectedMapID(correctedZoneID)

            if correctedMapID == targetMapID then
                local normalizedX, normalizedY = NormalizeCoordinates(waypoint.x, waypoint.y)

                -- Create a pin
                local pin = CreateFrame("Frame", nil, WorldMapFrame.ScrollContainer.Child, "BackdropTemplate")
                pin:SetSize(30, 30)

                -- Set appearance
                pin.texture = pin:CreateTexture(nil, "OVERLAY")
                pin.texture:SetAllPoints()
                pin.texture:SetTexture("Interface\\AchievementFrame\\UI-Achievement-Progressive-Shield")

                -- Position the pin
                pin:SetPoint("CENTER", WorldMapFrame.ScrollContainer.Child, "TOPLEFT",
                    normalizedX * WorldMapFrame.ScrollContainer.Child:GetWidth(),
                    -normalizedY * WorldMapFrame.ScrollContainer.Child:GetHeight())

                pin:Show()

                -- Debug pin placement
                --print(string.format("Pin added at Zone: %s (MapID: %d, ZoneID: %d), Coordinates: %.2f, %.2f (Normalized: %.4f, %.4f)",zoneInfo.name, correctedMapID, correctedZoneID, waypoint.x, waypoint.y, normalizedX, normalizedY))

                -- Store pin details for tooltip
                pin.waypoint = waypoint
				
						if TomTom and waypoint.x and waypoint.y then
                            -- Use the corrected MapID for TomTom Waypoint

							local achievementName = achievement.name or "Unknown Achievement"
							local criteriaName = criterion.description or "Unknown Objective"
							local source = "Meta-Track: Farewell to Arms"
							local achDesc = achievement.description or "No Achievment Description"
							local guideText = criterion.guide and "|cff00ff00Objective Guide Available (in addon UI)|r" or "|cffff0000No Objective Guide|r"

							TomTom:AddWaypoint(correctedMapID, waypoint.x / 100, waypoint.y / 100, {
								title = string.format("|cff00ff00%s|r\n\n|cff00ff00Achievement: |r%s\n%s\n\n|cff00ff00Objective: |r%s\n%s\n\n",
													  source, achievementName, achDesc, criteriaName, guideText),
								persistent = true,   -- Keep the waypoint until manually removed
								crazy = true,        -- Don't enable "crazy arrow" by default
								silent = true        -- Suppress messages in chat
							})


                            --print(string.format("TomTom Waypoint added: %.2f, %.2f in Zone %s (MapID %d)", waypoint.x, waypoint.y, zoneInfo.name, correctedMapID))
                        else
                            print("TomTom is not available or waypoint data is missing.")
                        end

                -- Handle interactions
                pin:SetScript("OnMouseDown", function(_, button)
                    if button == "RightButton" then
                        if TomTom and waypoint.x and waypoint.y then
                            -- Use the corrected MapID for TomTom Waypoint
                            TomTom:AddWaypoint(correctedMapID, waypoint.x / 100, waypoint.y / 100, {
                                title = string.format("%s (from: %s)", criterion.description, source)
                            })
                            --print(string.format("TomTom Waypoint added: %.2f, %.2f in Zone %s (MapID %d)", waypoint.x, waypoint.y, zoneInfo.name, correctedMapID))
                        else
                            print("TomTom is not available or waypoint data is missing.")
                        end
                    elseif button == "LeftButton" then
                        GameTooltip:SetOwner(pin, "ANCHOR_RIGHT")

                        -- Safely retrieve description and guide
                        local description = criterion.description or "No Description Available"
                        local guide = achievement.guide or "No additional guidance available."

                        -- Display the description
                        GameTooltip:SetText(description, 1, 1, 1)

                        -- Display the guide
                        GameTooltip:AddLine(string.format("Guide: %s", guide), 0.5, 0.8, 0.5) -- Greenish text for guides

                        -- Always show the TomTom interaction hint
                        GameTooltip:AddLine("|cff00ff00Right Click to Add TomTom Waypoint.|r", 0, 1, 0)

                        GameTooltip:Show()
                    end
                end)

                pin:SetScript("OnLeave", function()
                    GameTooltip:Hide()
                end)

                -- Add pin to activePins for tracking
                table.insert(activePins, pin)
            end
        end
    end

    local function UpdatePinsVisibility()
        local currentMapID = WorldMapFrame:GetMapID()
        for _, pin in ipairs(activePins) do
            if pin.waypoint and GetCorrectedMapID(GetCorrectedZoneID(pin.waypoint.mapID)) == currentMapID then
                pin:Show()
            else
                pin:Hide()
            end
        end
    end

    -- Hook into the ScrollContainer to monitor map changes
    WorldMapFrame.ScrollContainer:HookScript("OnUpdate", function()
        UpdatePinsVisibility()
    end)

    -- Ensure the correct map is opened
    C_Timer.NewTicker(0.1, function(ticker)
        if WorldMapFrame:GetMapID() ~= targetMapID then
            WorldMapFrame:SetMapID(targetMapID)
        else
            ticker:Cancel()
            AddPinsToMap()
            UpdatePinsVisibility()
        end
    end, 20)
end







local BUTTON_WIDTH = 400
local BUTTON_HEIGHT = 60
local BUTTON_PADDING = 10

------------------------------------------------------------
-- Populate Achievements
------------------------------------------------------------
function PopulateAchievements(filterText)
    if not content then return end
    -- Clear existing content
    for _, child in ipairs({content:GetChildren()}) do
        child:Hide()
        child:SetParent(nil)
    end

    local yOffset = -14
    local criteriaSearchEnabled = searchBox and searchBox.criteriaSearch:GetChecked()

    for _, achievement in ipairs(DrustWaypoints) do
        -- Determine visibility based on search criteria
        local isVisible
        if not filterText then
            isVisible = true
        else
            isVisible = achievement.name:lower():find(filterText)
            if not isVisible and criteriaSearchEnabled and achievement.criteria then
                for _, criterion in ipairs(achievement.criteria) do
                    if criterion.description and criterion.description:lower():find(filterText) then
                        isVisible = true
                        break
                    end
                end
            end
        end

        -- Hide the "Go Back" text if the achievement is not visible
        if achievement.goBackText then
            achievement.goBackText:Hide()
        end

        if isVisible then
            -- Create a Button instead of a Frame
            local achButton = CreateFrame("Button", nil, content, "BackdropTemplate")
            achButton:SetSize(BUTTON_WIDTH, BUTTON_HEIGHT)
            achButton:SetPoint("TOP", content, "TOP", 20, yOffset)
            achButton.achievementID = achievement.achievementID
            achButton:EnableMouse(true)
            achButton:SetFrameStrata("HIGH")
            achButton:SetFrameLevel(10)

            achButton:SetBackdrop({
                bgFile = "Interface\\AchievementFrame\\UI-Achievement-Parchment-Horizontal",
                edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
                tile = false,
                tileSize = 0,
                edgeSize = 16,
            })
            achButton:SetBackdropColor(0.3, 0.3, 0.3, 1)
            achButton:SetBackdropBorderColor(1, 1, 1, 1)

            -- Add a custom border as a texture layer
            local border = achButton:CreateTexture(nil, "OVERLAY")
            border:SetTexture("Interface\\AchievementFrame\\UI-Achievement-AchievementButtonBorder")
            border:SetAllPoints(achButton)

            local highlightTexture = achButton:CreateTexture(nil, "HIGHLIGHT")
            highlightTexture:SetTexture("Interface\\Buttons\\WHITE8X8")
            highlightTexture:SetVertexColor(0.3, 0.3, 0, 0.5)
            highlightTexture:SetBlendMode("ADD")

            local buttonWidth = achButton:GetWidth()
            local buttonHeight = achButton:GetHeight()
            highlightTexture:SetSize(buttonWidth, buttonHeight)
            highlightTexture:SetPoint("CENTER", achButton, "CENTER")
            achButton:SetHighlightTexture(highlightTexture)

            -- Determine text color based on faction
            local nameColor = "|cffffffff" -- Default white
            if achievement.faction == "Horde" then
                nameColor = "|cffff0000" -- Red for Horde
            elseif achievement.faction == "Alliance" then
                nameColor = "|cff0000ff" -- Blue for Alliance
            end

						-- Calculate Achievement Progress
			local totalCriteria = GetAchievementNumCriteria(achievement.achievementID)
			local completedCriteria = 0
			local criteriaAvailable = totalCriteria > 0

			if criteriaAvailable then
				for i = 1, totalCriteria do
					if select(3, GetAchievementCriteriaInfo(achievement.achievementID, i)) then
						completedCriteria = completedCriteria + 1
					end
				end
			else
				-- Handle achievements without criteria
				if select(4, GetAchievementInfo(achievement.achievementID)) then
					completedCriteria = 1
					totalCriteria = 1
				else
					-- For incomplete achievements with no criteria, display 0/1
					completedCriteria = 0
					totalCriteria = 1
				end
			end

			-- Apply special coloring for 0/1 case
			local progressColor
			if completedCriteria == 0 and totalCriteria == 1 then
				progressColor = "|cffff0000" -- Red for incomplete achievements
			else
				progressColor = (completedCriteria == totalCriteria) and "|cff00ff00" or "|cffff0000"
			end
			local progressText = string.format(progressColor .. " (%d/%d)|r", completedCriteria, totalCriteria)


            -- Add Achievement Text
            local achText = achButton:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
            achText:SetFont("Fonts\\FRIZQT__.TTF", 17)
            achText:SetPoint("CENTER", achButton, "CENTER", 0, 0)
            achText:SetText(nameColor .. achievement.name .. "|r " .. progressText)

            achButton:SetScript("OnClick", function(_, button)
                if button == "LeftButton" then
                    if IsShiftKeyDown() then
                        if not AchievementFrame then
                            AchievementFrame_LoadUI()
                        end
                        AchievementFrame:Show()
                        AchievementFrame_SelectAchievement(achievement.achievementID)
                    else
                        if expandedAchievements[achievement.achievementID] then
                            expandedAchievements[achievement.achievementID] = nil
                        else
                            expandedAchievements[achievement.achievementID] = true
                        end
                    end
                    PopulateAchievements(filterText)
                end
            end)

            AddTooltip(achButton, {
                "|cffffff00" .. achievement.name .. "|r",
                "\n" .. achievement.description,
                "\n" .. "|cff00ff00Left Click to expand or collapse |r",
                "\n" .. "|cff00ff00Shift-Left Click to open WoW Achievement UI |r",
            })

            yOffset = yOffset - 70

            -- Handle Expanded Achievements and "Go Back"
            if expandedAchievements[achievement.achievementID] then
                if achievement.parentAchievementID then
                    if achievement.goBackText then
                        achievement.goBackText:Hide()
                        achievement.goBackText = nil
                    end

                    local parentName = nil
                    for _, parentAchievement in ipairs(DrustWaypoints) do
                        if parentAchievement.achievementID == achievement.parentAchievementID then
                            parentName = parentAchievement.name
                            break
                        end
                    end

                    parentName = parentName or "Unknown"

                    -- Create the "Go Back" text
                    local goBackText = content:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
                    goBackText:SetFont("Fonts\\FRIZQT__.TTF", 12)
                    goBackText:SetPoint("TOPLEFT", content, "TOPLEFT", 30, yOffset)
                    goBackText:SetText("|TInterface\\Buttons\\UI-SpellbookIcon-PrevPage-Up:16|t Go Back (" .. parentName .. ")")
                    goBackText:SetTextColor(1, 0.8, 0)
                    goBackText:SetJustifyH("LEFT")
                    goBackText:SetShadowOffset(2, -3)
                    goBackText:SetShadowColor(0, 0, 0, 1)

                    goBackText:SetScript("OnMouseDown", function()
						-- Collapse the current achievement
						expandedAchievements[achievement.achievementID] = nil

						-- Expand the parent achievement
						expandedAchievements[achievement.parentAchievementID] = true

						-- Repopulate the achievements
						PopulateAchievements(nil)

						-- Scroll to the parent achievement reliably
						C_Timer.After(0.1, function()
							local parentFound = false
							local accumulatedOffset = 0
							local totalContentHeight = 0

							-- Calculate the total content height manually
							for _, child in ipairs({content:GetChildren()}) do
								if child:IsShown() then
									totalContentHeight = totalContentHeight + child:GetHeight() + 10 -- Add spacing
								end
							end

							for _, child in ipairs({content:GetChildren()}) do
								if child:IsShown() then
									-- Increment the offset for each shown child
									accumulatedOffset = accumulatedOffset + child:GetHeight() + 10

									-- Check if this is the parent achievement
									if child.achievementID == achievement.parentAchievementID then
										-- Highlight the parent achievement visually
										child:SetBackdropColor(0.6, 0.6, 0.0, 0.8) -- Yellow highlight effect
										C_Timer.After(1, function()
											child:SetBackdropColor(0.3, 0.3, 0.3, 1) -- Reset highlight after 1 second
										end)

										-- Scroll to make the parent achievement visible
										local scrollFrameHeight = scrollFrame:GetHeight()

										-- Calculate a valid scroll offset
										local targetOffset = math.max(0, math.min(accumulatedOffset - scrollFrameHeight / 2, totalContentHeight - scrollFrameHeight))
										local targetOffset2 = targetOffset + 170 

										-- Apply the scroll
										if scrollFrame.ScrollBar then
											if achievement.parentAchievementID == 40953 or achievement.parentAchievementID == 40960 then
												--print("Error: Achievement Name: ", achievement.name)
												scrollFrame.ScrollBar:SetValue(targetOffset)
											else
												scrollFrame.ScrollBar:SetValue(targetOffset2)
											end
										else
											scrollFrame:SetVerticalScroll(targetOffset2)
										end

										parentFound = true
										break
									end
								end
							end

							-- Log an error if the parent achievement is not found
							if not parentFound then
								print("Error: Could not find parent achievement in the UI for ID:", achievement.parentAchievementID)
							end
						end)
					end)


                    achievement.goBackText = goBackText
                    yOffset = yOffset - 30
                end

                -- Populate Criteria
                for _, criterion in ipairs(achievement.criteria or {}) do
                    local critFrame = CreateFrame("Frame", nil, content)
                    critFrame:SetSize(520, 30)
                    critFrame:SetPoint("TOPLEFT", content, "TOPLEFT", 30, yOffset)

                    local critText = critFrame:CreateFontString(nil, "OVERLAY")
                    critText:SetFont("Fonts\\FRIZQT__.TTF", 12)
                    critText:SetPoint("LEFT", critFrame, "LEFT", 10, 0)

                    local success, name, _, isComplete, quantity, reqQuantity = pcall(GetAchievementCriteriaInfo, achievement.achievementID, criterion.criteriaIndex or 0)
                    local critColor = isComplete and "|cff00ff00" or "|cffff0000"
                    local progressText = success and name and string.format(critColor .. " (%d/%d)|r", quantity or 0, reqQuantity or 1) or "|cffff0000 (API Error)|r"

                    if criterion.childAchievementID then
                        critText:SetText("|TInterface\\Icons\\Achievement_Quests_Completed_01:16|t " .. "|cffffffff" .. (criterion.description or "Unknown") .. "|r " .. progressText)
                    else
                        critText:SetText("|cffffffff" .. (criterion.description or "Unknown") .. "|r " .. progressText)
                    end

                    critText:SetShadowOffset(2, -1)
                    critText:SetShadowColor(0, 0, 0, 1)

                    AddTooltip(critFrame, {
						"|cffffff00" .. (criterion.description or "No Description Available") .. "|r", -- Safely handle nil
						"\n",
						(criterion.waypoints and #criterion.waypoints > 0) and 
							"|cff00ff00Right-click to set waypoints.|r" or 
							"|cffff0000No Waypoints Available.|r",
						"\n",
						criterion.guide and 
							{ label = "|cffffd700Guide:|r", text = "|cffffffff" .. criterion.guide .. "|r" } or 
							"|cffff0000No Guide Available.|r",
					})


                    critFrame:SetScript("OnMouseDown", function(_, button)
                        if button == "RightButton" then
                            AddCustomPins(achievement, criterion)
                            WorldMapFrame:Show()
						elseif button == "LeftButton" and criterion.childAchievementID then
							-- Collapse the parent achievement
							expandedAchievements[achievement.achievementID] = nil

							-- Expand the child achievement
							expandedAchievements[criterion.childAchievementID] = true

							-- Repopulate the achievements
							PopulateAchievements(nil)

							-- Scroll to the child achievement reliably
							C_Timer.After(0.1, function()
								local childFound = false
								local accumulatedOffset = 0
								local totalContentHeight = 0

								-- Calculate the total content height manually
								for _, child in ipairs({content:GetChildren()}) do
									if child:IsShown() then
										totalContentHeight = totalContentHeight + child:GetHeight() + 10 -- Add spacing
									end
								end

								for _, child in ipairs({content:GetChildren()}) do
									if child:IsShown() then
										-- Increment the offset for each shown child
										accumulatedOffset = accumulatedOffset + child:GetHeight() + 10

										-- Check if this is the target child
										if child.achievementID == criterion.childAchievementID then
											-- Highlight the child achievement visually
											child:SetBackdropColor(0.6, 0.6, 0.0, 0.8) -- Yellow highlight effect
											C_Timer.After(1, function()
												child:SetBackdropColor(0.3, 0.3, 0.3, 1) -- Reset highlight after 1 second
											end)

											-- Scroll to make the child achievement visible
											local scrollFrameHeight = scrollFrame:GetHeight()

											-- Calculate a valid scroll offset
											local targetOffset = math.max(0, math.min(accumulatedOffset - scrollFrameHeight / 2, totalContentHeight - scrollFrameHeight))
											local targetOffset2 = targetOffset + 170 

											-- Apply the scroll
											if scrollFrame.ScrollBar then
												if criterion.childAchievementID == 40953 or criterion.childAchievementID == 40960 or criterion.childAchievementID == 12521 then 
													--print("Error: Achievement Name: ", achievement.name)
													scrollFrame.ScrollBar:SetValue(targetOffset)
												else
													scrollFrame.ScrollBar:SetValue(targetOffset2)
												end
											else
												scrollFrame:SetVerticalScroll(targetOffset2)
											end

											childFound = true
											break
										end
									end
								end

								-- Log an error if the child achievement is not found
								if not childFound then
									print("Error: Could not find child achievement in the UI for ID:", criterion.childAchievementID)
								end
							end)
						end

                    end)
                    yOffset = yOffset - 40
                end
            end
        end
    end
end


-- Event Handling for Initial Data and Achievement Refresh
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD") -- Ensure progress is updated after login
eventFrame:RegisterEvent("ACHIEVEMENT_EARNED")
eventFrame:RegisterEvent("CRITERIA_UPDATE")

local debounceTimer
local function DebouncedPopulateAchievements()
    if debounceTimer then
        debounceTimer:Cancel()
    end
    debounceTimer = C_Timer.NewTimer(0.5, function()
        PopulateAchievements() -- Refresh UI
        UpdateProgressSummary() -- Update overall progress
    end)
end

eventFrame:SetScript("OnEvent", function(_, event)
    if event == "PLAYER_ENTERING_WORLD" or event == "ACHIEVEMENT_EARNED" or event == "CRITERIA_UPDATE" then
        if searchBox and searchBox:GetText() ~= "Search Achievements" and searchBox:GetText() ~= "" then
            -- Do not repopulate if the search bar is in use
            --print("Skipping achievement update due to active search.")
        else
            -- Call the debounced populate function if the search bar is empty
            DebouncedPopulateAchievements()
        end
    end
end)



------------------------------------------------------------
-- Initialization
------------------------------------------------------------
PopulateAchievements()
UpdateProgressSummary()
NotifyAchievementProgress()

------------------------------------------------------------
-- Toggle Frame Command
------------------------------------------------------------
SLASH_DRUSTSETTLESTRACKER1 = "/drustui"
SlashCmdList["DRUSTSETTLESTRACKER"] = function()
    if not frame or not frame:IsShown() then
        if not frame then
            --print("Meta-Track: Farewell to Arms: Reinitializing frame.")
            --CreateUIFrame() -- Reinitialize if necessary
        else
            frame:Show()
        end
    else
        frame:Hide()
    end
end

--print("Meta-Track: Farewell to Arms loaded.")

SLASH_DRUSTDEBUG1 = "/drustdebug"
SlashCmdList["DRUSTDEBUG"] = function(input)
    -- Convert the input string to a number (achievement ID)
    local achievementID = tonumber(input)
    if not achievementID then
        print("Error: Please provide a valid achievement ID. Example: /drustdebug 41205")
        return
    end

    -- Function to search for the achievement ID in a given table
    local function FindAchievementByID(partsTable, id)
        if not partsTable or type(partsTable) ~= "table" then
            return nil
        end

        for _, achievement in ipairs(partsTable) do
            if achievement.achievementID == id then
                return achievement
            end
        end
        return nil
    end

    -- Search in DrustWaypointsPart1
    local foundInPart1 = FindAchievementByID(DrustWaypointsPart1, achievementID)
    if foundInPart1 then
        print(string.format("Achievement found in DrustWaypointsPart1: %s (ID: %d)", foundInPart1.name, foundInPart1.achievementID))
    else
        print("Achievement not found in DrustWaypointsPart1.")
    end

    -- Search in DrustWaypointsPart2
    local foundInPart2 = FindAchievementByID(DrustWaypointsPart2, achievementID)
    if foundInPart2 then
        print(string.format("Achievement found in DrustWaypointsPart2: %s (ID: %d)", foundInPart2.name, foundInPart2.achievementID))
    else
        print("Achievement not found in DrustWaypointsPart2.")
    end

    -- Combine results
    if not foundInPart1 and not foundInPart2 then
        print(string.format("Achievement ID %d not found in any Waypoints data.", achievementID))
    end
end