local SousChef = SousChef
local u = SousChef.Utility
local m = SousChef.Media

local BACKPACK = ZO_PlayerInventoryBackpack
local BANK = ZO_PlayerBankBackpack
local GUILD_BANK = ZO_GuildBankBackpack

local COOKING_RANK_2 = [[SousChef\media\Two.dds]]
local COOKING_RANK_3 = [[SousChef\media\Three.dds]]
local COOKING_RANK_4 = [[SousChef\media\Four.dds]]
local COOKING_RANK_5 = [[SousChef\media\Five.dds]]
local COOKING_RANK_6 = [[SousChef\media\Six.dds]]
local COOKING_FLAVOUR = [[SousChef\media\Flavour.dds]]
local COOKING_SPICE =   [[SousChef\media\Spice.dds]]
local COOKING_SPICEB =   [[SousChef\media\Spice_Flat.dds]]
local COOKING_RANK_1B = [[SousChef\media\One_flat.dds]]
local COOKING_RANK_2B = [[SousChef\media\Two_flat.dds]]
local COOKING_RANK_3B = [[SousChef\media\Three_flat.dds]]
local COOKING_RANK_4B = [[SousChef\media\Four_flat.dds]]
local COOKING_RANK_5B = [[SousChef\media\Five_flat.dds]]
local COOKING_RANK_6B = [[SousChef\media\Six_flat.dds]]
local COOKING_FLAVOURB = [[SousChef\media\flavour_flat.dds]]
local COOKING_RANK_1 = [[SousChef\media\One.dds]]

local GRILLED  = [[/esoui/art/treeicons/provisioner_indexicon_meat_down.dds]]
local BREADPIE  = [[/esoui/art/treeicons/provisioner_indexicon_baked_down.dds]]
local SOUPSTEW  = [[/esoui/art/treeicons/provisioner_indexicon_stew_down.dds]]
local BEER  = [[/esoui/art/treeicons/provisioner_indexicon_beer_down.dds]]
local SPIRITS  = [[/esoui/art/treeicons/provisioner_indexicon_spirits_down.dds]]
local WINE  = [[/esoui/art/treeicons/provisioner_indexicon_wine_down.dds]]

m.COOKING = { COOKING_RANK_1, COOKING_RANK_2, COOKING_RANK_3, COOKING_RANK_4, COOKING_RANK_5, COOKING_RANK_6, COOKING_FLAVOUR, COOKING_SPICE, GRILLED, BREADPIE, SOUPSTEW, BEER, SPIRITS, WINE}
m.COOKINGB = { COOKING_RANK_1B, COOKING_RANK_2B, COOKING_RANK_3B, COOKING_RANK_4B, COOKING_RANK_5B, COOKING_RANK_6B, COOKING_FLAVOURB, COOKING_SPICEB, GRILLED, BREADPIE, SOUPSTEW, BEER, SPIRITS, WINE}

m.CANLEARN = [[/esoui/art/loot/loot_finesseitem.dds]]

local INVENTORIES = {
						[PLAYER_INVENTORY.inventories[1].listView] = {GetItemLink, "bagId", "slotIndex"}, -- Backpack
						[PLAYER_INVENTORY.inventories[3].listView] = {GetItemLink, "bagId", "slotIndex"}, -- Bank
						[PLAYER_INVENTORY.inventories[4].listView] = {GetItemLink, "bagId", "slotIndex"}, -- GuildBank
						[LOOT_WINDOW.list]   					   = {GetLootItemLink, "lootId", nil}	  -- LootWindow
}
local rowClicked = {}

function SousChef.HookInventory()
	for list, funcs in pairs(INVENTORIES) do
		if list and list.dataTypes and list.dataTypes[1] then
			local listName = list:GetName()
            SousChef.hookedFunctions[listName] = list.dataTypes[1].setupCallback
			if SousChef.hookedFunctions[listName] then
				list.dataTypes[1].setupCallback =
					function(rowControl, slot)
	                    SousChef.hookedFunctions[listName](rowControl, slot)
						SousChef.AddRankToSlot(rowControl, funcs)
					end
			else
				d("SousChef could not hook into the Inventory")
			end
		end
    end

	ZO_ScrollList_RefreshVisible(BACKPACK)
	ZO_ScrollList_RefreshVisible(BANK)
	ZO_ScrollList_RefreshVisible(GUILD_BANK)
	if not SousChef.settings.showOnClick then
		ZO_PreHookHandler(ItemTooltip, "OnShow", function() zo_callLater(function() SousChef.AddDetails(moc()) end, 1000) end)
		ZO_PreHookHandler(ItemTooltip, "OnUpdate", function() return SousChef.AddDetails(moc()) end)
		ZO_PreHookHandler(ItemTooltip, "OnHide", function() rowClicked = nil return false end )
	end
