-- tooltip.lua
-- Compact data + vendorType categories + zone-match filtering + distance

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

local VT = WDIGI.Data.VENDOR_TYPE

------------------------------------------------------------
-- CATEGORY DEFINITIONS (mapped to vendorType)
------------------------------------------------------------
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.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

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

    local itemID = GetItemInfoFromHyperlink(itemLink)
    if not itemID then return end

    if not ITEMLOCATIONSLIST[itemID] then return end

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

    local itemName, _, _, _, _, _, _, _, _, itemIcon = GetItemInfo(itemLink)
    WDIGI.Tooltip.lastItemName = itemName or "Unknown Item"
    WDIGI.Tooltip.lastItemIcon = itemIcon

    WDIGI.Tooltip.bestLocation = nil
    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 and (not WDIGI.Tooltip.bestLocation or best.dist < WDIGI.Tooltip.bestLocation.dist) then
            WDIGI.Tooltip.bestLocation = best
            WDIGI.Tooltip.bestLocation.header = cat.header
        end

        firstCategory = false
    end

    ------------------------------------------------------------
    -- Ctrl+Shift+Click → SetPin
    ------------------------------------------------------------
    if WDIGI.Tooltip.bestLocation then
        tooltip:SetScript("OnMouseDown", function(self, button)
            if IsControlKeyDown() and IsShiftKeyDown() and button == "LeftButton" then
                -- Debug: See what the click thinks is "best"
                if WDIGI.Tooltip.bestLocation then
                    WDIGI.Utils.Debug("Click Pin Triggered for MapID: " .. tostring(WDIGI.Tooltip.bestLocation.zID))
                    WDIGI.Commands.Pin()
                else
                    WDIGI.Utils.Error("Click Pin failed: bestLocation is nil!")
                end
            end
        end)
    end
end

------------------------------------------------------------
-- CATEGORY RENDERING (with zone-match filtering) v.3
------------------------------------------------------------
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 = {}

    --------------------------------------------------------
    -- Build vendor entries
    --------------------------------------------------------
    for _, e in ipairs(entries) do
        if e.vendorType == vendorType then
            local matchLevel = WDIGI.MapUtils.GetZoneMatchLevel(myMapID, e.mapID)

            if WDIGI.CurrentDebugLevel >= WDIGI.DebugLevels.TRACE then
                WDIGI.Utils.Trace(string.format("MATCH: %s | playerMap: %s | vendorMap: %s | matchLevel: %s",
                    e.vendorName, myMapID, e.mapID, matchLevel))
            end

            local onMap = (matchLevel == 0 or matchLevel == 1)
            local dist = 999999

            if onMap 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
                dist = math.sqrt(dx * dx + dy * dy) * (WDIGI.MapUtils.GetZoneMultiplier() or 1000)
            end

            table.insert(results, {
                dist       = dist,
                onMap      = onMap,
                matchLevel = matchLevel,
                zID        = e.mapID,
                parentID   = e.parentMapID,
                tx         = e.tx,
                ty         = e.ty,
                cost       = e.costString,
                vendorName = e.vendorName,
                vendorType = e.vendorType,
            })
        end
    end

    if #results == 0 then return nil end

    --------------------------------------------------------
    -- Determine best match level available
    --------------------------------------------------------
    local bestLevel = 3
    for _, r in ipairs(results) do
        if r.matchLevel < bestLevel then
            bestLevel = r.matchLevel
        end
    end

    --------------------------------------------------------
    -- Filter to only vendors at that match level
    --------------------------------------------------------
    local filtered = {}
    for _, r in ipairs(results) do
        if r.matchLevel == bestLevel then
            table.insert(filtered, r)
        end
    end
    results = filtered

    --------------------------------------------------------
    -- Sort results (same-zone first, then distance)
    --------------------------------------------------------
    table.sort(results, function(a, b)
        if a.onMap ~= b.onMap then return a.onMap end
        return a.dist < b.dist
    end)

    --------------------------------------------------------
    -- Render tooltip
    --------------------------------------------------------
    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]

        --------------------------------------------------------
        -- 1. CONTEXT-AWARE ZONE LOOKUP
        --------------------------------------------------------
        local mapInfo = C_Map.GetMapInfo(r.zID or 0)

        -- Fallback to Parent Map if specific map is unknown
        if not mapInfo and r.parentID and r.parentID > 0 then
            mapInfo = C_Map.GetMapInfo(r.parentID)
        end

        local zoneName = ""
        local isFallback = false

        if mapInfo then
            zoneName = mapInfo.name
        else
            isFallback = true
            -- Determine generic label based on source type
            if r.vendorType == WDIGI.Data.VENDOR_TYPE.DROPPED_BY then
                zoneName = "World Drop"
            else
                zoneName = "Unknown Location"
            end
        end

        --------------------------------------------------------
        -- 2. BUILD THE LINE
        --------------------------------------------------------
        local icon = WDIGI.Data.VENDOR_ICONS[r.vendorType]
        local iconTag = icon and ("|T" .. icon .. ":14:14:0:0|t ") or ""

        -- Use Green for known zones, Grey for fallbacks
        local zoneColor = isFallback and "|cff9d9d9d" or "|cff80ff80"
        local locationText = zoneColor .. zoneName .. "|r"

        -- Append coordinates only if they are valid
        if r.tx > 0 and r.ty > 0 then
            locationText = locationText .. string.format(" (|cffffff00%.1f, %.1f|r)", r.tx, r.ty)
        end

        local line = string.format("  %s|cffffffff%s|r - %s", iconTag, r.vendorName, locationText)

        -- Append distance only if on the same map and coords exist
        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

