-- Housing Decor Guide - Trainers Module
-- Loaded on demand when user clicks Trainers button
-- New UX: Single panel with collapsible profession sections, only shows known professions

local addonName, addon = ...

-- Module namespace
HDG_Trainers = HDG_Trainers or {}

-- Local references (set during init)
local CONFIG
local mainFrame
local PlayerHasProfession

-- Zone Map IDs for TomTom integration and localization
-- These are uiMapIDs used by C_Map.GetMapInfo()
local ZONE_MAP_IDS = {
    -- Capital Cities (Kalimdor/Eastern Kingdoms)
    ["Stormwind City"] = 84,
    ["Orgrimmar"] = 85,
    ["Ironforge"] = 87,
    ["Thunder Bluff"] = 88,
    ["Darnassus"] = 89,
    ["Undercity"] = 90,
    ["Silvermoon City"] = 110,
    ["Exodar"] = 103,
    ["The Exodar"] = 103,

    -- TBC
    ["Shattrath City"] = 111,
    ["Shattrath"] = 111,
    ["Hellfire Peninsula"] = 100,

    -- WotLK
    ["Dalaran (Northrend)"] = 125,
    ["Dalaran"] = 125,

    -- MoP
    ["Jade Forest"] = 371,
    ["The Jade Forest"] = 371,
    ["Valley of the Four Winds"] = 376,
    ["Kun-Lai Summit"] = 379,

    -- WoD
    ["Stormshield"] = 622,
    ["Warspear"] = 624,
    ["Lunarfall"] = 582,
    ["Frostwall"] = 590,

    -- Legion
    ["Dalaran (Broken Isles)"] = 627,

    -- BfA
    ["Boralus"] = 1161,
    ["Dazar'alor"] = 1165,

    -- Shadowlands
    ["Oribos"] = 1670,

    -- Dragonflight
    ["Valdrakken"] = 2112,

    -- TWW
    ["Dornogal"] = 2339,
}

-- Build reverse lookup: mapID -> localized name (built on first use)
local mapIDToLocalizedName = nil

local function BuildLocalizedZoneLookup()
    if mapIDToLocalizedName then return end
    mapIDToLocalizedName = {}

    for englishName, mapID in pairs(ZONE_MAP_IDS) do
        if not mapIDToLocalizedName[mapID] and C_Map and C_Map.GetMapInfo then
            local mapInfo = C_Map.GetMapInfo(mapID)
            if mapInfo and mapInfo.name then
                mapIDToLocalizedName[mapID] = mapInfo.name
            end
        end
    end
end

-- Reference centralized expansion order for display
local EXPANSION_ORDER = HDG_ExpansionData.EXPANSION_ORDER

-- Track collapsed state per profession
local collapsedProfessions = {}

-- Get characters who need training for a profession/expansion
-- Returns array of character names (without realm) whose skill is below max
local function GetCharactersNeedingTraining(profName, expName)
    local needsTraining = {}

    if not HDG_Settings or not HDG_Settings.characters then
        return needsTraining
    end

    -- Get max skill for this profession/expansion
    local maxSkill = nil
    if HDG_ProfessionThresholds and HDG_ProfessionThresholds[profName] and HDG_ProfessionThresholds[profName][expName] then
        maxSkill = HDG_ProfessionThresholds[profName][expName].max
    end

    if not maxSkill then
        return needsTraining
    end

    -- Check each character
    for charKey, charData in pairs(HDG_Settings.characters) do
        if charData.professions and charData.professions[profName] then
            local profData = charData.professions[profName]
            if profData.skillLevels and profData.skillLevels[expName] then
                local skillData = profData.skillLevels[expName]
                -- skillData can be a number or a table { current = X, max = Y }
                local currentSkill = type(skillData) == "table" and skillData.current or skillData
                if currentSkill and currentSkill > 0 and currentSkill < maxSkill then
                    -- Extract character name without realm
                    local charName = charKey:match("^([^-]+)") or charKey
                    table.insert(needsTraining, {
                        name = charName,
                        skill = currentSkill,
                        max = maxSkill
                    })
                end
            end
        end
    end

    -- Sort by skill level (lowest first)
    table.sort(needsTraining, function(a, b)
        return a.skill < b.skill
    end)

    return needsTraining
