import { world, system } from "@minecraft/server";
import * as utils from "./utils";
import * as Vector3 from "./vector3";
import * as gld from "./gld";




// export async function onTick()
// {
// 	let players = await world.getAllPlayers();
// 	for(let player of players) 
// 	{
// 		if (player === undefined)
// 			continue;
// 		let slowFall = player.getDynamicProperty("goe_spa_slow_fall");
// 		let slowFallHeight = player.getDynamicProperty("goe_spa_slow_fall_height");
// 		if (slowFall === undefined || slowFallHeight < player.location.y)
// 			continue;
		
// 		game.runPlayerCommand(player, `effect @s slow_falling 5 1 true`);
// 		player.setDynamicProperty("goe_spa_slow_fall", undefined);
// 		player.setDynamicProperty("goe_spa_slow_fall_height", undefined);
// 	}
// }

export async function onItemUse(event)
{
	const buildItemId = event.itemStack.typeId;
	if (await getData(buildItemId) === undefined)
		return;

	await preloadBuild(event.source, buildItemId);
}

export async function onScriptEventReceive(event) 
{
	if (event.message === "confirm")
		await loadBuild(event.sourceEntity);
	else if (event.message === "cancel")
		await cancelLoadBuild(event.sourceEntity);
}

export async function preloadBuild(player, buildItemId)
{
	let playerLocation = Vector3.copyCenter(player.location);
	let rot = player.getRotation();
	let playerFacing = Vector3.rotationToFacing(rot);

	let build = gld.GetBuildById(buildItemId);
	let cornerOffset = (build.size - 1) / 2;
	
	let buildArea = gld.buildLoad[playerFacing];
	let borderOffset = Vector3.copyFloor(buildArea.border).addOffset(cornerOffset);
	let newCenterLocation = Vector3.copyFloor(player.location).add(borderOffset);
	
	let areaIsClear = await utils.verifyAir2(playerLocation.add(buildArea.NW), playerLocation.add(buildArea.SE));
	if (!areaIsClear)
	{
		await player.onScreenDisplay.setActionBar("§cSummon build failed - can't place confirm\\cancel buttons\n        §e[Tip] You need 3 empty blocks in front of you");
		return;
	}
	
	let corner1 = newCenterLocation.add({x: -cornerOffset, y: 0, z: -cornerOffset});
	let corner2 = newCenterLocation.add({x: cornerOffset,  y: 0, z: cornerOffset});
	
	let nearbyBuildBorders = await utils.getEntitiesInArea("goe_spa:build_border", player.dimension, corner1.toLocation(), corner2.toLocation(), "xz", undefined);
	if (nearbyBuildBorders && nearbyBuildBorders.length > 0)
	{
		player.onScreenDisplay.setActionBar("§cSummon build failed - You're too close to another build!");
		return;
	}
	
	await utils.runPlayerCommand(player, `clear @s ${buildItemId} 0 1`); // Remove item from inventory

	let  buildBorder = player.dimension.spawnEntity("goe_spa:build_border", newCenterLocation);
	await buildBorder.triggerEvent(`goe_spa:${build.size}x${build.size}`);
	await buildBorder.setDynamicProperty("goe_spa_build_id", buildItemId);
	await buildBorder.setDynamicProperty("goe_spa_build_degrees", buildArea.degrees);
	
	let textLocation = playerLocation.add(buildArea.text);
	let confirmLocation = playerLocation.add(buildArea.confirm);
	let cancelLocation = playerLocation.add(buildArea.cancel);

	let confirmText = player.dimension.spawnEntity("goe_spa:confirm_build", textLocation);
	await confirmText.teleport( textLocation, { facingLocation: buildArea.facing.add(textLocation).toLocation()} );

	let confirmButton = player.dimension.spawnEntity("goe_spa:confirm_button", confirmLocation);
	confirmButton.setDynamicProperty("goe_spa_build_id", buildItemId);
	await confirmButton.teleport( confirmLocation, { facingLocation: buildArea.facing.add(confirmLocation).toLocation()} );

	let cancelButton = player.dimension.spawnEntity("goe_spa:cancel_button", cancelLocation);
	cancelButton.setDynamicProperty("goe_spa_build_id", buildItemId);
	await cancelButton.teleport( cancelLocation, { facingLocation: buildArea.facing.add(cancelLocation).toLocation()} );
	
}



