local async = LibStub("LibAsync")
local task = async:Create("FurnitureCatalogue_Tooltip")

local p 		= FurC.DebugOut -- debug function calling zo_strformat with up to 10 args

local function tryColorize(text)
	if not (text and FurC.GetColouredTooltips()) then return text end
	return text:gsub("cannot craft", "|cFF0000cannot craft|r"):gsub("Can be crafted", "|c00FF00Can be crafted|r")
end


local function addTooltipData(control, itemLink)

	if FurC.GetDisableTooltips() then return end
	local itemId, recipeArray = nil
	if nil == itemLink or FURC_EMPTY_STRING == itemLink then return end
	local isRecipe = IsItemLinkFurnitureRecipe(itemLink)

	itemLink = (isRecipe and GetItemLinkRecipeResultItemLink(itemLink)) or itemLink

    if not (isRecipe or IsItemLinkPlaceableFurniture(itemLink)) then return end
	itemId 		= FurC.GetItemId(itemLink)
	recipeArray = FurC.Find(itemLink)

	-- |H0:item:118206:5:1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0|h|h

	if not recipeArray then return end


	local unknown 	= not FurC.CanCraft(itemId, recipeArray)
	local stringTable = {}


	local function add(t, arg)
		if nil ~= arg then t[#t + 1] = arg end
		return t
	end

	-- if craftable:
	if isRecipe or recipeArray.origin == FURC_CRAFTING then
		if unknown and not FurC.GetHideUnknown() or not FurC.GetHideKnowledge() then
			local crafterList = FurC.GetCrafterList(itemLink, recipeArray)
			if crafterList then
				stringTable = add(stringTable, tryColorize(crafterList))
			end
		end
		if not isRecipe and (not FurC.GetHideCraftingStation()) then
			stringTable = add(stringTable, FurC.PrintCraftingStation(itemId, recipeArray))
		end
		if isRecipe then
			stringTable = add(stringTable, FurC.getRecipeSource(itemId, recipeArray))
		end
		-- check if we should show mats
		if not (FurC.GetHideMats() or isRecipe) then
			stringTable = add(stringTable, FurC.GetMats(itemLink, recipeArray, true):gsub(", ", "\n"))
		end
	else
		if not FurC.GetHideSource() then
			stringTable = add(stringTable, FurC.GetItemDescription(itemId, recipeArray))
		end
		stringTable = add(stringTable, recipeArray.achievement)
	end

	if #stringTable == 0 then return end

	control:AddVerticalPadding(8)
	ZO_Tooltip_AddDivider(control)

	for i = 1, #stringTable do
		control:AddLine(zo_strformat("<<C:1>>", stringTable[i]))
	end

end

local function TooltipHook(tooltipControl, method, linkFunc)
	local origMethod = tooltipControl[method]

	tooltipControl[method] = function(self, ...)
		origMethod(self, ...)
		addTooltipData(self, linkFunc(...))
	end
end

local function ReturnItemLink(itemLink)
	return FurC.GetItemLink(itemLink)
end

do
	local identifier = FurC.name .. "Tooltips"
	-- hook real late
	local function HookToolTips()
		EVENT_MANAGER:UnregisterForUpdate(identifier)
		TooltipHook(ItemTooltip, 	"SetBagItem", 				GetItemLink)
		TooltipHook(ItemTooltip, 	"SetTradeItem", 			GetTradeItemLink)
		TooltipHook(ItemTooltip, 	"SetBuybackItem",			GetBuybackItemLink)
		TooltipHook(ItemTooltip, 	"SetStoreItem", 			GetStoreItemLink)
		TooltipHook(ItemTooltip, 	"SetAttachedMailItem", 		GetAttachedItemLink)
		TooltipHook(ItemTooltip, 	"SetLootItem", 				GetLootItemLink)
		TooltipHook(ItemTooltip, 	"SetTradingHouseItem", 		GetTradingHouseSearchResultItemLink)
		TooltipHook(ItemTooltip, 	"SetTradingHouseListing", 	GetTradingHouseListingItemLink)
		TooltipHook(ItemTooltip, 	"SetLink", 					ReturnItemLink)
		TooltipHook(PopupTooltip, 	"SetLink", 					ReturnItemLink)
	end
	-- hook late
	local function DeferHookToolTips()
		EVENT_MANAGER:UnregisterForEvent(identifier, EVENT_PLAYER_ACTIVATED)
		EVENT_MANAGER:RegisterForUpdate(identifier, 100, HookToolTips)
	end
	function FurC.CreateTooltips()
		EVENT_MANAGER:RegisterForEvent(identifier, EVENT_PLAYER_ACTIVATED, DeferHookToolTips)
	end
end