end

-- Get character with most known decor recipes for a profession
-- Returns { name = "Char-Realm", count = N, total = M } or nil if none found
local function GetTopDecorCrafter(profName)
    if not HDG_Settings or not HDG_Settings.characters then
        return nil
    end

    local topCrafter = nil
    local topCount = 0

    for charKey, charData in pairs(HDG_Settings.characters) do
        if charData.professions and charData.professions[profName] then
            local profData = charData.professions[profName]
            local knownCount = profData.knownCount or 0
            local totalCount = profData.totalCount or 0

            if knownCount > topCount then
                topCount = knownCount
                topCrafter = {
                    name = charKey,
                    count = knownCount,
                    total = totalCount
                }
            end
        end
    end

    return topCrafter
end

-- Cache for localized zone names
local localizedZoneCache = {}

-- Get localized zone name from English zone name using WoW API
local function GetLocalizedZoneName(englishZoneName)
    if not englishZoneName then return nil end

    -- Check cache first
    if localizedZoneCache[englishZoneName] then
        return localizedZoneCache[englishZoneName]
    end

    -- Build the lookup table if needed
    BuildLocalizedZoneLookup()

    -- Look up mapID from our zone table
    local mapID = ZONE_MAP_IDS[englishZoneName]
    if mapID then
        -- First try our pre-built lookup
        if mapIDToLocalizedName and mapIDToLocalizedName[mapID] then
            localizedZoneCache[englishZoneName] = mapIDToLocalizedName[mapID]
            return mapIDToLocalizedName[mapID]
        end

        -- Fallback: try C_Map.GetMapInfo directly
        if C_Map and C_Map.GetMapInfo then
            local mapInfo = C_Map.GetMapInfo(mapID)
            if mapInfo and mapInfo.name then
                localizedZoneCache[englishZoneName] = mapInfo.name
                return mapInfo.name
            end
        end
    end

    -- Fallback to English name
    return englishZoneName
end

-- Module frame reference
local trainersPanel = nil

-- NPC Name Cache (populated at runtime via WoW API)
local NPCNameCache = {}

-- Get NPC name from WoW API with fallback to cached name
-- Uses C_TooltipInfo.GetHyperlink pattern similar to AllTheThings
local function GetNPCName(npcID, cachedName)
    if not npcID then return cachedName or "Unknown" end

    -- Check our cache first
    if NPCNameCache[npcID] then
        return NPCNameCache[npcID]
    end

    -- Try to get name from WoW API
    if C_TooltipInfo and C_TooltipInfo.GetHyperlink then
        local tooltipData = C_TooltipInfo.GetHyperlink(string.format("unit:Creature-0-0-0-0-%d-0000000000", npcID))
        if tooltipData and tooltipData.lines and tooltipData.lines[1] then
            local name = tooltipData.lines[1].leftText
            if name and name ~= "" and not name:find("Retrieving") then
                NPCNameCache[npcID] = name
                return name
            end
        end
    end

    -- Fallback to cached name from database
    return cachedName or "Unknown"
end

-- Helper function to parse coordinates from location string
local function ParseTrainerCoords(location)
    if not location then return nil, nil, nil end
    
    local zoneName, x, y = location:match("^(.-)%s*%[([%d%.]+),%s*([%d%.]+)%]$")
    if zoneName and x and y then
        return zoneName, tonumber(x), tonumber(y)
    end
    
    return location, nil, nil
end

