-- luacheck: globals Item Vector2 Character MyModGlobal CLIENT
-- luacheck: max line length 420
if not CLIENT then return end
local dump = require("Cyka.dump")
local quickstack = require("Cyka.quickstack")

---@class ItemLocation
---@field item Barotrauma.Item
---@field distance number

---@param A Vector2
---@param B Vector2
---@return number
local function getDistanceQuick(A, B)
	return math.abs(A.X - B.X) + math.abs(A.Y - B.Y)
end

---@param source Vector2
---@param distanceThreshold number
---@return ItemLocation[]
local function getNearbyItems(source, distanceThreshold)
	-- local log = {}
	---@type ItemLocation[]
	local items = {}
	local whitelistedComponents = "Holdable,Pickable,Wearable"
	local blacklistedComponents = "ConnectionPanel"
	for item in Item.ItemList do
		-- log[#log + 1] = string.format("Checking item %s", tostring(item))
		local distance, tags, hasAnyOfComponent
		---@cast item Barotrauma.Item
		local parentInventory = item.ParentInventory
		if parentInventory then
			-- log[#log + 1] = string.format("Item %s is in an inventory", tostring(item))
			goto continue
		end
		-- tags = tostring(item.Tags)
		-- if not string.find(tags, "item") then
		-- 	-- log[#log + 1] = string.format("Item %s is not an item (but a structure) - %s", tostring(item), tags)
		-- 	goto continue
		-- end
		-- for component in item.Components do
		-- 	-- For some God forsaken reason this does not work
		-- 	-- Not that it classifies the incorrect items
		-- 	-- But it just literally does not work
		-- 	-- The code does not execute
		-- 	-- Some of the items vanish into thin air, as if they never existed
		-- 	-- I have no idea why
		-- 	-- So we'll do this in 2 steps...
		-- 	-- if string.find(blacklistedComponents, component.Name) then
		-- 	-- 	log[#log + 1] = string.format("Item %s has blacklisted component %s - %s", tostring(item), component.Name, component.Name)
		-- 	-- 	goto continue
		-- 	-- end
		-- 	if string.find(whitelistedComponents, component.Name) then
		-- 		hasAnyOfComponent = true
		-- 		break
		-- 	end
		-- end
		-- if not hasAnyOfComponent then
		-- 	-- log[#log + 1] = string.format("Item %s is not %s", tostring(item), whitelistedComponents)
		-- 	goto continue
		-- end

		distance = getDistanceQuick(item.WorldPosition, source)
		if distance > distanceThreshold then
			-- log[#log + 1] = string.format("Item %s is too far away - %s", tostring(item), distance)
			goto continue
		end
		items[#items + 1] = {
			item = item,
			distance = distance,
		}
		::continue::
	end
	-- print(table.concat(log, "\n"))

	table.sort(items, function(a, b)
		return a.distance > b.distance
	end)
	local log = ""
	for _, item in pairs(items) do
		local components = ""
		for component in item.item.Components do
			components = components .. component.Name .. ", "
		end
		log = log ..
		string.format("%s d:%d t:%s c:%s\n", tostring(item.item.Prefab.Identifier.Value), item.distance, tostring(item.item.Tags),
			components)
	end
	print(log)

	-- local str = ""
	-- for _, item in pairs(items) do
	-- 	str = str .. tostring(item.item) .. " " .. item.distance .. " "
	-- 	local tags = tostring(item.item.Tags)
	-- 	str = str .. tags .. " "
	-- 	for component in item.item.Components do
	-- 		str = str .. component.Name .. " "
	-- 	end
	-- 	str = str .. "---" .. "\n"
	-- end
	-- print(str)

	-- local filteredItems = {}
	-- for _, item in pairs(items) do
	-- 	for component in item.item.Components do
	-- 		if string.find(blacklistedComponents, component.Name) then
	-- 			goto continue
	-- 		end
	-- 	end
	-- 	filteredItems[#filteredItems + 1] = item.item
	-- 	::continue::
	-- end
	-- dump(filteredItems)

	-- str = ""
	-- for _, item in pairs(filteredItems) do
	-- 	str = str .. tostring(item) .. " "
	-- 	local tags = tostring(item.Tags)
	-- 	str = str .. tags .. " "
	-- 	for component in item.Components do
	-- 		str = str .. component.Name .. " "
	-- 	end
	-- 	str = str .. "---" .. "\n"
	-- end
	-- print(str)

	return filteredItems
end

local function tryAoePickup()
	MyModGlobal.debugPrint("tryAoePickup")
	local character = Character.Controlled
	if not character then
		MyModGlobal.debugPrint("No controlled character")
		return
	end

	local itemTree, err = quickstack.tryBuildCharacterItemTree(character)
	if err then
		MyModGlobal.debugPrint(err)
		return
	end

	local distanceThreshold = 500
	local characterPos = character.WorldPosition
	local nearbyItems = getNearbyItems(characterPos, distanceThreshold)

	-- local errors = quickstack.tryMoveItems(nearbyItems, itemTree, true)
	-- for _, error in pairs(errors) do
	-- 	MyModGlobal.debugPrint(string.format("Error moving items: %s", error))
	-- end
end

return {
	tryAoePickup = tryAoePickup,
}
