import { world, ItemStack, BlockPermutation, ItemEnchantableComponent, MolangVariableMap } from '@minecraft/server';
import { decrementItemInHand, toggleBlockState } from './utils';
import { airBlocks, backBlockLocation, blockException, directions, frontBlockLocation, leftBlockLocation, rightBlockLocation, solidBlocks } from './globalVariables';


world.beforeEvents.worldInitialize.subscribe((e) => {
	e.blockComponentRegistry.registerCustomComponent("mc:stairs", new McStairs());
	e.blockComponentRegistry.registerCustomComponent("mc:block_connection", new McBlockConnection());
	e.blockComponentRegistry.registerCustomComponent("mc:fence_gate", new McFenceGate());

});

world.afterEvents.playerBreakBlock.subscribe((e) => {
	updateAdjacentBlocksIfNeeded(e.block);
})

class McFenceGate {
	onPlace(e) {
		const { block } = e;
		const direction = block.permutation.getState("minecraft:cardinal_direction");
		const rightBlock = block.offset(rightBlockLocation[direction]);
		const leftBlock = block.offset(leftBlockLocation[direction]);
		const isRightWall = rightBlock.typeId.includes("wall");
		const isLeftWall = leftBlock.typeId.includes("wall");
		const shouldEnableWall = isRightWall || isLeftWall;
		block.setPermutation(block.permutation.withState("mc:wall", shouldEnableWall));
	}
	onPlayerInteract(e) {
		toggleBlockState(e, "mc:open", "close.nether_wood_fence_gate", "open.nether_wood_fence_gate");
	}
}
function UpdateBlockConnection(block) {
	const states = block.permutation.getAllStates();
	let prefix = "";
	if (!block.typeId.includes("fence") && !block.typeId.includes("hedge") && !block.typeId.includes("bars_0")) return;
	for (const stateName in states) {
		if (stateName.includes(":n") || stateName.includes(":s") || stateName.includes(":w") || stateName.includes(":e")) {
			prefix = stateName.split(":")[0];
			break;
		}
	}
	if (!prefix) return;
	for (const direction in directions) {
		const offset = directions[direction];
		const adjacentBlock = block.offset(offset);
		const shouldConnect = shouldBlockConnect(adjacentBlock, offset);
		const stateName = `${prefix}:${direction[0]}`;

		if (stateName in states) {
			block.setPermutation(block.permutation.withState(stateName, shouldConnect ? 1 : 0));
		}
	}
}
function updateAdjacentBlocksIfNeeded(block) {
	try {
		for (const direction in directions) {
			const offset = directions[direction];
			const adjacentBlock = block.offset(offset);
			UpdateBlockConnection(adjacentBlock);
		}
	} catch (error) { }
}
world.afterEvents.playerPlaceBlock.subscribe((e) => {
	const { block } = e;
	updateAdjacentBlocksIfNeeded(block);
});

world.afterEvents.blockExplode.subscribe((e) => {
	const { block } = e;
	updateAdjacentBlocksIfNeeded(block);
});
function shouldBlockConnect(block, connectionVector) {
	// Special handling for fence gates
	if (block.typeId.includes("fence_gate")) {
		const gateDirection = block.permutation.getState("minecraft:cardinal_direction");
		const isNorthSouth = gateDirection === "north" || gateDirection === "south";

		// For north/south gates, only connect if there's x movement (east/west connections)
		// For east/west gates, only connect if there's z movement (north/south connections)
		return isNorthSouth ? (connectionVector.x !== 0) : (connectionVector.z !== 0);
	}

	return block.hasTag("is_solid") || block.hasTag("block_conection") ||
		(solidBlocks.some(connect => block.typeId.includes(connect)) &&
			!blockException.some(exception => block.typeId.includes(exception)) &&
			block.typeId.includes("minecraft:"));
}
class McBlockConnection {
	onPlace(e) {
		const { block } = e;
		UpdateBlockConnection(block);
		updateAdjacentBlocksIfNeeded(block);
	}
}

