-- ============================================================================
-- HDG_ExpansionData.lua - Centralized Expansion Data Module
-- ============================================================================
-- Single source of truth for all expansion-related data:
-- - Expansion ordering for display
-- - Expansion name normalization
-- - Expansion colors
-- - Expansion abbreviations
-- ============================================================================

HDG_ExpansionData = {}

-- ============================================================================
-- MASTER DATA TABLE (Single Source of Truth)
-- ============================================================================
-- Each expansion defined once with all its properties.
-- All lookup tables are built automatically from this data.
-- aliases: additional names that resolve to this expansion
--
-- IMPORTANT: DO NOT CHANGE the 'abbr' values! They are used as keys in:
--   - HDG_CraftQuotes.lua (profession craft quotes)
--   - HDG_Vamoose.lua (lumber farming quotes)
-- Changing abbreviations will break quote lookups.

-- Localized expansion names from WoW clients:
-- EN=English, DE=German, ES=Spanish, FR=French, IT=Italian, RU=Russian, KO=Korean, ZH=Chinese
local EXPANSION_DATA = {
    { display = "Classic",              api = "Classic",      abbr = "Classic", short = "CLS", color = { 0.6, 0.6, 0.6 } },
    -- TBC: Outland (EN), Scherbenwelt (DE), Terrallende (ES), Outreterre (FR), Terre Esterne (IT)
    { display = "The Burning Crusade",  api = "Outland",      abbr = "TBC",     short = "TBC", color = { 0.4, 0.7, 0.4 },
      apiTags = { "Burning Crusade", "Scherbenwelt", "Terrallende", "Outreterre", "Terre Esterne", "Запределье", "外域", "아웃랜드" } },
    -- WotLK: Northrend (EN), Nordend (DE), Rasganorte (ES), Norfendre (FR), Nordania (IT)
    { display = "Wrath of the Lich King", api = "Northrend",  abbr = "WotLK",   short = "WLK", color = { 0.4, 0.6, 0.8 },
      aliases = { "WotLK", "Nordend", "Rasganorte", "Norfendre", "Nordania", "Нордскол", "诺森德", "노스렌드" } },
    -- Cata: Kataklysmus (DE), Cataclismo (ES/IT/PT)
    { display = "Cataclysm",            api = "Cataclysm",    abbr = "Cata",    short = "CAT", color = { 0.8, 0.5, 0.2 },
      aliases = { "Kataklysmus", "Cataclismo", "Катаклизм", "大地的裂变", "대격변" } },
    -- MoP: Pandaria same in most languages
    { display = "Mists of Pandaria",    api = "Pandaria",     abbr = "MoP",     short = "MOP", color = { 0.3, 0.7, 0.5 },
      aliases = { "MoP", "Пандария", "潘达利亚", "판다리아" } },
    -- WoD: Draenor same in most languages
    { display = "Warlords of Draenor",  api = "Draenor",      abbr = "WoD",     short = "WOD", color = { 0.7, 0.5, 0.3 },
      aliases = { "WoD", "Дренор", "德拉诺", "드레노어" } },
    -- Legion: same in most languages
    { display = "Legion",               api = "Legion",       abbr = "Legion",  short = "LEG", color = { 0.5, 0.9, 0.3 },
      aliases = { "Легион", "军团再临", "군단" } },
    -- BfA: Kul Tiran (Alliance), Zandalari (Horde) - faction-specific profession skill names
    { display = "Battle for Azeroth",   api = "BfA",          abbr = "BfA",     short = "BFA", color = { 0.8, 0.7, 0.2 },
      aliases = { "Kul", "Kul Tiran", "Zandalari", "Kul Tiras", "Культирас", "Зандалари", "库尔提拉斯", "赞达拉", "쿨 티란", "잔달라" } },
    -- SL: Schattenlande (DE), Ombreterre (FR), Tierras Sombrías (ES), Terre Ombrose (IT)
    { display = "Shadowlands",          api = "Shadowlands",  abbr = "SL",      short = "SL",  color = { 0.6, 0.4, 0.8 },
      aliases = { "Schattenlande", "Ombreterre", "Tierras Sombrías", "Terre Ombrose", "Темные Земли", "暗影国度", "어둠땅" } },
    -- DF: Dracheninseln (DE), Islas del Dragón (ES), Îles aux Dragons (FR), Isole dei Draghi (IT)
    { display = "Dragonflight",         api = "Dragon Isles", abbr = "DF",      short = "DF",  color = { 0.2, 0.6, 1.0 },
      aliases = { "Dragon", "Dracheninseln", "Islas del Dragón", "Îles aux Dragons", "Isole dei Draghi", "Драконьи острова", "巨龙群岛", "용의 섬" } },
    -- TWW: Khaz Algar is same in most languages (proper noun)
    { display = "The War Within",       api = "Khaz Algar",   abbr = "TWW",     short = "TWW", color = { 1.0, 0.5, 0.2 },
      aliases = { "Khaz", "Каз'Алгар", "卡兹阿加", "카즈 알가르" } },
    { display = "Midnight",             api = "Midnight",     abbr = "MN",      short = "MN",  color = { 0.6, 0.2, 0.8 } },
}

