-- Frame Setup
local AnnounceFrame = CreateFrame("Frame")
AnnounceFrame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
AnnounceFrame:RegisterEvent("CHAT_MSG_ADDON")
AnnounceFrame:RegisterEvent("ZONE_CHANGED_NEW_AREA")

-- Constants
local ANNOUNCEMENT_PREFIX = "BlackBoxCrate"
local HONOR_CURRENCY_ID = 1602

local zoneMapIDs = {
    ["Azj%-Kahet"]          = 2255,
    ["Siren Isle"]          = 2369,
    ["Isle of Dorn"]        = 2248,
    ["Ringing Deeps"]       = 2214,
    ["The Ringing Deeps"]   = 2214,
    ["Hallowfall"]          = 2215,
    ["Undermine"]           = 2346,
}

local zoneNameRemap = {
    ["City of Threads"]         = "Azj-Kahet",
    ["City of Threads - Lower"] = "Azj-Kahet",
    ["Slam Central Station"]    = "Undermine"
}

local knownCrateZoneIDs = {
    [2255] = true, -- Azj-Kahet
    [2369] = true, -- Siren Isle
    [2248] = true, -- Isle of Dorn
    [2214] = true, -- Ringing Deeps
    [2215] = true, -- Hallowfall
    [2346] = true, -- Undermine
}

-- State
local hasAnnounced = {}
local currentMapID = nil

-- Register Addon Prefix
C_ChatInfo.RegisterAddonMessagePrefix(ANNOUNCEMENT_PREFIX)

-- Utilities

local function GetZoneInfo()
    local mapID = C_Map.GetBestMapForUnit("player")
    if not mapID then return 0, "Unknown Zone", 0, 0 end

    local pos = C_Map.GetPlayerMapPosition(mapID, "player")
    if not pos then return mapID, "Unknown Zone", 0, 0 end

    local info = C_Map.GetMapInfo(mapID)
    local zoneName = info and info.name or "Unknown Zone"

    -- Apply remap for subzones
    zoneName = zoneNameRemap[zoneName] or zoneName

    return mapID, zoneName, pos.x * 100, pos.y * 100
end

local function SendCrateAnnouncement(zoneName, x, y)
    local msg = string.format("War Supply Chest opened in %s (%.1f,%.1f)", zoneName, x, y)
    local channel = IsInRaid() and "RAID" or "PARTY"

    if IsInGroup() or IsInRaid() then
        if C_ChatInfo.IsAddonMessagePrefixRegistered(ANNOUNCEMENT_PREFIX) then
            C_ChatInfo.SendAddonMessage(ANNOUNCEMENT_PREFIX, zoneName, channel)
        end
        SendChatMessage(msg, channel)
    end
end

-- Event Handler

AnnounceFrame:SetScript("OnEvent", function(_, event, arg1, arg2)
    if event == "CURRENCY_DISPLAY_UPDATE" then
        local currencyID = arg1
        if currencyID ~= HONOR_CURRENCY_ID then return end

        local mapID, zoneName, x, y = GetZoneInfo()
        if knownCrateZoneIDs[mapID] and not hasAnnounced[mapID] then
            SendCrateAnnouncement(zoneName, x, y)
            hasAnnounced[mapID] = true
        end

    elseif event == "CHAT_MSG_ADDON" then
        local prefix, zoneName = arg1, arg2
        if prefix == ANNOUNCEMENT_PREFIX then
            for pattern, id in pairs(zoneMapIDs) do
                if zoneName:match(pattern) then
                    hasAnnounced[id] = true
                    break
                end
            end
        end

    elseif event == "ZONE_CHANGED_NEW_AREA" then
        local mapID = C_Map.GetBestMapForUnit("player")
        if currentMapID and currentMapID ~= mapID then
            hasAnnounced[currentMapID] = nil
        end
        currentMapID = mapID
    end
end)