-- Helper function to add TomTom waypoint
local function AddTomTomWaypoint(zoneName, x, y, title)
    if not TomTom then
        print("|cFFfcd34d[Housing Decor Guide]|r TomTom addon not found. Install TomTom to use waypoints.")
        return false
    end
    
    local mapID = ZONE_MAP_IDS[zoneName]
    if not mapID then
        print("|cFFFF6600[Housing Decor Guide]|r Unknown zone: '" .. tostring(zoneName) .. "' - please report this!")
        return false
    end
    
    local wayX = x / 100
    local wayY = y / 100
    
    local success, uid = pcall(function()
        if TomTom.AddWaypoint then
            return TomTom:AddWaypoint(mapID, wayX, wayY, {
                title = title or "Trainer",
                from = "Housing Decor Guide",
                persistent = false,
                minimap = true,
                world = true,
            })
        end
    end)
    
    if success and uid then
        print(string.format("|cFF00FF00[Housing Decor Guide]|r Waypoint added: %s (%.1f, %.1f)", title or zoneName, x, y))
        return true
    else
        print(string.format("|cFFFF0000[Housing Decor Guide]|r Failed to set waypoint: %s", tostring(uid or "unknown error")))
        return false
    end
end

-- Column widths for trainer table layout (use CONFIG if available, else defaults)
local function GetTrainersConfig()
    if CONFIG and CONFIG.TRAINERS_TAB then
        return CONFIG.TRAINERS_TAB
    end
    -- Fallback defaults
    return {
        FACTION_COL = 46,
        NAME_COL = 160,
        ZONE_COL = 140,
        COORDS_COL = 70,
        ROW_HEIGHT = 22,
        ENTRY_PADDING = 24,
        FACTION_BOX_WIDTH = 20,
        FACTION_BOX_HEIGHT = 16,
    }
end