end

function SousChef.getIcon(row)
	local rankIcon = SousChef.slotLines[row:GetName()]
	if(not rankIcon) then
		rankIcon =  WINDOW_MANAGER:CreateControl(row:GetName() .. "SousChef", row, CT_TEXTURE)
        SousChef.slotLines[row:GetName()] = rankIcon
        if SousChef.settings.showOnClick then
        	ZO_PreHookHandler(row, "OnMouseDown", SousChef.AddDetails)
        	ZO_PreHookHandler(row, "OnMouseExit", function(self) rowClicked = nil return false end )
		end
	end
	return rankIcon
end

local function CalculateHowManyCouldBeCreated(recipeListIndex, recipeIndex, numIngredients)
    local minCount

    for ingredientIndex = 1, numIngredients do
        local _, _, requiredQuantity = GetRecipeIngredientItemInfo(recipeListIndex, recipeIndex, ingredientIndex)
        local ingredientCount = GetCurrentRecipeIngredientCount(recipeListIndex, recipeIndex, ingredientIndex)

        minCount = zo_min(zo_floor(ingredientCount / requiredQuantity), minCount or math.huge)
        if minCount == 0 then
            return 0
        end
    end

    return minCount or 0
end

function SousChef.AddDetails(row)
	if not row.dataEntry or not row.dataEntry.data or rowClicked == row then return false end
	rowClicked = row
	local rowInfo = row.dataEntry.data
	local bagId = rowInfo.bagId or rowInfo.lootId
	local slotIndex = rowInfo.slotIndex

	if u.MatchesRecipe(rowInfo.name and rowInfo.name or "") then
        local gmatch = u.MatchInGlobalCookbook(rowInfo.name)
        if gmatch then
            ZO_Tooltip_AddDivider(ItemTooltip)
            ItemTooltip:AddLine("Known by ", "ZoFontWinH5", 1,1,1, BOTTOM, MODIFY_TEXT_TYPE_UPPERCASE)
            ItemTooltip:AddLine(u.TableKeyConcat(gmatch))
            return false
        end
    end

    if SousChef.settings.onlyShowShopping and SousChef.slotLines[row:GetName()] and SousChef.slotLines[row:GetName()]:IsHidden() then return end

	local itemId = u.GetItemID(slotIndex and GetItemLink(bagId, slotIndex) or GetLootItemLink(bagId)) -- Get itemId of inventory or loot slot
	local usableIngredient = SousChef.ReverseCookbook[itemId]
	if SousChef.settings.showAltIngredientKnowledge then usableIngredient = SousChef.settings.ReverseCookbook[itemId] end
	if usableIngredient then
		ZO_Tooltip_AddDivider(ItemTooltip)
		ItemTooltip:AddLine("Used in:", "ZoFontWinH5", 1,1,1, BOTTOM, MODIFY_TEXT_TYPE_UPPERCASE)
	    for i,v in ipairs(usableIngredient) do
	    	local line = v
	    	if type(SousChef.settings.shoppingList[v]) == "table" and next(SousChef.settings.shoppingList[v]) then
	    		line = "*(" .. u.TableKeyConcat(SousChef.settings.shoppingList[v])..") ".. line
	    	end
	    	if SousChef.settings.showCounts then
	    		local bookmark = SousChef.CookbookIndex[v]
	    		if bookmark then
	    			local count = CalculateHowManyCouldBeCreated(bookmark.listIndex, bookmark.recipeIndex, bookmark.numIngredients)
	    			if count > 0 then
	    				line = line .." - (" .. count .. ")"
	    			end
	    		end
	    	end
	    	ItemTooltip:AddLine(line)
	    end
	end
	return false
end

function SousChef.AddRecipeToIgnoreList(link)
	if GetItemLinkInfo(link) ~= "" then link = string.match(link, "([%w\128-\244 ]+)%]") end
	SousChef.settings.ignoredRecipes[link] = true
	d("Adding " .. link .. " to ignored recipes")

end

function SousChef.RemoveRecipeFromIgnoreList(link)
	if GetItemLinkInfo(link) ~= "" then link = string.match(link, "([%w\128-\244 ]+)%]") end
	if not SousChef.settings.ignoredRecipes[link] then d(link .. " not found in ignore list") return end
	SousChef.settings.ignoredRecipes[link] = nil
	d("Removed " .. link .. " from ignored recipes")
end

function SousChef.ListIgnoredRecipes()
	d("Ignoring:")
	 for recipe in pairs(SousChef.settings.ignoredRecipes) do
        d(recipe)
    end
end