function UpdateStairs(block) {
	const direction = block.permutation.getState("minecraft:cardinal_direction");
	const frontBlock = block.offset(frontBlockLocation[direction]);
	const backBlock = block.offset(backBlockLocation[direction]);
	const isFrontStair = frontBlock.hasTag('mc.stairs');
	const isBackStair = backBlock.hasTag('mc.stairs');
	let shape = "straight";
	if (direction === "north") {
		if (isFrontStair && frontBlock.permutation.getState("minecraft:cardinal_direction") === "east") {
			shape = "outer_right";
		} else if (isFrontStair && frontBlock.permutation.getState("minecraft:cardinal_direction") === "west") {
			shape = "outer_left";
		} else if (isBackStair && !backBlock.permutation.getState("mc:shape").startsWith("outer") && backBlock.permutation.getState("minecraft:cardinal_direction") === "west") {
			shape = "inner_left";
		} else if (isBackStair && !backBlock.permutation.getState("mc:shape").startsWith("outer") && backBlock.permutation.getState("minecraft:cardinal_direction") === "east") {
			shape = "inner_right";
		}
	} else if (direction === "south") {
		if (isFrontStair && frontBlock.permutation.getState("minecraft:cardinal_direction") === "west") {
			shape = "outer_right";
		} else if (isFrontStair && frontBlock.permutation.getState("minecraft:cardinal_direction") === "east") {
			shape = "outer_left";
		} else if (isBackStair && !backBlock.permutation.getState("mc:shape").startsWith("outer") && backBlock.permutation.getState("minecraft:cardinal_direction") === "east") {
			shape = "inner_left";
		} else if (isBackStair && !backBlock.permutation.getState("mc:shape").startsWith("outer") && backBlock.permutation.getState("minecraft:cardinal_direction") === "west") {
			shape = "inner_right";
		}
	} else if (direction === "east") {
		if (isFrontStair && frontBlock.permutation.getState("minecraft:cardinal_direction") === "north") {
			shape = "outer_left";
		} else if (isFrontStair && frontBlock.permutation.getState("minecraft:cardinal_direction") === "south") {
			shape = "outer_right";
		} else if (isBackStair && !backBlock.permutation.getState("mc:shape").startsWith("outer") && backBlock.permutation.getState("minecraft:cardinal_direction") === "south") {
			shape = "inner_right";
		} else if (isBackStair && !backBlock.permutation.getState("mc:shape").startsWith("outer") && backBlock.permutation.getState("minecraft:cardinal_direction") === "north") {
			shape = "inner_left";
		}
	} else if (direction === "west") {
		if (isFrontStair && frontBlock.permutation.getState("minecraft:cardinal_direction") === "south") {
			shape = "outer_left";
		} else if (isFrontStair && frontBlock.permutation.getState("minecraft:cardinal_direction") === "north") {
			shape = "outer_right";
		} else if (isBackStair && !backBlock.permutation.getState("mc:shape").startsWith("outer") && backBlock.permutation.getState("minecraft:cardinal_direction") === "north") {
			shape = "inner_right";
		} else if (isBackStair && !backBlock.permutation.getState("mc:shape").startsWith("outer") && backBlock.permutation.getState("minecraft:cardinal_direction") === "south") {
			shape = "inner_left";
		}
	}
	block.setPermutation(block.permutation.withState("mc:shape", shape));
}
class McStairs {
	onPlace(e) {
		const { block } = e;
		UpdateStairs(block);
		const direction = block.permutation.getState("minecraft:cardinal_direction");
		const leftBlock = block.offset(leftBlockLocation[direction]);
		const rightBlock = block.offset(rightBlockLocation[direction]);
		if (leftBlock.hasTag("mc.stairs")) UpdateStairs(leftBlock);
		if (rightBlock.hasTag("mc.stairs")) UpdateStairs(rightBlock);
	}
	onPlayerDestroy(e) {
		const { block, destroyedBlockPermutation } = e;
		const direction = destroyedBlockPermutation.getState("minecraft:cardinal_direction");
		const leftBlock = block.offset(leftBlockLocation[direction]);
		const rightBlock = block.offset(rightBlockLocation[direction]);
		if (leftBlock.hasTag("mc.stairs")) UpdateStairs(leftBlock);
		if (rightBlock.hasTag("mc.stairs")) UpdateStairs(rightBlock);
	}
}
class McDoorInteraction {
	onPlayerInteract(e) {
		const { block, dimension } = e;
		const currentState = block.permutation.getState("mc:open");
		if (block.typeId.includes("top")) block.below().setPermutation(block.below().permutation.withState("mc:open", !currentState));
		if (block.typeId.includes("bottom")) block.above().setPermutation(block.above().permutation.withState("mc:open", !currentState));
		block.setPermutation(block.permutation.withState("mc:open", !currentState));
		dimension.playSound(currentState ? "close.nether_wood_door" : "open.nether_wood_door", block.center());
	}
}



function isPlayerLookingAtEntity(playerRotationY, entityRotationY) {
	let difference = playerRotationY - entityRotationY;
	if (difference > 180) {
		difference -= 360;
	} else if (difference < -180) {
		difference += 360;
	}
	return Math.abs(difference) > 90;
}