-- ============================================================================
-- BUILD LOOKUP TABLES (Auto-generated from EXPANSION_DATA)
-- ============================================================================

-- Display name order for UI iteration
HDG_ExpansionData.EXPANSION_ORDER = {}

-- Indexed by any name format -> expansion data
local expansionByName = {}

-- Build all lookups from master data
for i, exp in ipairs(EXPANSION_DATA) do
    exp.order = i
    HDG_ExpansionData.EXPANSION_ORDER[i] = exp.display

    -- Index by all name formats (display, api, abbr)
    expansionByName[exp.display] = exp
    expansionByName[exp.api] = exp
    expansionByName[exp.abbr] = exp

    -- Index by aliases
    if exp.aliases then
        for _, alias in ipairs(exp.aliases) do
            expansionByName[alias] = exp
        end
    end

    -- Index by API tag names (Blizzard uses different names in catalog tags)
    if exp.apiTags then
        for _, apiTag in ipairs(exp.apiTags) do
            expansionByName[apiTag] = exp
        end
    end
end

-- Add unknown fallback
local UNKNOWN_EXPANSION = { display = "Unknown", api = "Unknown", abbr = "???", color = { 0.5, 0.5, 0.5 }, order = 999 }
expansionByName["Unknown"] = UNKNOWN_EXPANSION

-- ============================================================================
-- UTILITY FUNCTIONS
-- ============================================================================

-- Internal: resolve any name format to expansion data
local function resolveExpansion(name)
    if not name then return UNKNOWN_EXPANSION end
    return expansionByName[name] or UNKNOWN_EXPANSION
end

-- Get expansion sort order (works with any name format)
function HDG_ExpansionData.GetSortOrder(expansion)
    return resolveExpansion(expansion).order
end

-- Get expansion color (works with any name format)
function HDG_ExpansionData.GetColor(expansion)
    return resolveExpansion(expansion).color
end

-- Get abbreviation (works with any name format)
function HDG_ExpansionData.GetAbbreviation(expansion)
    return resolveExpansion(expansion).abbr
end

-- Get short name (max 3 chars, works with any name format)
function HDG_ExpansionData.GetShortName(expansion)
    return resolveExpansion(expansion).short
end

-- Get full display name (works with any name format)
function HDG_ExpansionData.GetDisplayName(expansion)
    return resolveExpansion(expansion).display
end

-- Normalize API expansion name to display name for consistent storage
-- Handles faction-specific BfA names (Zandalari/Kul Tiran -> Battle for Azeroth)
-- Handles API names (Dragon Isles -> Dragonflight, Khaz Algar -> The War Within)
function HDG_ExpansionData.NormalizeApiName(apiName)
    return resolveExpansion(apiName).display
end

