if not core.global_exists("stairs") or not core.get_modpath("stairs") then return end

local S = ...

local function rotate_and_place(itemstack, placer, pointed_thing)
	local retname = itemstack:get_name()
	local p0 = pointed_thing.under
	local p1 = pointed_thing.above
	local param2 = 0

	if placer then
		local placer_pos = placer:get_pos()
		if placer_pos then
			local diff = vector.subtract(p1, placer_pos)
			param2 = core.dir_to_facedir(diff)
			-- The player places a node on the side face of the node they are standing on
			if p0.y == p1.y and math.abs(diff.x) <= 0.5 and math.abs(diff.z) <= 0.5 and diff.y < 0 then
				-- Reverse node direction
				param2 = (param2 + 2) % 4
			end
		end

		local finepos = vector.apply(
			core.pointed_thing_to_face_pos(placer, pointed_thing),
			function(a) return a % 1 end
		)

		if p0.y - 1 == p1.y or (finepos.y > 0 and finepos.y < 0.5)
				or (finepos.y < -0.5 and finepos.y > -0.999999999) then
			param2 = param2 + 20
			if param2 == 21 then
				param2 = 23
			elseif param2 == 23 then
				param2 = 21
			end
		end

		local finedir = core.facedir_to_dir(param2)
		local right = true
		if finedir.z == 1 then -- z+
			right = finepos.x <= 0.5
		elseif finedir.z == -1 then -- z-
			right = finepos.x > 0.5
		elseif finedir.x == 1 then -- x+
			right = finepos.z > 0.5
		elseif finedir.x == -1 then -- x-
			right = finepos.z <= 0.5
		end
		if param2 >= 20 then
			right = not right -- invert
		end

		if right then
			local idef = itemstack:get_definition()
			local node_name = idef._subnodes_node_name
			local _, right_name = subnodes.make_name_subname(node_name, "stairsplus:right_halfstair")
			itemstack:set_name(right_name)
		end
	end
	core.item_place(itemstack, placer, pointed_thing, param2)
	itemstack:set_name(retname)
	return itemstack
end

local function register_inverted_lbm(subnode_name, node_name, ...)
	local arg = {...}
	return core.register_lbm({
		label = "Update inverted half stairs from " .. node_name,
		name = ":" .. arg[1] .. "_inverted_halfstair_replace",
		nodenames = arg,
		run_at_every_load = true,
		action = function(pos, node, dtime_s)
			local n = {}
			n.name = subnode_name
			n.param2 = node.param2 + 20
			if n.param2 == 21 then
				n.param2 = 23
			elseif n.param2 == 23 then
				n.param2 = 21
			end
			core.set_node(pos, n)
		end
	})
end

local function register_corner_lbm(subnode_name, node_name, ...)
	local arg = {...}
	return core.register_lbm({
		label = "Update half corners from " .. node_name,
		name = ":" .. arg[1] .. "_halfcorner_replace",
		nodenames = arg,
		run_at_every_load = true,
		action = function(pos, node, dtime_s)
			local n = {name = subnode_name, param2 = 0}
			if node.param2 == 0 then
				n.param2 = 11
			elseif node.param2 == 1 then
				n.param2 = 16
			elseif node.param2 == 2 then
				n.param2 = 5
			elseif node.param2 == 3 then
				n.param2 = 14
			end
			core.set_node(pos, n)
		end
	})
end

local function register_inverted_corner_lbm(subnode_name, node_name, ...)
	local arg = {...}
	return core.register_lbm({
		label = "Update inverted half corners from " .. node_name,
		name = ":" .. arg[1] .. "_inverted_halfcorner_replace",
		nodenames = arg,
		run_at_every_load = true,
		action = function(pos, node, dtime_s)
			local n = {name = subnode_name, param2 = 0}
			if node.param2 == 0 then
				n.param2 = 12
			elseif node.param2 == 1 then
				n.param2 = 9
			elseif node.param2 == 2 then
				n.param2 = 18
			elseif node.param2 == 3 then
				n.param2 = 7
			end
			core.set_node(pos, n)
		end
	})