async function cancelLoadBuild(cancelButton) {;
	const buildId = await cancelButton.getDynamicProperty("goe_spa_build_id");
	const buildBorder = await utils.getEntityInLocation("goe_spa:build_border", cancelButton.dimension, cancelButton.location);
	await utils.runEntityCommand(cancelButton, `give @p ${buildId}`);
	await clearBuildEntities(buildBorder);
}

async function loadBuild(yesButton)
{
	let buildBorder = await utils.getEntityInLocation("goe_spa:build_border", yesButton.dimension, yesButton.location);
	let buildId = buildBorder.getDynamicProperty("goe_spa_build_id");
	let buildDegrees = buildBorder.getDynamicProperty("goe_spa_build_degrees");
	let centerLocation = buildBorder.location;
	let build = gld.GetBuildById(buildId);

	let cornerOffset = (build.size - 1) / 2;
	let corner1 = Vector3.copy(centerLocation).add({x: -cornerOffset, y: build.yOffset, z: -cornerOffset}).toLocation();
	let corner2 = Vector3.copy(centerLocation).add({x: cornerOffset,  y: 50, z: cornerOffset}).toLocation();

	let nearbyItems = await utils.getEntitiesInArea("minecraft:item", buildBorder.dimension, corner1, corner2, "xz", undefined);
	for (let item of nearbyItems)
		item.remove();


	//await utils.runMobCommand(buildBorder, `kill @e[type=item,x=~-${cornerOffset},y=~-1,z=~-4{cornerOffset},dx=${build.size},dy=40,dz=${build.size}]`);
	await utils.runMobCommand(buildBorder, `playsound goe_spa:building @a[r=30] ~ ~ ~ 100 1 1`);
	await utils.runMobCommand(buildBorder, `structure load ${buildId} ~-${cornerOffset} ~${build.yOffset} ~-${cornerOffset} ${buildDegrees}_degrees none layer_by_layer 3`);

	system.runTimeout(() => { loadBuildStep2(build, buildBorder, cornerOffset, corner1, corner2, buildDegrees); }, 33);
}

async function loadBuildStep2(build, buildBorder, cornerOffset, corner1, corner2, buildDegrees)
{
	
	let nearbyItems = await utils.getEntitiesInArea("minecraft:item", buildBorder.dimension, corner1, corner2, "xz", undefined);
	for (let item of nearbyItems)
		item.remove();
	await utils.runMobCommand(buildBorder, `structure load ${build.id} ~-${cornerOffset} ~${build.yOffset} ~-${cornerOffset} ${buildDegrees}_degrees none`);

	await clearBuildEntities(buildBorder);
}

// export async function hideMobs(yesButton, square) {
// 	let noButton = await game.getEntityInLocation("goe_spa:no_button", yesButton.dimension, yesButton.location);
// 	yesButton.triggerEvent("goe_spa:hide");
// 	noButton.triggerEvent("goe_spa:hide");
// }

export async function clearBuildEntities(border) {
	let confirmText = await utils.getEntityInLocation("goe_spa:confirm_build", border.dimension, border.location);
	let yesButton = await utils.getEntityInLocation("goe_spa:confirm_button", border.dimension, border.location);
	let noButton = await utils.getEntityInLocation("goe_spa:cancel_button", border.dimension, border.location);

	border.remove();
	confirmText.remove();
	yesButton.remove();
	noButton.remove();
}

export function getData(buildId)
{
	let buildIndex = gld.builds.findIndex((element) => element.id === buildId);
	return gld.builds[buildIndex];
}