--------------------------------------------------------------------------------
-- Nanami-UI: Zone Level Range Module (ZoneLevelRange.lua)
-- Displays zone level ranges, territory status, instances and raids
-- on the world map continent view using Nanami-themed tooltip.
-- Self-contained data; supersedes LevelRange-Turtle's display.
--------------------------------------------------------------------------------

SFrames = SFrames or {}
SFrames.ZoneLevelRange = {}
local ZLR = SFrames.ZoneLevelRange

--------------------------------------------------------------------------------
-- Locale helper
--------------------------------------------------------------------------------
local isZH = (GetLocale() == "zhCN")
local function N(en, zh) return isZH and zh or en end

--------------------------------------------------------------------------------
-- Faction constants
--------------------------------------------------------------------------------
local F_A = "Alliance"
local F_H = "Horde"
local F_C = "Contested"

--------------------------------------------------------------------------------
-- Zone Level Ranges: [localizedName] = { min, max, factionType }
--------------------------------------------------------------------------------
local ZONE_RANGES = {
    -- Eastern Kingdoms
    [N("Elwynn Forest",       "艾尔文森林")]       = {  1, 10, F_A },
    [N("Dun Morogh",          "丹莫罗")]           = {  1, 10, F_A },
    [N("Tirisfal Glades",     "提瑞斯法林地")]     = {  1, 10, F_H },
    [N("Loch Modan",          "洛克莫丹")]         = { 10, 20, F_A },
    [N("Silverpine Forest",   "银松森林")]         = { 10, 20, F_H },
    [N("Westfall",            "西部荒野")]         = { 10, 20, F_A },
    [N("Redridge Mountains",  "赤脊山")]           = { 15, 25, F_C },
    [N("Duskwood",            "暮色森林")]         = { 18, 30, F_C },
    [N("Hillsbrad Foothills", "希尔斯布莱德丘陵")] = { 20, 30, F_C },
    [N("Wetlands",            "湿地")]             = { 20, 30, F_C },
    [N("Alterac Mountains",   "奥特兰克山脉")]     = { 30, 40, F_C },
    [N("Arathi Highlands",    "阿拉希高地")]       = { 30, 40, F_C },
    [N("Stranglethorn Vale",  "荆棘谷")]           = { 30, 45, F_C },
    [N("Badlands",            "荒芜之地")]         = { 35, 45, F_C },
    [N("Swamp of Sorrows",    "悲伤沼泽")]         = { 35, 45, F_C },
    [N("The Hinterlands",     "辛特兰")]           = { 40, 50, F_C },
    [N("Searing Gorge",       "灼热峡谷")]         = { 43, 50, F_C },
    [N("Blasted Lands",       "诅咒之地")]         = { 45, 55, F_C },
    [N("Burning Steppes",     "燃烧平原")]         = { 50, 58, F_C },
    [N("Western Plaguelands", "西瘟疫之地")]       = { 51, 58, F_C },
    [N("Eastern Plaguelands", "东瘟疫之地")]       = { 53, 60, F_C },
    [N("Deadwind Pass",       "逆风小径")]         = { 55, 60, F_C },

    -- Kalimdor
    [N("Durotar",              "杜隆塔尔")]         = {  1, 10, F_H },
    [N("Mulgore",              "莫高雷")]           = {  1, 10, F_H },
    [N("Teldrassil",           "泰达希尔")]         = {  1, 10, F_A },
    [N("Darkshore",            "黑海岸")]           = { 10, 20, F_A },
    [N("The Barrens",          "贫瘠之地")]         = { 10, 25, F_H },
    [N("Stonetalon Mountains", "石爪山脉")]         = { 15, 27, F_C },
    [N("Ashenvale",            "灰谷")]             = { 18, 30, F_C },
    [N("Thousand Needles",     "千针石林")]         = { 25, 35, F_C },
    [N("Desolace",             "凄凉之地")]         = { 30, 40, F_C },
    [N("Dustwallow Marsh",     "尘泥沼泽")]         = { 35, 45, F_C },
    [N("Feralas",              "菲拉斯")]           = { 40, 50, F_C },
    [N("Tanaris",              "塔纳利斯")]         = { 40, 50, F_C },
    [N("Azshara",              "艾萨拉")]           = { 45, 55, F_C },
    [N("Felwood",              "费伍德森林")]       = { 48, 55, F_C },
    [N("Un'Goro Crater",       "安戈洛环形山")]     = { 48, 55, F_C },
    [N("Silithus",             "希利苏斯")]         = { 55, 60, F_C },
    [N("Winterspring",         "冬泉谷")]           = { 55, 60, F_C },
    [N("Moonglade",            "月光林地")]         = {  1, 60, F_C },

    -- Turtle WoW
    [N("Thalassian Highlands", "阿尔萨拉斯")]       = {  1, 10, F_A },
    [N("Blackstone Island",    "黑石岛")]           = {  1, 10, F_H },
    [N("Gilneas",              "吉尔尼斯")]         = { 39, 46, F_C },
    [N("Gillijim's Isle",      "吉利吉姆之岛")]     = { 48, 53, F_C },
    [N("Lapidis Isle",         "拉匹迪斯之岛")]     = { 48, 53, F_C },
    [N("Tel'Abim",             "泰拉比姆")]         = { 54, 60, F_C },
    [N("Scarlet Enclave",      "东瘟疫之地：血色领地")] = { 55, 60, F_C },
    [N("Hyjal",                "海加尔山")]         = { 58, 60, F_C },
    [N("Grim Reaches",         "冷酷海岸")]         = { 33, 38, F_C },
    [N("Northwind",            "北风领")]           = { 28, 34, F_C },
    [N("Balor",                "巴洛")]             = { 29, 34, F_C },
    [N("Moonsong Coast",       "月语海岸")]         = { 53, 58, F_C },
}