-- Create a trainer entry row with columns: Faction | Name | Zone | Coords | TomTom
local function CreateTrainerEntry(parent, width, yOffset, faction, trainerInfo)
    local TC = GetTrainersConfig()
    local row = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    row:SetSize(width - TC.ENTRY_PADDING, TC.ROW_HEIGHT)
    row:SetPoint("TOPLEFT", TC.ENTRY_PADDING, yOffset)
    row:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8X8",
        tile = false,
    })

    -- Alternate row colors for readability
    local rowIndex = math.floor(math.abs(yOffset) / TC.ROW_HEIGHT)
    if rowIndex % 2 == 0 then
        row:SetBackdropColor(unpack(HDG_UIHelpers.ROW_EVEN))
    else
        row:SetBackdropColor(unpack(HDG_UIHelpers.ROW_ODD))
    end

    local xPos = 4

    -- Column 1: Faction indicator
    local factionBg = row:CreateTexture(nil, "BACKGROUND")
    factionBg:SetPoint("LEFT", xPos, 0)
    factionBg:SetTexture("Interface\\Buttons\\WHITE8X8")

    local factionText = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    factionText:SetPoint("LEFT", xPos + 2, 0)
    factionText:SetShadowOffset(0, 0)

    if faction == "Alliance" then
        factionBg:SetSize(TC.FACTION_BOX_WIDTH, TC.FACTION_BOX_HEIGHT)
        factionBg:SetVertexColor(0.1, 0.2, 0.4, 0.8)
        factionText:SetWidth(16)
        factionText:SetText("|cFF3366CCA|r")
    elseif faction == "Horde" then
        factionBg:SetSize(TC.FACTION_BOX_WIDTH, TC.FACTION_BOX_HEIGHT)
        factionBg:SetVertexColor(0.4, 0.1, 0.1, 0.8)
        factionText:SetWidth(16)
        factionText:SetText("|cFFCC3333H|r")
    else
        -- Both factions: show A and H side by side
        factionBg:SetSize(TC.FACTION_BOX_WIDTH, TC.FACTION_BOX_HEIGHT)
        factionBg:SetVertexColor(0.1, 0.2, 0.4, 0.8)
        factionText:SetWidth(16)
        factionText:SetText("|cFF3366CCA|r")

        local hordeBg = row:CreateTexture(nil, "BACKGROUND")
        hordeBg:SetSize(TC.FACTION_BOX_WIDTH, TC.FACTION_BOX_HEIGHT)
        hordeBg:SetPoint("LEFT", factionBg, "RIGHT", 2, 0)
        hordeBg:SetColorTexture(0.4, 0.1, 0.1, 0.8)

        local hordeText = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        hordeText:SetPoint("CENTER", hordeBg, "CENTER", 0, 0)
        hordeText:SetJustifyH("CENTER")
        hordeText:SetShadowOffset(0, 0)
        hordeText:SetWidth(16)
        hordeText:SetText("|cFFCC3333H|r")
    end
    xPos = xPos + TC.FACTION_COL

    -- Parse coordinates from location string
    local zoneName, coordX, coordY = ParseTrainerCoords(trainerInfo.location)
    local hasCoords = coordX and coordY
    local localizedZone = GetLocalizedZoneName(zoneName) or zoneName or ""

    -- Column 2: Trainer Name (white, bold)
    local displayName = GetNPCName(trainerInfo.npcID, trainerInfo.name)
    local nameText = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    nameText:SetPoint("LEFT", xPos, 0)
    nameText:SetWidth(TC.NAME_COL)
    nameText:SetJustifyH("LEFT")
    nameText:SetShadowOffset(0, 0)
    nameText:SetText("|cFFFFFFFF" .. displayName .. "|r")
    xPos = xPos + TC.NAME_COL

    -- Column 3: Zone Name (gray) - localized
    local zoneText = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    zoneText:SetPoint("LEFT", xPos, 0)
    zoneText:SetWidth(TC.ZONE_COL)
    zoneText:SetJustifyH("LEFT")
    zoneText:SetShadowOffset(0, 0)
    zoneText:SetText("|cFFAAAAAA" .. localizedZone .. "|r")
    xPos = xPos + TC.ZONE_COL

    -- Column 4: Coordinates (cyan if available, dim if not)
    local coordText = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    coordText:SetPoint("LEFT", xPos, 0)
    coordText:SetWidth(TC.COORDS_COL)
    coordText:SetJustifyH("LEFT")
    coordText:SetShadowOffset(0, 0)
    if hasCoords then
        coordText:SetText(string.format("|cFF66CCCC%.1f, %.1f|r", coordX, coordY))
    else
        coordText:SetText("|cFF666666--|r")
    end
    xPos = xPos + TC.COORDS_COL

    -- Column 5: TomTom waypoint button
    if hasCoords then
        local waypointBtn = CreateFrame("Button", nil, row)
        waypointBtn:SetSize(16, 16)
        waypointBtn:SetPoint("LEFT", xPos, 0)

        local btnIcon = waypointBtn:CreateTexture(nil, "ARTWORK")
        btnIcon:SetAllPoints()
        btnIcon:SetTexture("Interface\\MINIMAP\\TRACKING\\Target")
        btnIcon:SetVertexColor(0.3, 0.9, 0.3)

        waypointBtn:SetScript("OnEnter", function(self)
            btnIcon:SetVertexColor(0.5, 1, 0.5)
            row:SetBackdropColor(unpack(HDG_UIHelpers.ROW_HOVER))
            GameTooltip:SetOwner(self, HDG_UIHelpers.TOOLTIP_ANCHOR)
            if TomTom then
                GameTooltip:SetText("Add TomTom Waypoint", 1, 1, 1)
                GameTooltip:AddLine(string.format("%s (%.1f, %.1f)", localizedZone, coordX, coordY), 0.8, 0.8, 0.8)
            else
                GameTooltip:SetText("TomTom Not Installed", 1, 0.5, 0.5)
            end
            GameTooltip:Show()
        end)

        waypointBtn:SetScript("OnLeave", function()
            btnIcon:SetVertexColor(0.3, 0.9, 0.3)
            local idx = math.floor(math.abs(yOffset) / TC.ROW_HEIGHT)
            if idx % 2 == 0 then
                row:SetBackdropColor(unpack(HDG_UIHelpers.ROW_EVEN))
            else
                row:SetBackdropColor(unpack(HDG_UIHelpers.ROW_ODD))
            end
            GameTooltip:Hide()
        end)

        waypointBtn:SetScript("OnClick", function()
            local title = displayName .. " - " .. localizedZone
            AddTomTomWaypoint(zoneName, coordX, coordY, title)  -- Keep English zoneName for mapID lookup
        end)
    end

    -- Row hover effect
    row:EnableMouse(true)
    row:SetScript("OnEnter", function(self)
        self:SetBackdropColor(unpack(HDG_UIHelpers.ROW_HOVER))
    end)
    row:SetScript("OnLeave", function(self)
        local idx = math.floor(math.abs(yOffset) / TC.ROW_HEIGHT)
        if idx % 2 == 0 then
            self:SetBackdropColor(unpack(HDG_UIHelpers.ROW_EVEN))
        else
            self:SetBackdropColor(unpack(HDG_UIHelpers.ROW_ODD))
        end
    end)

    return yOffset - TC.ENTRY_PADDING