-- Normalize expansion prefix to full display name
-- Used for converting "Outland Alchemy" -> "The Burning Crusade"
function HDG_ExpansionData.NormalizeToDisplayName(expansion)
    if not expansion then return "Unknown" end

    -- Try direct lookup first
    local resolved = expansionByName[expansion]
    if resolved then return resolved.display end

    -- Extract first word (e.g., "Classic" from "Classic Alchemy")
    local prefix = expansion:match("^([^%s]+)") or expansion
    resolved = expansionByName[prefix]
    if resolved then return resolved.display end

    return "Unknown"
end

-- Get expansion from skill name string
function HDG_ExpansionData.GetExpansionFromSkill(skillName)
    if not skillName then return "Unknown" end

    -- Check each expansion's API name, aliases, and apiTags in the skill string
    for _, exp in ipairs(EXPANSION_DATA) do
        if string.find(skillName, exp.api, 1, true) then
            return exp.display
        end
        -- Check aliases (e.g., "Kul Tiran", "Zandalari" for BfA, "Nordend" for WotLK German)
        if exp.aliases then
            for _, alias in ipairs(exp.aliases) do
                if string.find(skillName, alias, 1, true) then
                    return exp.display
                end
            end
        end
        -- Check apiTags (localized API names like "Scherbenwelt" for German TBC)
        if exp.apiTags then
            for _, tag in ipairs(exp.apiTags) do
                if string.find(skillName, tag, 1, true) then
                    return exp.display
                end
            end
        end
    end

    return "Unknown"
end

-- ============================================================================
-- LEGACY COMPATIBILITY (for existing code that accesses tables directly)
-- ============================================================================

-- Build EXPANSION_SORT_ORDER for any code that accesses it directly
HDG_ExpansionData.EXPANSION_SORT_ORDER = setmetatable({}, {
    __index = function(_, key)
        return resolveExpansion(key).order
    end
})

-- Build EXPANSION_COLORS for any code that accesses it directly
HDG_ExpansionData.EXPANSION_COLORS = setmetatable({}, {
    __index = function(_, key)
        return resolveExpansion(key).color
    end
})

-- Build EXPANSION_ABBR for any code that accesses it directly
HDG_ExpansionData.EXPANSION_ABBR = setmetatable({}, {
    __index = function(_, key)
        return resolveExpansion(key).abbr
    end
})

-- Build EXPANSION_SHORT for any code that accesses it directly (max 3 chars)
HDG_ExpansionData.EXPANSION_SHORT = setmetatable({}, {
    __index = function(_, key)
        return resolveExpansion(key).short
    end
})

-- ============================================================================
-- PROFESSION NAME LOCALIZATION
-- ============================================================================
-- Helper to get localized profession name from our localization table.
-- Uses addon's locale override setting, not just WoW client locale.
-- Falls back to WoW's name if no translation exists.

-- Mapping from English profession name to localization key
local PROF_LOCALE_KEYS = {
    ["All"] = "PROF_ALL",
    ["Alchemy"] = "PROF_ALCHEMY",
    ["Blacksmithing"] = "PROF_BLACKSMITHING",
    ["Cooking"] = "PROF_COOKING",
    ["Enchanting"] = "PROF_ENCHANTING",
    ["Engineering"] = "PROF_ENGINEERING",
    ["Inscription"] = "PROF_INSCRIPTION",
    ["Jewelcrafting"] = "PROF_JEWELCRAFTING",
    ["Leatherworking"] = "PROF_LEATHERWORKING",
    ["Tailoring"] = "PROF_TAILORING",
    ["Herbalism"] = "PROF_HERBALISM",
    ["Mining"] = "PROF_MINING",
    ["Skinning"] = "PROF_SKINNING",
    ["Fishing"] = "PROF_FISHING",
}

-- Cache for WoW API localized profession names
local wowProfessionCache = {}