-- ------------------------------------------------------------
-- -- CATEGORY RENDERING (with zone-match filtering) v.1
-- ------------------------------------------------------------
-- 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 = {}
--
--     --------------------------------------------------------
--     -- Build vendor entries
--     --------------------------------------------------------
--     for _, e in ipairs(entries) do
--         if e.vendorType == vendorType then
--
--             local matchLevel = WDIGI.MapUtils.GetZoneMatchLevel(myMapID, e.mapID)
--
--             if WDIGI.CurrentDebugLevel >= WDIGI.DebugLevels.TRACE then
--                 WDIGI.Utils.Trace(string.format("MATCH: %s | playerMap: %s | vendorMap: %s | matchLevel: %s",
--                     e.vendorName, myMapID, e.mapID, matchLevel))
--             end
--
--             -- matchLevel 0 = same zone
--             -- matchLevel 1 = same parent zone (Stormwind subzones)
--             local onMap = (matchLevel == 0 or matchLevel == 1)
--
--             local dist = 999999
--
--             if onMap 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
--                 dist = math.sqrt(dx * dx + dy * dy) *
--                        (WDIGI.MapUtils.GetZoneMultiplier() or 1000)
--             end
--
--             local mapInfo  = C_Map.GetMapInfo(e.mapID)
--             local zoneName = mapInfo and mapInfo.name or "Unknown Zone"
--             local coordStr = string.format("%.1f, %.1f", e.tx, e.ty)
--             local icon = WDIGI.Data.VENDOR_ICONS[e.vendorType]
--             local iconTag = icon and ("|T" .. icon .. ":14:14:0:0|t ") or ""
--
--             local lineText = string.format(
--                 "%s|cffffffff%s|r - |cff80ff80%s|r (|cffffff00%s|r)",
--                 iconTag,
--                 e.vendorName,
--                 zoneName,
--                 coordStr
--             )
--
--             table.insert(results, {
--                 text       = lineText,
--                 dist       = dist,
--                 onMap      = onMap,
--                 matchLevel = matchLevel,
--                 zID        = e.mapID,
--                 tx         = e.tx,
--                 ty         = e.ty,
--                 cost       = e.costString,
--                 vendorName = e.vendorName,
--                 vendorType = e.vendorType,
--             })
--         end
--     end
--
--     if #results == 0 then return nil end
--
--     --------------------------------------------------------
--     -- Determine best match level available
--     --------------------------------------------------------
--     local bestLevel = 3
--     for _, r in ipairs(results) do
--         if r.matchLevel < bestLevel then
--             bestLevel = r.matchLevel
--         end
--     end
--
--     --------------------------------------------------------
--     -- Filter to only vendors at that match level
--     --------------------------------------------------------
--     local filtered = {}
--     for _, r in ipairs(results) do
--         if r.matchLevel == bestLevel then
--             table.insert(filtered, r)
--         end
--     end
--
--     results = filtered
--
--     --------------------------------------------------------
--     -- Sort results (same-zone first, then distance)
--     --------------------------------------------------------
--     table.sort(results, function(a, b)
--         if a.onMap ~= b.onMap then return a.onMap end
--         return a.dist < b.dist
--     end)
--
--     --------------------------------------------------------
--     -- Render tooltip
--     --------------------------------------------------------
--     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 line = "  - " .. r.text
--
--         if r.onMap and r.dist < 5000 then
--             line = line .. " |cff32ff32(" .. math.floor(r.dist) .. "yd)|r"
--         end
--
--         tooltip:AddLine(line)
--     end
--
--     return results[1]
-- end
