-- @author DoomTero 2026
-- @copyright 2026 DoomTero - ZomboRut original work. ref:200c42ac
-- @license Proprietary. Not licensed for reuse, redistribution or derivative works without written permission from DoomTero. Ask - permission is obtainable. See ZomboRut/LICENSE.txt

require "TimedActions/ISSubdueZombieAction"

local ITEM_DUCT_TAPE = ISSubdueZombieAction.ITEM_DUCT_TAPE
local ITEM_ROPE      = ISSubdueZombieAction.ITEM_ROPE
local BELT_COUNT     = ISSubdueZombieAction.BELT_COUNT

local function isDownedZombie(obj)
	if not instanceof(obj, "IsoZombie") then return false end
	if obj:isDead() then return false end
	if obj:getModData().zrSubdued then return false end
	return obj:isKnockedDown() or obj:isOnFloor() or obj:isCrawling()
end

local findOnTilesAndNeighbors = require("ZomboRut/ContextMenu/ZR_MenuUtil").findOnTilesAndNeighbors
local setIcon = require("ZomboRut/ContextMenu/ZR_MenuUtil").icon

local function findBinding(playerObj)
	return ISSubdueZombieAction.findBinding(playerObj)
end

local function findDuctTape(playerObj)
	local inv = playerObj:getInventory()
	return inv and inv:getFirstTypeRecurse(ITEM_DUCT_TAPE) or nil
end

local ICON_PX = 20
local function itemIcon(fullType)
	local path
	pcall(function()
		local script = ScriptManager.instance:getItem(fullType)
		local name = script and script:getIcon()
		if not name or name == "" then return end
		local candidate = "media/textures/Item_" .. name
		if tryGetTexture(candidate) then path = candidate end
	end)
	if not path then return "" end
	return string.format("<IMAGE:%s,%d,%d> ", path, ICON_PX, ICON_PX)
end

local function onSubdue(playerObj, target)
	if not findBinding(playerObj) or not findDuctTape(playerObj) then return end

	local sq = target:getSquare()
	if not sq then return end
	if not luautils.walkAdj(playerObj, sq) then return end

	ISTimedActionQueue.add(ISSubdueZombieAction:new(playerObj, target))
end

return function(ContextMenu, playerObj, context, worldobjects, getRoot)
	if not playerObj then return end

	if playerObj:isDraggingCorpse() then return end

	local target = findOnTilesAndNeighbors(worldobjects, "moving", isDownedZombie)
	if not target then return end

	local binding = findBinding(playerObj)
	local tape = findDuctTape(playerObj)
	local option = getRoot():addOption(
		getText("ContextMenu_ZR_Subdue") or "Subdue",
		worldobjects,
		function() onSubdue(playerObj, target) end)
	setIcon(option, "Subdue")

	if not binding or not tape then
		option.notAvailable = true

		local lines = {}
		if not tape then
			lines[#lines + 1] = itemIcon(ITEM_DUCT_TAPE)
				.. getItemNameFromFullType(ITEM_DUCT_TAPE)
		end
		if not binding then
			lines[#lines + 1] = itemIcon(ITEM_ROPE)
				.. getText("ContextMenu_ZR_Subdue_MissingBinding",
					getItemNameFromFullType(ITEM_ROPE), BELT_COUNT)
		end

		local desc = getText("ContextMenu_ZR_Subdue_Missing")
		for i = 1, #lines do
			desc = desc .. " <LINE> <RGB:1,0.35,0.35>  * " .. lines[i]
		end

		local tooltip = ISToolTip:new()
		tooltip:initialise()
		tooltip:setVisible(false)
		tooltip.description = desc
		option.toolTip = tooltip
	end
end
