--[[
	Cerebro - Tooltip Injector Module
	
	PURPOSE:
	Injects Cerebro-relevant information into native WoW tooltips.
	
	1. Player Unit Tooltips - Shows EPGP summary (PR, EP/GP) when hovering a friendly player.
	2. Item Tooltips - Shows GP cost breakdown (Normal/Heroic/Mythic) for equippable items.
	
	SECURITY:
	Read-only. No mutations, no officer checks required.
	
	EXTERNAL DEPENDENCIES:
	- Models/Player.lua (GetEP, GetRawGP, GetPR)
	- Modules/EPGP.lua (GetItemGP, GetSlotBaseGP)
	- WoW API: GetItemInfoInstant, TooltipDataProcessor
]]--

local AddonName, _PrivateTable = ...
local Cerebro = LibStub("AceAddon-3.0"):GetAddon(AddonName)
local TooltipInjector = Cerebro:NewModule("TooltipInjector", "AceEvent-3.0")

-- Difficulty lookup: ID -> display name
local DIFFICULTY_INFO = {
	{ id = 14, name = "Normal",  color = {1, 1, 1} },       -- white
	{ id = 15, name = "Heroic",  color = {0.2, 1, 0.2} },   -- green
	{ id = 16, name = "Mythic",  color = {1, 0.5, 0} },     -- orange
}

function TooltipInjector:OnEnable()
	-- Unit tooltips: Use UPDATE_MOUSEOVER_UNIT event instead of TooltipDataProcessor.
	-- WoW 12.0 Midnight runs TooltipDataProcessor callbacks in a tainted execution context
	-- where ALL values (data.guid, tooltip:GetUnit(), even captured upvalues) are secret.
	-- C_Timer.After(0) doesn't help because the captured tooltip reference carries taint.
	-- The UPDATE_MOUSEOVER_UNIT event runs in a fully untainted context where standard
	-- unit APIs (UnitIsPlayer, UnitName, etc.) work without restriction.
	self:RegisterEvent("UPDATE_MOUSEOVER_UNIT")

	-- Item tooltips via TooltipDataProcessor (items are not affected by unit taint)
	if TooltipDataProcessor and TooltipDataProcessor.AddTooltipPostCall then
		TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, function(tooltip, data)
			self:OnTooltipSetItem(tooltip, data)
		end)
	end
end

--[[=============================================
	Player Unit Tooltip
	Shows EPGP summary when hovering a friendly player.
	Uses UPDATE_MOUSEOVER_UNIT event to avoid WoW 12.0 taint.
===============================================]]

-- Guard tag to prevent duplicate injection if event fires multiple times
local CEREBRO_TOOLTIP_TAG = "CerebroEPGPInjected"

function TooltipInjector:UPDATE_MOUSEOVER_UNIT()
	-- All unit APIs are safe here — we're in an untainted event handler
	if not UnitIsPlayer("mouseover") then return end
	if not UnitIsFriend("player", "mouseover") then return end

	local name, realm = UnitName("mouseover")
	if not name then return end

	-- Build full name for DB lookup
	local fullName = (realm and realm ~= "") and (name .. "-" .. realm) or name
	local targetName = Cerebro:GetFullPlayerName(fullName)
	if not targetName then return end

	-- Ensure GameTooltip is visible and not already injected
	if not GameTooltip:IsVisible() then return end
	if GameTooltip[CEREBRO_TOOLTIP_TAG] then return end

	-- Guard: Only show EPGP info for players already tracked in our database.
	-- Without this check, Player:New() -> GetData() -> GetPlayerData() auto-creates
	-- a Pending record for ANY friendly player we hover, polluting the DB with
	-- random nearby players who have nothing to do with our guild or raids.
	if not Cerebro.db.global.players[targetName] then return end

	-- Add EPGP Info
	local player = Cerebro.Player:New(targetName)
	local ep = player:GetEP()
	local gp = player:GetRawGP()
	local pr = player:GetPR()

	GameTooltip:AddLine(" ")
	GameTooltip:AddLine("|cffffd700Cerebro:|r")
	GameTooltip:AddDoubleLine("PR:", string.format("|cffffffff%.2f|r", pr))
	GameTooltip:AddDoubleLine("EP / GP:", string.format("|cffffffff%d / %d|r", ep, gp))

	GameTooltip[CEREBRO_TOOLTIP_TAG] = true
	GameTooltip:Show()
end

-- Clear injection tag when tooltip hides (so next mouseover can inject fresh)
GameTooltip:HookScript("OnHide", function(self)
	self[CEREBRO_TOOLTIP_TAG] = nil
end)

--[[=============================================
	Item Tooltip
	Shows GP cost for all three raid difficulties
	on any equippable item.
===============================================]]

function TooltipInjector:OnTooltipSetItem(tooltip, _data)
	-- Only inject into the main GameTooltip (not comparison tooltips, embedded tooltips, etc.)
	if tooltip ~= GameTooltip then return end

	-- Get item link from the tooltip
	local _, itemLink = tooltip:GetItem()
	if not itemLink then return end

	-- Ensure EPGP module is loaded
	local EPGP = Cerebro.modules.EPGP
	if not EPGP then return end

	-- Check if item is equippable and has a configured slot weight
	local _, _, _, itemEquipLoc = GetItemInfoInstant(itemLink)
	if not itemEquipLoc or itemEquipLoc == "" then return end

	local baseGP = EPGP:GetSlotBaseGP(itemEquipLoc)
	if not baseGP or baseGP == 0 then return end

	-- Get friendly slot name for display
	local slotName = Cerebro:GetFriendlySlotName(itemEquipLoc)

	-- Header
	tooltip:AddLine(" ")
	tooltip:AddLine("|cffffd700Cerebro GP|r |cff888888(" .. slotName .. ")|r")

	-- Show GP cost for each difficulty
	for _, diff in ipairs(DIFFICULTY_INFO) do
		local gp = EPGP:GetItemGP(itemLink, diff.id)
		if gp and gp > 0 then
			tooltip:AddDoubleLine(
				diff.name .. ":",
				Cerebro:FormatNumber(gp) .. " GP",
				diff.color[1], diff.color[2], diff.color[3],  -- left color
				1, 1, 1                                        -- right color (white)
			)
		end
	end

	tooltip:Show()
end