--------------------------------------------------------------------------------
-- Instances: [zoneName] = { { instanceName, levelString }, ... }
--------------------------------------------------------------------------------
local ZONE_INSTANCES = {
    [N("Westfall",            "西部荒野")]         = { { N("Deadmines",            "死亡矿井"),    "17-26" } },
    [N("The Barrens",         "贫瘠之地")]         = { { N("Wailing Caverns",      "哀嚎洞穴"),    "17-24" },
                                                        { N("Razorfen Kraul",       "剃刀高地"),    "25-30" },
                                                        { N("Razorfen Downs",       "剃刀沼泽"),    "33-45" } },
    [N("Silverpine Forest",   "银松森林")]         = { { N("Shadowfang Keep",      "影牙城堡"),    "22-30" } },
    [N("Dun Morogh",          "丹莫罗")]           = { { N("Gnomeregan",           "诺莫瑞根"),    "29-38" } },
    [N("Tirisfal Glades",     "提瑞斯法林地")]     = { { N("The Scarlet Monastery","血色修道院"),   "34-45" } },
    [N("Badlands",            "荒芜之地")]         = { { N("Uldaman",              "奥达曼"),      "35-47" } },
    [N("Desolace",            "凄凉之地")]         = { { N("Maraudon",             "玛拉顿"),      "46-55" } },
    [N("Swamp of Sorrows",    "悲伤沼泽")]         = { { N("The Sunken Temple",    "沉没的神庙"),   "45-55" } },
    [N("Searing Gorge",       "灼热峡谷")]         = { { N("Blackrock Depths",     "黑石深渊"),    "52-60" },
                                                        { N("Blackrock Spire",      "黑石塔"),      "58-60" } },
    [N("Eastern Plaguelands", "东瘟疫之地")]       = { { N("Stratholme",           "斯坦索姆"),    "58-60" } },
    [N("Feralas",             "菲拉斯")]           = { { N("Dire Maul",            "厄运之槌"),    "55-60" } },
    [N("Western Plaguelands", "西瘟疫之地")]       = { { N("Scholomance",          "通灵学院"),    "57-60" } },
    [N("Durotar",             "杜隆塔尔")]         = { { N("Ragefire Chasm",       "怒焰裂谷"),    "13-18" } },
    [N("Ashenvale",           "灰谷")]             = { { N("Blackfathom Deeps",    "黑暗深渊"),    "24-32" },
                                                        { N("The Crescent Grove",   "新月林地"),    "32-38" } },
    [N("Gilneas",             "吉尔尼斯")]         = { { N("Gilneas City",         "吉尔尼斯城"),  "43-49" } },
    [N("Burning Steppes",     "燃烧平原")]         = { { N("Hateforge Quarry",     "仇恨熔炉采石场"), "52-60" },
                                                        { N("Blackrock Depths",     "黑石深渊"),    "52-60" },
                                                        { N("Blackrock Spire",      "黑石塔"),      "58-60" } },
    [N("Deadwind Pass",       "逆风小径")]         = { { N("Karazhan Crypt",       "卡拉赞地穴"),  "58-60" } },
    [N("Elwynn Forest",       "艾尔文森林")]       = { { N("The Stockades",        "监狱"),        "24-32" },
                                                        { N("Stormwind Vault",      "暴风城地窖"),  "60+" } },
    [N("Tanaris",             "塔纳利斯")]         = { { N("Zul'Farrak",           "祖尔法拉克"),  "44-54" },
                                                        { N("Caverns of Time: The Black Morass", "时光之穴：黑色沼泽"), "60+" } },
    [N("Balor",               "巴洛")]             = { { N("Stormwrought Ruins",   "风暴废墟"),    "35-41" } },
    [N("Wetlands",            "湿地")]             = { { N("Dragonmaw Retreat",    "龙喉要塞"),    "27-33" } },
    [N("Moonsong Coast",      "月语海岸")]         = { { N("Timbermaw Hold",       "木喉要塞"),    "60+" } },
}