end

-- Create expansion section within a profession
local function CreateExpansionSection(parent, width, yOffset, expName, expData, profName)
    -- Expansion label (indented, with subtle background)
    local expFrame = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    expFrame:SetSize(width - 12, 20)
    expFrame:SetPoint("TOPLEFT", 12, yOffset)
    expFrame:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8X8",
        tile = false,
    })
    expFrame:SetBackdropColor(0.15, 0.15, 0.18, 0.5)

    local expColor = HDG_ExpansionData.GetColor(expName)

    -- Colored left accent bar
    local accentBar = expFrame:CreateTexture(nil, "ARTWORK")
    accentBar:SetSize(3, 16)
    accentBar:SetPoint("LEFT", 2, 0)
    accentBar:SetTexture("Interface\\Buttons\\WHITE8X8")
    accentBar:SetVertexColor(expColor[1], expColor[2], expColor[3], 1)

    local expLabel = expFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    expLabel:SetPoint("LEFT", 10, 0)
    expLabel:SetShadowOffset(0, 0)  -- Remove text shadow
    expLabel:SetText(string.format("|cFF%02x%02x%02x%s|r",
        expColor[1] * 255, expColor[2] * 255, expColor[3] * 255, expName))

    -- Check for characters needing training and show on right side of expansion header
    local charsNeedingTraining = GetCharactersNeedingTraining(profName, expName)
    if #charsNeedingTraining > 0 then
        local names = {}
        for _, charInfo in ipairs(charsNeedingTraining) do
            table.insert(names, string.format("|cFFfcd34d%s|r |cFF888888(%d/%d)|r", charInfo.name, charInfo.skill, charInfo.max))
        end
        local trainingText = expFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        trainingText:SetPoint("RIGHT", -8, 0)
        trainingText:SetShadowOffset(0, 0)
        trainingText:SetText("|cFF888888Needs training:|r " .. table.concat(names, ", "))
    end

    yOffset = yOffset - 22

    if expData.notes then
        local noteText = parent:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        noteText:SetPoint("TOPLEFT", 28, yOffset)
        noteText:SetShadowOffset(0, 0)  -- Remove text shadow
        noteText:SetText("|cFF666666" .. expData.notes .. "|r")
        yOffset = yOffset - 20
    else
        if expData.Alliance then
            yOffset = CreateTrainerEntry(parent, width, yOffset, "Alliance", expData.Alliance)
        end
        if expData.Horde then
            yOffset = CreateTrainerEntry(parent, width, yOffset, "Horde", expData.Horde)
        end
        if expData.Both then
            yOffset = CreateTrainerEntry(parent, width, yOffset, "Both", expData.Both)
        end
    end

    return yOffset - 2
