-- UI/WarBoard_MapOverlay.lua
-- Draws bounty targets on the world map (HereBeDragons-Pins), one icon per target.
-- World coordinates arrive from WB.BountyTracker; HBDPins places them on whatever
-- map/zoom the viewer is looking at. Icon art = the target's faction + bounty rank.

local addonName, WB = ...

WB.MapOverlay = WB.MapOverlay or {}
local Overlay = WB.MapOverlay

local HBDPins = LibStub and LibStub("HereBeDragons-Pins-2.0", true)

local targets     = {}    -- [targetGuid] = { worldX, worldY, iID, name, faction, rank, shard, rxAt }
local TARGET_STALE = 130   -- ~3 missed 45s broadcasts before the icon drops

-- Faction + rank → icon atlas (No rank = the faction crest; ranks 1-3 = Warfront waves).
local ICON_ATLAS = {
    Horde = {
        [0] = "HordeSymbol",
        [1] = "Warfront-HordeWave1", [2] = "Warfront-HordeWave2", [3] = "Warfront-HordeWave3",
    },
    Alliance = {
        [0] = "AllianceSymbol",
        [1] = "Warfront-AllianceWave1", [2] = "Warfront-AllianceWave2", [3] = "Warfront-AllianceWave3",
    },
}
local function IconAtlas(faction, rank)
    local set = ICON_ATLAS[faction] or ICON_ATLAS.Horde
    return set[rank or 0] or set[0]
end

-- ── Icon pool ──────────────────────────────────────────────────────────────────────
local pool = {}
local function GetIcon(idx)
    if pool[idx] then return pool[idx] end
    local icon = CreateFrame("Frame", nil, UIParent)
    icon:SetSize(22, 22)
    icon:EnableMouse(true)
    icon.tex = icon:CreateTexture(nil, "ARTWORK")
    icon.tex:SetAllPoints()
    icon.label = icon:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    icon.label:SetPoint("TOP", icon, "BOTTOM", 0, -1)
    icon.label:SetTextColor(1, 0.35, 0.30)
    icon:SetScript("OnEnter", function(self)
        if not self.tipTitle then return end
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        GameTooltip:SetText(self.tipTitle, 1, 0.82, 0.2)
        if self.tipBody then GameTooltip:AddLine(self.tipBody, 0.8, 0.8, 0.8) end
        GameTooltip:Show()
    end)
    icon:SetScript("OnLeave", function() GameTooltip:Hide() end)
    pool[idx] = icon
    return icon
end

-- ── Refresh (place all live target icons) ───────────────────────────────────────────
function Overlay:Refresh()
    if not HBDPins then return end
    if not WorldMapFrame or not WorldMapFrame:IsShown() then return end
    HBDPins:RemoveAllWorldMapIcons("WarBoard")

    local now, idx = time(), 0
    for guid, t in pairs(targets) do
        if t.worldX and t.worldY and t.iID and (now - (t.rxAt or 0)) < TARGET_STALE then
            idx = idx + 1
            local icon = GetIcon(idx)
            icon.tex:SetAtlas(IconAtlas(t.faction, t.rank))
            local short = t.name and (t.name:match("^([^%-]+)") or t.name) or "Bounty"
            short = (WB.SanitizeDisplay and WB.SanitizeDisplay(short, 24)) or short   -- wire name → sanitize
            icon.label:SetText(short)
            local ageS = now - (t.rxAt or now)
            icon.tipTitle = "|cffff4040Bounty:|r " .. short
            local shard = t.shard and ((WB.SanitizeDisplay and WB.SanitizeDisplay(tostring(t.shard), 12)) or tostring(t.shard))
            icon.tipBody  = (shard and ("Shard " .. shard .. "  •  ") or "") .. "seen " .. math.floor(ageS) .. "s ago"
            HBDPins:AddWorldMapIconWorld("WarBoard", icon, t.iID, t.worldX, t.worldY,
                HBD_PINS_WORLDMAP_SHOW_CONTINENT)
        end
    end
end

-- ── Public API (called by WB.BountyTracker) ─────────────────────────────────────────
function Overlay:UpdateTarget(data)
    if type(data) ~= "table" or not data.targetGuid then return end
    targets[data.targetGuid] = {
        worldX = data.worldX, worldY = data.worldY, iID = data.iID,
        name = data.targetName, faction = data.faction, rank = data.rank,
        shard = data.shard, rxAt = time(),
    }
    if WorldMapFrame and WorldMapFrame:IsShown() then self:Refresh() end
end

function Overlay:RemoveTarget(guid)
    if guid then targets[guid] = nil else wipe(targets) end
    if WorldMapFrame and WorldMapFrame:IsShown() then self:Refresh() end
end

function Overlay:Purge()
    local now = time()
    for guid, t in pairs(targets) do
        if (now - (t.rxAt or 0)) >= TARGET_STALE then targets[guid] = nil end
    end
end

-- ── Hooks ──────────────────────────────────────────────────────────────────────────
if WorldMapFrame then
    WorldMapFrame:HookScript("OnShow", function() Overlay:Refresh() end)
    if WorldMapFrame.RegisterCallback then
        WorldMapFrame:RegisterCallback("MapChanged", function() Overlay:Refresh() end, Overlay)
    end
end

C_Timer.NewTicker(1, function()
    if WorldMapFrame and WorldMapFrame:IsShown() then Overlay:Refresh() end
end)
C_Timer.NewTicker(30, function() Overlay:Purge() end)