--------------------------------------------------------------------------------
-- Raids
--------------------------------------------------------------------------------
local ZONE_RAIDS = {
    [N("Eastern Plaguelands", "东瘟疫之地")]       = { { N("Naxxramas",            "纳克萨玛斯"),  "60+" } },
    [N("Dustwallow Marsh",    "尘泥沼泽")]         = { { N("Onyxia's Lair",        "奥妮克希亚的巢穴"), "60+" } },
    [N("Silithus",            "希利苏斯")]         = { { N("Ruins of Ahn'Qiraj",   "安其拉废墟"),  "60+" },
                                                        { N("Temple of Ahn'Qiraj",  "安其拉神庙"),  "60+" } },
    [N("Stranglethorn Vale",  "荆棘谷")]           = { { N("Zul'Gurub",            "祖尔格拉布"),  "60+" } },
    [N("Hyjal",               "海加尔山")]         = { { N("Emerald Sanctum",      "翡翠圣所"),    "60+" } },
    [N("Deadwind Pass",       "逆风小径")]         = { { N("Lower Karazhan Halls", "下层卡拉赞大厅"), "60+" } },
}

--------------------------------------------------------------------------------
-- Fishing Level Requirements
--------------------------------------------------------------------------------
local ZONE_FISHING = {
    [N("Elwynn Forest",       "艾尔文森林")]       = 25,
    [N("Dun Morogh",          "丹莫罗")]           = 25,
    [N("Tirisfal Glades",     "提瑞斯法林地")]     = 25,
    [N("Loch Modan",          "洛克莫丹")]         = 75,
    [N("Silverpine Forest",   "银松森林")]         = 75,
    [N("Westfall",            "西部荒野")]         = 75,
    [N("Redridge Mountains",  "赤脊山")]           = 150,
    [N("Duskwood",            "暮色森林")]         = 150,
    [N("Hillsbrad Foothills", "希尔斯布莱德丘陵")] = 150,
    [N("Wetlands",            "湿地")]             = 150,
    [N("Alterac Mountains",   "奥特兰克山脉")]     = 225,
    [N("Arathi Highlands",    "阿拉希高地")]       = 225,
    [N("Stranglethorn Vale",  "荆棘谷")]           = 225,
    [N("Swamp of Sorrows",    "悲伤沼泽")]         = 225,
    [N("The Hinterlands",     "辛特兰")]           = 300,
    [N("Western Plaguelands", "西瘟疫之地")]       = 300,
    [N("Durotar",             "杜隆塔尔")]         = 25,
    [N("Mulgore",             "莫高雷")]           = 25,
    [N("Teldrassil",          "泰达希尔")]         = 25,
    [N("Darkshore",           "黑海岸")]           = 75,
    [N("The Barrens",         "贫瘠之地")]         = 75,
    [N("Stonetalon Mountains","石爪山脉")]         = 150,
    [N("Ashenvale",           "灰谷")]             = 150,
    [N("Thousand Needles",    "千针石林")]         = 225,
    [N("Desolace",            "凄凉之地")]         = 225,
    [N("Dustwallow Marsh",    "尘泥沼泽")]         = 225,
    [N("Feralas",             "菲拉斯")]           = 300,
    [N("Tanaris",             "塔纳利斯")]         = 300,
    [N("Azshara",             "艾萨拉")]           = 300,
    [N("Felwood",             "费伍德森林")]       = 300,
    [N("Un'Goro Crater",      "安戈洛环形山")]     = 300,
    [N("Moonglade",           "月光林地")]         = 300,
}