end

-- Create collapsible profession section
-- isKnownByPlayer: true if the current character has this profession
local function CreateProfessionSection(parent, width, yOffset, profName, trainerData, isKnownByPlayer)
    local isCollapsed = collapsedProfessions[profName]
    local localizedProfName = HDG_ExpansionData.GetLocalizedProfessionName(profName)

    -- Profession header (clickable) - more prominent
    local header = CreateFrame("Button", nil, parent, "BackdropTemplate")
    header:SetSize(width, 28)
    header:SetPoint("TOPLEFT", 0, yOffset)
    header:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8X8",
        edgeFile = "Interface\\Buttons\\WHITE8X8",
        edgeSize = 1,
        tile = false,
        insets = {left = 0, right = 0, top = 0, bottom = 0}
    })

    -- Different background color for known vs not-known professions
    if isKnownByPlayer then
        header:SetBackdropColor(0.18, 0.18, 0.25, 0.95)  -- Normal (player has this profession)
    else
        header:SetBackdropColor(0.12, 0.12, 0.15, 0.95)  -- Darker (player doesn't have this profession)
    end
    header:SetBackdropBorderColor(unpack(HDG_UIHelpers.BORDER_COLOR_DIM))

    -- Collapse indicator (use simple +/- that render reliably)
    local collapseIcon = header:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    collapseIcon:SetPoint("LEFT", 8, 0)
    collapseIcon:SetShadowOffset(0, 0)  -- Remove text shadow
    if isCollapsed then
        collapseIcon:SetText("|cFFe2e8f0+|r")
    else
        collapseIcon:SetText("|cFFe2e8f0-|r")
    end

    -- Profession name - gold if player has it, gray if not
    local profText = header:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    profText:SetPoint("LEFT", 26, 0)
    profText:SetShadowOffset(0, 0)  -- Remove text shadow
    if isKnownByPlayer then
        profText:SetText("|cFFffd100" .. localizedProfName .. "|r")  -- Gold for known
    else
        profText:SetText("|cFF888888" .. localizedProfName .. "|r")  -- Gray for not known
    end

    -- Top decor crafter for this profession
    local topCrafter = GetTopDecorCrafter(profName)
    local crafterText = header:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    crafterText:SetPoint("RIGHT", -90, 0)
    crafterText:SetShadowOffset(0, 0)
    if topCrafter and topCrafter.count > 0 then
        crafterText:SetText("|cFF88aacc" .. topCrafter.name .. "|r")
    else
        crafterText:SetText("|cFF666666none known|r")
    end

    -- Trainer count hint (brighter gray)
    local countText = header:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    countText:SetPoint("RIGHT", -10, 0)
    countText:SetShadowOffset(0, 0)  -- Remove text shadow
    local trainerCount = 0
    if trainerData then
        for _, expData in pairs(trainerData) do
            if expData.Alliance then trainerCount = trainerCount + 1 end
            if expData.Horde then trainerCount = trainerCount + 1 end
            if expData.Both then trainerCount = trainerCount + 1 end
        end
    end
    countText:SetText("|cFF999999" .. trainerCount .. " trainers|r")
    
    -- Click to toggle
    header:SetScript("OnClick", function()
        collapsedProfessions[profName] = not collapsedProfessions[profName]
        HDG_Trainers:Refresh()
    end)
    
    header:SetScript("OnEnter", function(self)
        self:SetBackdropColor(0.25, 0.25, 0.35, 0.95)
    end)

    header:SetScript("OnLeave", function(self)
        -- Restore correct color based on whether player has this profession
        if isKnownByPlayer then
            self:SetBackdropColor(0.18, 0.18, 0.25, 0.95)
        else
            self:SetBackdropColor(0.12, 0.12, 0.15, 0.95)
        end
    end)
    
    yOffset = yOffset - 30
    
    -- If not collapsed, show expansions
    if not isCollapsed and trainerData then
        for _, expName in ipairs(EXPANSION_ORDER) do
            local expData = trainerData[expName]
            if expData then
                yOffset = CreateExpansionSection(parent, width, yOffset, expName, expData, profName)
            end
        end
        yOffset = yOffset - 6  -- Extra gap after profession
    end
    
    return yOffset
end

-- Get all professions, with player's known professions first, then others
-- Returns: { professions = {}, knownSet = {} }
local function GetAllProfessionsSorted()
    local allProfs = {
        "Alchemy", "Blacksmithing", "Enchanting", "Engineering",
        "Inscription", "Jewelcrafting", "Leatherworking", "Tailoring", "Cooking"
    }

    local known = {}
    local notKnown = {}
    local knownSet = {}

    for _, profName in ipairs(allProfs) do
        if PlayerHasProfession and PlayerHasProfession(profName) then
            knownSet[profName] = true
            -- Add Cooking at the end of known list
            if profName ~= "Cooking" then
                table.insert(known, profName)
            end
        else
            -- Add Cooking at the end of not-known list
            if profName ~= "Cooking" then
                table.insert(notKnown, profName)
            end
        end
    end

    -- Add Cooking last in its respective group
    if knownSet["Cooking"] then
        table.insert(known, "Cooking")
    else
        table.insert(notKnown, "Cooking")
    end

    -- Combine: known first, then not known
    local result = {}
    for _, prof in ipairs(known) do
        table.insert(result, prof)
    end
    for _, prof in ipairs(notKnown) do
        table.insert(result, prof)
    end

    return { professions = result, knownSet = knownSet }
end

-- Initialize the module (called from main addon)
function HDG_Trainers:Init(configRef, mainFrameRef, playerHasProfFunc)
    CONFIG = configRef
    mainFrame = mainFrameRef
    PlayerHasProfession = playerHasProfFunc

    -- All professions default to collapsed
    local allProfs = {
        "Alchemy", "Blacksmithing", "Enchanting", "Engineering",
        "Inscription", "Jewelcrafting", "Leatherworking", "Tailoring", "Cooking"
    }

    -- Check if we have saved state with the new "allCollapsedDefault" marker
    -- If not, reset to all collapsed (migration from old format)
    if HDG_Settings and HDG_Settings.trainersCollapsed and HDG_Settings.trainersCollapsed._allCollapsedDefault then
        -- Load saved state
        for profName, isCollapsed in pairs(HDG_Settings.trainersCollapsed) do
            if profName ~= "_allCollapsedDefault" then
                collapsedProfessions[profName] = isCollapsed
            end
        end
    else
        -- First time or migration: all collapsed
        for _, profName in ipairs(allProfs) do
            collapsedProfessions[profName] = true
        end
        -- Mark that we've set the default
        if HDG_Settings then
            HDG_Settings.trainersCollapsed = { _allCollapsedDefault = true }
            for _, profName in ipairs(allProfs) do
                HDG_Settings.trainersCollapsed[profName] = true
            end
        end
    end
end

-- Create the trainers panel (called when tab is first clicked)
function HDG_Trainers:CreatePanel()
    if trainersPanel then return trainersPanel end
    
    -- Create panel that fills the content area
    trainersPanel = CreateFrame("Frame", nil, mainFrame, "BackdropTemplate")
    trainersPanel:SetPoint("TOPLEFT", 8, -(CONFIG.BANNER_HEIGHT + CONFIG.TAB_HEIGHT + 8))
    trainersPanel:SetPoint("BOTTOMRIGHT", -8, 24)
    trainersPanel:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8X8",
        edgeFile = "Interface\\Buttons\\WHITE8X8",
        tile = false, edgeSize = 1,
        insets = {left = 0, right = 0, top = 0, bottom = 0}
    })
    trainersPanel:SetBackdropColor(unpack(HDG_UIHelpers.BG_PANEL))
    trainersPanel:SetBackdropBorderColor(unpack(HDG_UIHelpers.BORDER_COLOR))
    trainersPanel:Hide()
    
    -- Title
    local title = trainersPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    title:SetPoint("TOP", 0, -8)
    title:SetShadowOffset(0, 0)  -- Remove text shadow
    title:SetText("|cFFe2e8f0Profession Trainers|r")  -- Cool white to match Recipes tab

    -- Subtitle
    local subtitle = trainersPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    subtitle:SetPoint("TOP", title, "BOTTOM", 0, -2)
    subtitle:SetShadowOffset(0, 0)  -- Remove text shadow
    subtitle:SetText("|cFF888888Click profession to expand/collapse|r")
    
    -- Scroll frame
    local scrollFrame = CreateFrame("ScrollFrame", nil, trainersPanel, "UIPanelScrollFrameTemplate")
    scrollFrame:SetPoint("TOPLEFT", 8, -36)
    scrollFrame:SetPoint("BOTTOMRIGHT", -28, 8)
    trainersPanel.scrollFrame = scrollFrame

    -- Content frame
    local content = CreateFrame("Frame", nil, scrollFrame)
    content:SetSize(scrollFrame:GetWidth(), 1)
    scrollFrame:SetScrollChild(content)
    trainersPanel.content = content

    -- Apply minimalist scrollbar styling
    if HDG_UIHelpers and HDG_UIHelpers.StyleScrollBar then
        HDG_UIHelpers.StyleScrollBar(scrollFrame)
    end

    mainFrame.trainersPanel = trainersPanel
    return trainersPanel