-- Get localized profession name (uses addon locale override first, then WoW API)
-- @param englishName: English profession name (e.g., "Alchemy")
-- @return Localized name from our table, or WoW API, or English name
function HDG_ExpansionData.GetLocalizedProfessionName(englishName)
    if not englishName then return "Unknown" end

    local L = HDG_L or {}
    local key = PROF_LOCALE_KEYS[englishName]

    -- Check our addon's localization first (respects locale override)
    if key and L[key] then
        return L[key]
    end

    -- Fall back to WoW API localized name
    if not wowProfessionCache[englishName] then
        local skillLineID = HDG_ExpansionData.PROFESSION_IDS[englishName]
        if skillLineID and C_TradeSkillUI and C_TradeSkillUI.GetProfessionInfoBySkillLineID then
            local profInfo = C_TradeSkillUI.GetProfessionInfoBySkillLineID(skillLineID)
            if profInfo and profInfo.professionName then
                wowProfessionCache[englishName] = profInfo.professionName
            end
        end
    end

    if wowProfessionCache[englishName] then
        return wowProfessionCache[englishName]
    end

    -- Final fallback to English name
    return englishName
end

-- ============================================================================
-- PROFESSION DATA (Bidirectional Lookup)
-- ============================================================================

-- Master profession data (single source of truth)
-- Using custom icons with transparent backgrounds (downloaded from Wowhead, processed to remove black corners)
-- Gathering professions use Blizzard icons for now
local PROFESSION_DATA = {
    -- Crafting professions
    { name = "Alchemy",       id = 171, code = "AL", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_alchemy.png" },
    { name = "Blacksmithing", id = 164, code = "BS", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_blacksmithing.png" },
    { name = "Cooking",       id = 185, code = "CK", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_cooking.png" },
    { name = "Enchanting",    id = 333, code = "EN", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_enchanting.png" },
    { name = "Engineering",   id = 202, code = "EG", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_engineering.png" },
    { name = "Inscription",   id = 773, code = "IN", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_inscription.png" },
    { name = "Jewelcrafting", id = 755, code = "JC", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_jewelcrafting.png" },
    { name = "Leatherworking",id = 165, code = "LW", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_leatherworking.png" },
    { name = "Tailoring",     id = 197, code = "TL", icon = "Interface\\AddOns\\HousingDecorGuide\\textures\\professions\\prof_tailoring.png" },
    -- Gathering professions (using Blizzard icons)
    { name = "Herbalism",     id = 182, code = "HB", icon = "Interface\\Icons\\Spell_Nature_NatureTouchGrow" },
    { name = "Mining",        id = 186, code = "MN", icon = "Interface\\Icons\\Trade_Mining" },
    { name = "Skinning",      id = 393, code = "SK", icon = "Interface\\Icons\\INV_Misc_Pelt_Wolf_01" },
}

-- Build lookup tables from master data
HDG_ExpansionData.PROFESSION_IDS = {}    -- Name -> ID
HDG_ExpansionData.PROFESSION_NAMES = {}  -- ID -> Name
HDG_ExpansionData.PROFESSION_CODES = {}  -- Name -> Code (2-letter)
HDG_ExpansionData.PROFESSION_ICONS = {}  -- Name -> Icon path
HDG_ExpansionData.PROFESSION_BY_CODE = {} -- Code -> Name

for _, prof in ipairs(PROFESSION_DATA) do
    HDG_ExpansionData.PROFESSION_IDS[prof.name] = prof.id
    HDG_ExpansionData.PROFESSION_NAMES[prof.id] = prof.name
    HDG_ExpansionData.PROFESSION_CODES[prof.name] = prof.code
    HDG_ExpansionData.PROFESSION_ICONS[prof.name] = prof.icon
    HDG_ExpansionData.PROFESSION_BY_CODE[prof.code] = prof.name
end

-- Get profession ID from name
function HDG_ExpansionData.GetProfessionID(professionName)
    return HDG_ExpansionData.PROFESSION_IDS[professionName]
end

-- Get profession name from skill line ID
function HDG_ExpansionData.GetProfessionName(skillLineID)
    return HDG_ExpansionData.PROFESSION_NAMES[skillLineID]
end

-- Get profession 2-letter code from name
function HDG_ExpansionData.GetProfessionCode(professionName)
    return HDG_ExpansionData.PROFESSION_CODES[professionName] or "??"
end

-- Get profession name from 2-letter code
function HDG_ExpansionData.GetProfessionByCode(code)
    return HDG_ExpansionData.PROFESSION_BY_CODE[code]
end

-- Get profession icon texture path from name
function HDG_ExpansionData.GetProfessionIcon(professionName)
    return HDG_ExpansionData.PROFESSION_ICONS[professionName] or "Interface\\Icons\\INV_Misc_QuestionMark"
end

-- ============================================================================
-- LUMBER DATA (Expansion-specific lumber types)
-- ============================================================================

-- Master lumber data: ordered array (single source of truth)
-- Order matches expansion order for consistent UI display
-- shortName is the material name only (no "Lumber" suffix) for language-neutral display
local LUMBER_DATA = {
    { id = 245586, name = "Ironwood Lumber",     shortName = "Ironwood",    expansion = "Classic" },
    { id = 242691, name = "Olemba Lumber",       shortName = "Olemba",      expansion = "The Burning Crusade" },
    { id = 251762, name = "Coldwind Lumber",     shortName = "Coldwind",    expansion = "Wrath of the Lich King" },
    { id = 251764, name = "Ashwood Lumber",      shortName = "Ashwood",     expansion = "Cataclysm" },
    { id = 251763, name = "Bamboo Lumber",       shortName = "Bamboo",      expansion = "Mists of Pandaria" },
    { id = 251766, name = "Shadowmoon Lumber",   shortName = "Shadowmoon",  expansion = "Warlords of Draenor" },
    { id = 251767, name = "Fel-Touched Lumber",  shortName = "Fel-Touched", expansion = "Legion" },
    { id = 251768, name = "Darkpine Lumber",     shortName = "Darkpine",    expansion = "Battle for Azeroth" },
    { id = 251772, name = "Arden Lumber",        shortName = "Arden",       expansion = "Shadowlands" },
    { id = 251773, name = "Dragonpine Lumber",   shortName = "Dragonpine",  expansion = "Dragonflight" },
    { id = 248012, name = "Dornic Fir Lumber",   shortName = "Dornic Fir",  expansion = "The War Within" },
    { id = 256963, name = "Thalassian Lumber",   shortName = "Thalassian",  expansion = "Midnight" },
}

-- Build lookup tables from master data
HDG_ExpansionData.LUMBER_ORDER = {}  -- IDs in expansion order
HDG_ExpansionData.LUMBER_TYPES = {}  -- ID -> {name, expansion}
HDG_ExpansionData.LUMBER_IDS = {}    -- ID -> true (quick lookup)

for _, lumber in ipairs(LUMBER_DATA) do
    HDG_ExpansionData.LUMBER_ORDER[#HDG_ExpansionData.LUMBER_ORDER + 1] = lumber.id
    HDG_ExpansionData.LUMBER_TYPES[lumber.id] = { name = lumber.name, shortName = lumber.shortName, expansion = lumber.expansion }
    HDG_ExpansionData.LUMBER_IDS[lumber.id] = true
end

-- Check if an item ID is lumber
function HDG_ExpansionData.IsLumber(itemID)
    return HDG_ExpansionData.LUMBER_IDS[itemID] == true
end

-- Get lumber info by item ID
function HDG_ExpansionData.GetLumberInfo(itemID)
    return HDG_ExpansionData.LUMBER_TYPES[itemID]
end

-- Lumber/wood words to strip from localized names (various languages)
-- Patterns are applied in order: prefixes first, then suffixes
local LUMBER_WORD_PATTERNS = {
    -- Prefix patterns (word at start, strip with following space/preposition)
    -- More specific patterns (with preposition) must come before simpler ones
    "^Madeira%s+de%s+",     -- Portuguese: "Madeira de X"
    "^Madeira%s+",          -- Portuguese: "Madeira X" (without de)
    "^Madera%s+de%s+",      -- Spanish: "Madera de X"
    "^Madera%s+",           -- Spanish: "Madera X" (without de)
    "^Bois%s+d'",           -- French: "Bois d'X"
    "^Bois%s+de%s+",        -- French: "Bois de X"
    "^Bois%s+",             -- French: "Bois X" (without de)
    "^Legname%s+di%s+",     -- Italian: "Legname di X" (alternate word)
    "^Legname%s+",          -- Italian: "Legname X"
    "^Legno%s+di%s+",       -- Italian: "Legno di X"
    "^Legno%s+",            -- Italian: "Legno X" (without di)
    "^Holz%s+von%s+",       -- German: "Holz von X"
    "^Holz%s+",             -- German: "Holz X"
    "^Bauholz%s+",          -- German: "Bauholz X" (construction wood)
    "^Древесина%s+",        -- Russian: "Древесина X"
    "^Пиломатериалы%s+",    -- Russian: "Пиломатериалы X" (lumber)
    "^목재%s*",              -- Korean: "목재 X" or "목재X"
    "^木材%s*",              -- Chinese: "木材 X" or "木材X"
    -- Suffix patterns (word at end)
    "%s+Lumber$",           -- English: "X Lumber"
    "%s+Wood$",             -- English: "X Wood"
    "%-Holz$",              -- German: "X-Holz"
    "[Hh]olz$",             -- German: "Xholz" (compound)
    "%-[Bb]auholz$",        -- German: "X-Bauholz"
    "%s+목재$",              -- Korean: "X 목재"
    "목재$",                 -- Korean: "X목재" (no space)
    "%s*木材$",              -- Chinese: "X木材" or "X 木材"
    "%s+древесина$",        -- Russian: "X древесина"
    "%s+Madera$",           -- Spanish suffix form
    "%s+Madeira$",          -- Portuguese suffix form
    "%s+Bois$",             -- French suffix form
    "%s+Legno$",            -- Italian suffix form
    "%s+Legname$",          -- Italian suffix form (alternate)
}

-- Extract just the material name from a localized lumber name
-- e.g., "Ironwood Lumber" -> "Ironwood", "Madeira de Xiloferrea" -> "Xiloferrea"
function HDG_ExpansionData.GetLumberMaterialName(lumberId)
    if not lumberId then return nil end

    -- Get the localized name from WoW API
    local localizedName = C_Item and C_Item.GetItemNameByID(lumberId)
    if not localizedName then
        -- Fallback to English shortName if API not ready
        local info = HDG_ExpansionData.LUMBER_TYPES[lumberId]
        return info and info.shortName or nil
    end

    -- Apply patterns to strip lumber/wood words
    local materialName = localizedName
    for _, pattern in ipairs(LUMBER_WORD_PATTERNS) do
        local stripped = materialName:gsub(pattern, "")
        if stripped ~= materialName then
            materialName = stripped
            break  -- Only apply first matching pattern
        end
    end

    -- Trim any remaining whitespace
    materialName = materialName:match("^%s*(.-)%s*$")

    -- Capitalize first letter (handles lowercase after stripping prefix like "Madera xiloférrea" -> "Xiloférrea")
    if materialName and #materialName > 0 then
        materialName = materialName:sub(1, 1):upper() .. materialName:sub(2)
    end

    -- If nothing was stripped, return the full name (unknown language pattern)
    return materialName ~= "" and materialName or localizedName
end

-- ============================================================================
-- BOP GATHERED REAGENTS (not tradeable, exclude from cost calculations)
-- ============================================================================

-- BoP gathered items that can't be bought on AH
HDG_ExpansionData.BOP_REAGENT_IDS = {
    [120945] = true,  -- Primal Spirit (WoD)
}

-- Check if an item ID is a BoP gathered reagent
function HDG_ExpansionData.IsBoPReagent(itemID)
    -- Check lumber first
    if HDG_ExpansionData.LUMBER_IDS[itemID] then
        return true
    end
    -- Check other BoP reagents
    return HDG_ExpansionData.BOP_REAGENT_IDS[itemID] == true
end