--------------------------------------------------------------------------------
-- Sub-zone -> Parent Zone Mapping
--------------------------------------------------------------------------------
local ZONE_SUBZONES = {
    [N("Orgrimmar",       "奥格瑞玛")]     = N("Durotar",              "杜隆塔尔"),
    [N("Thunder Bluff",   "雷霆崖")]       = N("Mulgore",              "莫高雷"),
    [N("Undercity",       "幽暗城")]       = N("Tirisfal Glades",      "提瑞斯法林地"),
    [N("Ironforge",       "铁炉堡")]       = N("Dun Morogh",           "丹莫罗"),
    [N("Stormwind City",  "暴风城")]       = N("Elwynn Forest",        "艾尔文森林"),
    [N("Darnassus",       "达纳苏斯")]     = N("Teldrassil",           "泰达希尔"),
    [N("Alah'Thalas",     "萨拉斯高地")]   = N("Thalassian Highlands", "阿尔萨拉斯"),
}

--------------------------------------------------------------------------------
-- Display strings & colors
--------------------------------------------------------------------------------
local S_LEVELS    = N("Level %d-%d",         "等级 %d-%d")
local S_FISHING   = N("Fishing Level %d",    "钓鱼等级 %d")
local S_INSTANCES = N("Instances:",          "地下城:")
local S_RAIDS     = N("Raids:",              "团队副本:")
local S_FRIENDLY  = N("Friendly Territory",  "友好领土")
local S_HOSTILE   = N("Hostile Territory",   "敌对领土")
local S_CONTESTED = N("Contested Territory", "争夺中的领土")

local COLORS = {
    friendly  = { 0.20, 0.90, 0.20 },
    hostile   = { 0.90, 0.20, 0.20 },
    contested = { 0.80, 0.60, 0.40 },
    levels    = { 0.80, 0.60, 0.00 },
    header    = { 1.00, 0.84, 0.00 },
    instance  = { 0.81, 0.81, 0.81 },
    fishing   = { 0.50, 0.70, 0.90 },
}

--------------------------------------------------------------------------------
-- Tooltip frame & display logic
--------------------------------------------------------------------------------
local zlrTT
local zlrCurrentZone, zlrCurrentArea
local zlrOldUpdate

local function CreateZLRTooltip()
    if zlrTT then return end
    zlrTT = CreateFrame("GameTooltip", "NanamiZoneLevelTT", UIParent, "GameTooltipTemplate")
    zlrTT:SetFrameStrata("TOOLTIP")
    zlrTT:SetFrameLevel(255)
end

local function StyleTooltip()
    if not zlrTT then return end
    local _A = SFrames.ActiveTheme
    if not _A then return end
    zlrTT:SetBackdrop({
        bgFile   = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 14,
        insets = { left = 3, right = 3, top = 3, bottom = 3 },
    })
    zlrTT:SetBackdropColor(_A.panelBg[1], _A.panelBg[2], _A.panelBg[3], _A.panelBg[4] or 0.95)
    zlrTT:SetBackdropBorderColor(_A.panelBorder[1], _A.panelBorder[2], _A.panelBorder[3], _A.panelBorder[4] or 1)
end