end

-- Refresh the trainers display
function HDG_Trainers:Refresh()
    if not trainersPanel then
        self:CreatePanel()
    end

    local content = trainersPanel.content
    if not content then return end

    -- Clear existing content
    for _, child in ipairs({content:GetChildren()}) do
        child:Hide()
        child:SetParent(nil)
    end
    for _, region in ipairs({content:GetRegions()}) do
        region:Hide()
        region:SetParent(nil)
    end

    -- Get trainer data
    local allTrainerData = HDG_TrainersDB
    if not allTrainerData then
        local emptyText = content:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        emptyText:SetPoint("CENTER", 0, 0)
        emptyText:SetShadowOffset(0, 0)  -- Remove text shadow
        emptyText:SetText("|cFF888888Trainer data not loaded|r")
        content:SetHeight(100)
        return
    end

    -- Get all professions sorted (player's known first, then others)
    local profData = GetAllProfessionsSorted()
    local allProfs = profData.professions
    local knownSet = profData.knownSet

    local contentWidth = trainersPanel.scrollFrame:GetWidth() - 4
    local yOffset = 0

    -- Create section for each profession (all professions, known ones first)
    for _, profName in ipairs(allProfs) do
        local trainerData = allTrainerData[profName]
        if trainerData then
            yOffset = CreateProfessionSection(content, contentWidth, yOffset, profName, trainerData, knownSet[profName])
        end
    end

    -- Update content height
    content:SetHeight(math.abs(yOffset) + 10)

    -- Save collapsed state
    if HDG_Settings then
        HDG_Settings.trainersCollapsed = collapsedProfessions
    end
end

-- Show the panel
function HDG_Trainers:Show()
    if not trainersPanel then
        self:CreatePanel()
    end
    self:Refresh()
    trainersPanel:Show()
end

-- Hide the panel
function HDG_Trainers:Hide()
    if trainersPanel then
        trainersPanel:Hide()
    end
end

-- Check if panel is shown
function HDG_Trainers:IsShown()
    return trainersPanel and trainersPanel:IsShown()
end
