local ADDON_NAME, WDIGI = ...
WDIGI.Tooltip = WDIGI.Tooltip or {}

local VT = WDIGI.Data.VENDOR_TYPE

------------------------------------------------------------
-- CATEGORY DEFINITIONS
------------------------------------------------------------
WDIGI.Tooltip.CATEGORIES = {
    { vendorType = VT.DROPPED_BY,        header = "|cff00ff00What Drops This?|r",       setting = "WDIGI_Limit_DroppedBy" },
    { vendorType = VT.SOLD_BY,           header = "|cffffff00Who Sells This?|r",        setting = "WDIGI_Limit_SoldBy" },
    { vendorType = VT.CONTAINED_IN,      header = "|cff00ffffContained In?|r",          setting = "WDIGI_Limit_ContainedIn" },
    { vendorType = VT.DISENCHANTED_FROM, header = "|cffc080ffDisenchanted From?|r",     setting = "WDIGI_Limit_Disenchanted" },
    { vendorType = VT.GATHERED_FROM,     header = "|cffff8000Gathered From?|r",         setting = "WDIGI_Limit_GatheredFrom" },
    { vendorType = VT.CRAFTED_BY,        header = "|cffeda55fCrafted By?|r",            setting = "WDIGI_Limit_CraftedBy" },
    { vendorType = VT.LEARNED_FROM,      header = "|cffabd473Learned From?|r",          setting = "WDIGI_Limit_LearnedFrom" },
    { vendorType = VT.QUEST_REWARD,      header = "|cffffcc00Quest Reward?|r",          setting = "WDIGI_Limit_QuestReward" },    
    { vendorType = VT.UNKNOWN,           header = "|cffaaaaaaOther Sources?|r",         setting = "WDIGI_Limit_Other" }
}

------------------------------------------------------------
-- MAIN TOOLTIP UPDATE
------------------------------------------------------------
function WDIGI.Tooltip.Update(tooltip)
    if tooltip ~= GameTooltip and tooltip ~= ItemRefTooltip then return end
    if not tooltip or tooltip:IsForbidden() then return end

    local _, itemLink = tooltip:GetItem()
    if not itemLink then return end

    local itemID = GetItemInfoFromHyperlink(itemLink)
    if not itemID or not ITEMLOCATIONSLIST[itemID] then return end

    if WDIGI.Settings.Get("WDIGI_ALTKey_Toggle") and not IsAltKeyDown() then return end

    local itemName, _, _, _, _, _, _, _, _, itemIcon = GetItemInfo(itemLink)
    if not itemName then return end

    WDIGI.Tooltip.lastItemName = itemName
    WDIGI.Tooltip.lastItemIcon = itemIcon
    WDIGI.Tooltip.bestLocation = nil
    
    local linesAdded = false
    local firstCategory = true

    for _, cat in ipairs(WDIGI.Tooltip.CATEGORIES) do
        local best = WDIGI.Tooltip.AddCategory(tooltip, itemID, cat.vendorType, cat.header, cat.setting, firstCategory)
        if best then
            linesAdded = true
            if (not WDIGI.Tooltip.bestLocation or best.dist < WDIGI.Tooltip.bestLocation.dist) then
                WDIGI.Tooltip.bestLocation = best
                WDIGI.Tooltip.bestLocation.header = cat.header
            end
        end
        firstCategory = false
    end

    if linesAdded then tooltip:Show() end
end

------------------------------------------------------------
-- CATEGORY RENDERING
------------------------------------------------------------
function WDIGI.Tooltip.AddCategory(tooltip, itemID, vendorType, header, setting, firstCategory)
    local entries = WDIGI.Data.ParseItemData(itemID)
    if #entries == 0 then return nil end

    local myMapID, px, py = WDIGI.MapUtils.GetCurrentPlayerData()
    local results = {}

    for _, e in ipairs(entries) do
        if e.vendorType == vendorType then
            local matchLevel = WDIGI.MapUtils.GetZoneMatchLevel(myMapID, e.mapID)
            
            local isLocal = (matchLevel == 0)
            local dist = 999999 

            if isLocal and px and py and e.tx > 0 and e.ty > 0 then
                local dx = (e.tx / 100) - px
                local dy = (e.ty / 100) - py
                
                local mult = WDIGI.MapUtils.GetZoneMultiplier(e.mapID) or 1000
                dist = math.sqrt(dx * dx + dy * dy) * mult
            else
                dist = 1000000 * (matchLevel + 1)
            end

            table.insert(results, {
                dist       = dist,
                onMap      = isLocal,
                matchLevel = matchLevel,
                zID        = e.mapID,
                parentID   = e.parentMapID,
                tx         = e.tx,
                ty         = e.ty,
                vendorName = e.vendorName,
                vendorType = e.vendorType,
                cost       = e.cost,
                npcID      = e.npcID,      
                sType      = e.sourceType, 
                era        = e.clientVer   
            })
        end
    end

    if #results == 0 then return nil end

    local bestLevel = 3
    for _, r in ipairs(results) do
        if r.matchLevel < bestLevel then bestLevel = r.matchLevel end
    end

    local filterLevel = (bestLevel == 0) and 1 or bestLevel
    local filtered = {}
    for _, r in ipairs(results) do
        if r.matchLevel <= filterLevel then table.insert(filtered, r) end
    end
    results = filtered

    -- Sort: Absolute spatial distance priority
    table.sort(results, function(a, b)
        if a.dist ~= b.dist then return a.dist < b.dist end
        return a.matchLevel < b.matchLevel
    end)

    if WDIGI.Settings.Get("WDIGI_ShowItemID_Toggle") and firstCategory then
        tooltip:AddLine("|cffff0000Item ID:|r " .. itemID)
    end

    tooltip:AddLine("\n" .. header)

    local limit = WDIGI.Settings.Get(setting) or 5
    for i = 1, math.min(limit, #results) do
        local r = results[i]
        local mapInfo = C_Map.GetMapInfo(r.zID or 0) or (r.parentID and C_Map.GetMapInfo(r.parentID))
        local zoneName = mapInfo and mapInfo.name or (r.vendorType ~= VT.SOLD_BY and "World Drop" or "Unknown")
        
        -- Rich Icon Selection
        local icon = WDIGI.Data.VENDOR_ICONS[r.vendorType]
        if r.sType == "creature" or (r.npcID and r.npcID > 0) then
            icon = 135911 
        elseif r.sType == "gameobject" then
            icon = 132594 
        end
        
        local iconTag = icon and ("|T" .. icon .. ":14:14:0:0:64:64:8:56:8:56|t ") or ""
        local zoneColor = not mapInfo and "|cff9d9d9d" or "|cff80ff80"

        local line = string.format("  %s|cffffffff%s|r - %s%s|r", iconTag, r.vendorName, zoneColor, zoneName)
        
        if r.tx > 0 then
            line = line .. string.format(" (|cffffff00%.1f, %.1f|r)", r.tx, r.ty)
        end

        -- 🚀 REDUCED: Invoke shared centralized formatting pipeline
        local formattedCost = WDIGI.Data.GetFormattedCost(r.cost, r.vendorType)
        if formattedCost and formattedCost ~= "" then
            line = line .. " [" .. formattedCost .. "]"
        end
        
        if r.onMap and r.dist < 5000 and r.tx > 0 then
            line = line .. " |cff32ff32(" .. math.floor(r.dist) .. "yd)|r"
        end

        tooltip:AddLine(line)
    end

    return results[1]
end