end

subnodes.register_kind("stairsplus:halfstair", {
	node_override = {
		drawtype = "nodebox",
		paramtype = "light",
		paramtype2 = "facedir",
		node_box = {
			type = "fixed",
			fixed = {
				{-0.5, -0.5, -0.5, 0, 0, 0.5},
				{-0.5, 0, 0, 0, 0.5, 0.5},
			},
		},

		on_place = function(itemstack, placer, pointed_thing)
			local rc = voxelgarden.call_on_rightclick(itemstack, placer, pointed_thing)
			if rc then return rc end

			return rotate_and_place(itemstack, placer, pointed_thing)
		end,
	},

	get_readable_name = function(base_description)
		return S("@1 Half Stair", base_description)
	end,

	get_crafts = function(n, m)
		local _, m = subnodes.make_name_subname(m, "stairs:stair")
		return {
			output = n .. " 4",
			recipe = {
				{m, m},
			}
		}
	end,

	after_register = function(subnode_name, node_name)
		local _, subnode_name2 = subnodes.make_name_subname(node_name, "stairsplus:right_halfstair")
		local _, old_basename, old_basename2 = subnodes.make_name_subname(node_name, "stairsplus:stair")
		local old_name, old_name2 = old_basename .. "_half", old_basename2 .. "_half"
		core.register_alias(old_name, subnode_name)
		core.register_alias(old_name2, subnode_name)
		register_inverted_lbm(subnode_name2, node_name, old_name .. "_inverted", old_name2 .. "_inverted")
		voxelgarden.register_item_conversion(old_name .. "_inverted", subnode_name)
		voxelgarden.register_item_conversion(old_name2 .. "_inverted", subnode_name)

		local _, corner_basename, corner_basename2 = subnodes.make_name_subname(node_name, "stairsplus:corner")
		local corner_name, corner_name2 = corner_basename .. "_half", corner_basename2 .. "_half"
		register_corner_lbm(subnode_name, node_name, corner_name, corner_name2)
		register_inverted_corner_lbm(subnode_name, node_name, corner_name .. "_inverted",
			corner_name2 .. "_inverted")
		voxelgarden.register_item_conversion(corner_name, subnode_name)
		voxelgarden.register_item_conversion(corner_name2, subnode_name)
		voxelgarden.register_item_conversion(corner_name .. "_inverted", subnode_name)
		voxelgarden.register_item_conversion(corner_name2 .. "_inverted", subnode_name)
	end,
})

subnodes.register_kind("stairsplus:right_halfstair", {
	node_override = {
		drawtype = "nodebox",
		paramtype = "light",
		paramtype2 = "facedir",
		node_box = {
			type = "fixed",
			fixed = {
				{0, -0.5, -0.5, 0.5, 0, 0.5},
				{0, 0, 0, 0.5, 0.5, 0.5},
			},
		},
		groups = {not_in_creative_inventory = 1},
	},

	get_readable_name = function(base_description)
		return S("@1 Half Stair", base_description)
	end,
	drop = subnodes.create_drop_kind("stairsplus:halfstair"),
	after_register = function(subnode_name, node_name)
		local _, subnode_name2 = subnodes.make_name_subname(node_name, "stairsplus:halfstair")
		local _, old_basename, old_basename2 = subnodes.make_name_subname(node_name, "stairsplus:stair")
		local old_name, old_name2 = old_basename .. "_right_half", old_basename2 .. "_right_half"
		core.register_alias(old_name, subnode_name)
		core.register_alias(old_name2, subnode_name)
		register_inverted_lbm(subnode_name2, node_name, old_name .. "_inverted", old_name2 .. "_inverted")
		voxelgarden.register_item_conversion(old_name .. "_inverted", subnode_name2)
		voxelgarden.register_item_conversion(old_name2 .. "_inverted", subnode_name2)
	end,
})