local function UpdateZLRTooltip(zoneName)
    if not zlrTT then return end

    if not zoneName or zoneName == "" then
        zlrTT:Hide()
        return
    end

    local data = ZONE_RANGES[zoneName]
    if not data then
        zlrTT:Hide()
        return
    end

    zlrTT:SetOwner(UIParent, "ANCHOR_NONE")
    zlrTT:ClearAllPoints()
    if WorldMapDetailFrame then
        zlrTT:SetPoint("BOTTOMLEFT", WorldMapDetailFrame, "BOTTOMLEFT", 2, 2)
    end

    local minLv, maxLv, faction = data[1], data[2], data[3]

    zlrTT:SetText(zoneName, 1, 1, 1)

    local lvStr = string.format(S_LEVELS, minLv, maxLv)
    zlrTT:AddLine(lvStr, COLORS.levels[1], COLORS.levels[2], COLORS.levels[3])

    local _, playerFaction = UnitFactionGroup("player")
    local territoryText, territoryColor
    if faction == F_C then
        territoryText = S_CONTESTED
        territoryColor = COLORS.contested
    elseif playerFaction == faction then
        territoryText = S_FRIENDLY
        territoryColor = COLORS.friendly
    else
        territoryText = S_HOSTILE
        territoryColor = COLORS.hostile
    end
    zlrTT:AddLine(territoryText, territoryColor[1], territoryColor[2], territoryColor[3])

    local instances = ZONE_INSTANCES[zoneName]
    if instances then
        zlrTT:AddLine(" ")
        zlrTT:AddLine(S_INSTANCES, COLORS.header[1], COLORS.header[2], COLORS.header[3])
        for _, inst in ipairs(instances) do
            local iName, iLevels = inst[1], inst[2]
            zlrTT:AddDoubleLine(
                iName, "(" .. iLevels .. ")",
                COLORS.instance[1], COLORS.instance[2], COLORS.instance[3],
                COLORS.instance[1], COLORS.instance[2], COLORS.instance[3]
            )
        end
    end

    local raids = ZONE_RAIDS[zoneName]
    if raids then
        zlrTT:AddLine(" ")
        zlrTT:AddLine(S_RAIDS, COLORS.header[1], COLORS.header[2], COLORS.header[3])
        for _, raid in ipairs(raids) do
            local rName, rLevels = raid[1], raid[2]
            zlrTT:AddDoubleLine(
                rName, "(" .. rLevels .. ")",
                COLORS.instance[1], COLORS.instance[2], COLORS.instance[3],
                COLORS.instance[1], COLORS.instance[2], COLORS.instance[3]
            )
        end
    end

    local fishLv = ZONE_FISHING[zoneName]
    if fishLv then
        zlrTT:AddLine(" ")
        zlrTT:AddLine(string.format(S_FISHING, fishLv), COLORS.fishing[1], COLORS.fishing[2], COLORS.fishing[3])
    end

    StyleTooltip()
    zlrTT:Show()
end

--------------------------------------------------------------------------------
-- Hook WorldMapButton_OnUpdate
--------------------------------------------------------------------------------
local function HookWorldMapUpdate()
    zlrOldUpdate = WorldMapButton_OnUpdate
    WorldMapButton_OnUpdate = function(a1)
        if zlrOldUpdate then zlrOldUpdate(a1) end

        local areaNameRaw = WorldMapFrame and WorldMapFrame.areaName or ""
        local _, _, trimmed = string.find(areaNameRaw, "^%s*(.-)%s*$")
        if not trimmed then trimmed = areaNameRaw end
        local zoneNum = GetCurrentMapZone and GetCurrentMapZone() or -1

        if ZONE_SUBZONES[trimmed] then
            trimmed = ZONE_SUBZONES[trimmed]
        end

        if zoneNum == zlrCurrentZone and areaNameRaw == zlrCurrentArea then
            return
        end
        zlrCurrentZone = zoneNum
        zlrCurrentArea = areaNameRaw

        if zoneNum == 0 then
            UpdateZLRTooltip(trimmed)
        else
            UpdateZLRTooltip(nil)
        end
    end
end

--------------------------------------------------------------------------------
-- Suppress LevelRange-Turtle's original tooltip
--------------------------------------------------------------------------------
local function SuppressLevelRangeTooltip()
    local _G = getfenv(0)
    if _G["LevelRangeTooltip"] then
        _G["LevelRangeTooltip"]:Hide()
        _G["LevelRangeTooltip"].Show = function(self) self:Hide() end
    end
end

--------------------------------------------------------------------------------
-- Hook WorldMapFrame hide to dismiss tooltip
--------------------------------------------------------------------------------
local function HookMapHide()
    if not WorldMapFrame then return end
    local prevOnHide = WorldMapFrame:GetScript("OnHide")
    WorldMapFrame:SetScript("OnHide", function(a1,a2,a3,a4,a5)
        if prevOnHide then prevOnHide(a1,a2,a3,a4,a5) end
        if zlrTT then zlrTT:Hide() end
        zlrCurrentZone = nil
        zlrCurrentArea = nil
    end)
end

--------------------------------------------------------------------------------
-- Initialize
--------------------------------------------------------------------------------
function ZLR:Initialize()
    local wmCfg = SFramesDB and SFramesDB.WorldMap
    if wmCfg and wmCfg.enabled == false then return end

    CreateZLRTooltip()
    HookWorldMapUpdate()
    HookMapHide()
    SuppressLevelRangeTooltip()

    self.initialized = true
end
