import { world, system, Block, ItemStack } from '@minecraft/server';
const tallStructs = [
	'raigen:mini_mega_pine_tree_1',
	'raigen:mini_mega_pine_tree_2',
	'raigen:mini_mega_pine_tree_3',
	'raigen:mini_mega_pine_tree_4',
	'raigen:mini_mega_pine_tree_5',
	'raigen:mini_mega_pine_tree_6',
	'raigen:mini_end_spike_1',
	'raigen:mini_end_spike_2',
	'raigen:mini_end_spike_3',
	'raigen:mini_end_spike_4',
	'raigen:mini_end_spike_6',
	'raigen:mini_end_spike_7',
	'raigen:mini_end_spike_8',
	'raigen:mini_end_spike_9',
	'raigen:mini_end_spike_10',
	'raigen:mini_mega_spruce_tree_1',
	'raigen:mini_mega_spruce_tree_2',
	'raigen:mini_mega_spruce_tree_4',
	'raigen:mini_mega_spruce_tree_6',
	'raigen:mini_tall_jungle_tree_3',
	'raigen:mini_tall_jungle_tree_4',
	'raigen:mini_tall_jungle_tree_5',
	'raigen:mini_tall_jungle_tree_6',
	'raigen:mini_bastion_rampart_2',
	'raigen:mini_bastion_entrance_gate_1',
	'raigen:mini_bastion_entrance_gate_2',
	'raigen:mini_bastion_entrance_base_1',
	'raigen:mini_bastion_entrance_base_2',
	'raigen:mini_bastion_wall_base_1',
	'raigen:mini_bastion_wall_base_2',
	'raigen:mini_bastion_bottom_rampart_wall',
	'raigen:mini_bastion_mid_wall_main',
	'raigen:mini_bastion_lava_basin_rampart',
	'raigen:mini_bastion_mid_wall_side'
];
const longStructs = [
	'raigen:mini_bastion_bridge',
	'raigen:mini_ancient_city_entrance_path_2',
	'raigen:mini_ancient_city_entrance_path_3',
	'raigen:mini_ancient_city_entrance_path_4',
	'raigen:mini_ancient_city_entrance_pillars_5',
	'raigen:mini_ancient_city_entrance_pillars_6',
	'raigen:mini_ancient_city_entrance_pillars_7',
	'raigen:mini_ancient_city_entrance_pillars_8',
	'raigen:mini_ancient_city_center_1',
	'raigen:mini_ancient_city_center_2',
	'raigen:mini_ancient_city_center_3',
	'raigen:mini_ancient_city_bottom_wall_1',
	'raigen:mini_ancient_city_bottom_wall_2',
	'raigen:mini_ancient_city_sauna'
];
const repBlocks = [
	'minecraft:air',
	'minecraft:water',
	'minecraft:fire',
	'minecraft:snow_layer'
];
const allList = [

];
world.beforeEvents.itemUseOn.subscribe(ed =>{
	let item = ed.itemStack;
	let bp = ed.block;
	let sup = item.typeId.replaceAll('_item', '');
	if(!tallStructs.includes(sup) && !longStructs.includes(sup)) return;
	system.run(() =>{
		var dir = ed.blockFace;
		if(dir == 'Up'){
			let placed = bp.above();
			if(tallStructs.includes(placed.typeId)) tallFunct(placed, dir, bp.dimension, bp, sup);
			if(longStructs.includes(placed.typeId)) longFunct(placed, dir, bp.dimension, bp, sup);
		}
		if(dir == 'Down'){
			let placed = bp.below();
			if(tallStructs.includes(placed.typeId)) tallFunct(placed, dir, bp.dimension, bp, sup);
			if(longStructs.includes(placed.typeId)) longFunct(placed, dir, bp.dimension, bp, sup);
		}
		if(dir == 'North'){
			let placed = bp.north();
			if(tallStructs.includes(placed.typeId)) tallFunct(placed, dir, bp.dimension, bp, sup);
			if(longStructs.includes(placed.typeId)) longFunct(placed, dir, bp.dimension, bp, sup);
		}
		if(dir == 'East'){
			let placed = bp.east();
			if(tallStructs.includes(placed.typeId)) tallFunct(placed, dir, bp.dimension, bp, sup);
			if(longStructs.includes(placed.typeId)) longFunct(placed, dir, bp.dimension, bp, sup);
		}
		if(dir == 'South'){
			let placed = bp.south();
			if(tallStructs.includes(placed.typeId)) tallFunct(placed, dir, bp.dimension, bp, sup);
			if(longStructs.includes(placed.typeId)) longFunct(placed, dir, bp.dimension, bp, sup);
		}
		if(dir == 'West'){
			let placed = bp.west();
			if(tallStructs.includes(placed.typeId)) tallFunct(placed, dir, bp.dimension, bp, sup);
			if(longStructs.includes(placed.typeId)) longFunct(placed, dir, bp.dimension, bp, sup);
		}
	});
});

function tallFunct(placed, dir, dim, block, sup){
	let plRot = placed.permutation.getState('raigen:rotation');
	if(dir == 'Up'){
		if(!repBlocks.includes(placed.above().typeId) && !tallStructs.includes(placed.above().typeId)) { rmvBlock(dir, dim, block); return; }
		dim.runCommand(`setblock ${block.x} ${block.y + 2} ${block.z} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
	}
	if(dir == 'Down'){ rmvBlock(dir, dim, block); }
	if(dir == 'North'){
		if(!repBlocks.includes(placed.above().typeId) && !tallStructs.includes(placed.above().typeId)) { rmvBlock(dir, dim, block); return; }
		dim.runCommand(`setblock ${block.x} ${block.y + 1} ${block.z - 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
	}
	if(dir == 'East'){
		if(!repBlocks.includes(placed.above().typeId) && !tallStructs.includes(placed.above().typeId)) { rmvBlock(dir, dim, block); return; }
		dim.runCommand(`setblock ${block.x + 1} ${block.y + 1} ${block.z} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
	}
	if(dir == 'South'){
		if(!repBlocks.includes(placed.above().typeId) && !tallStructs.includes(placed.above().typeId)) { rmvBlock(dir, dim, block); return; }
		dim.runCommand(`setblock ${block.x} ${block.y + 1} ${block.z + 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
	}
	if(dir == 'West'){
		if(!repBlocks.includes(placed.above().typeId) && !tallStructs.includes(placed.above().typeId)) { rmvBlock(dir, dim, block); return; }
		dim.runCommand(`setblock ${block.x - 1} ${block.y + 1} ${block.z} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
	}
}

function longFunct(placed, dir, dim, block, sup){
	let plRot = placed.permutation.getState('raigen:rotation');
	if(dir == 'Up'){
		if(plRot == 2){
			if(!repBlocks.includes(placed.north().typeId) && !longStructs.includes(placed.north().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x} ${block.y + 1} ${block.z - 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 3){
			if(!repBlocks.includes(placed.south().typeId) && !longStructs.includes(placed.south().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x} ${block.y + 1} ${block.z + 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 4){
			if(!repBlocks.includes(placed.west().typeId) && !longStructs.includes(placed.west().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x - 1} ${block.y + 1} ${block.z} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 5){
			if(!repBlocks.includes(placed.east().typeId) && !longStructs.includes(placed.east().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x + 1} ${block.y + 1} ${block.z} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
	}
	if(dir == 'Down'){
		if(plRot == 2){
			if(!repBlocks.includes(placed.north().typeId) && !longStructs.includes(placed.north().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x} ${block.y - 1} ${block.z - 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 3){
			if(!repBlocks.includes(placed.south().typeId) && !longStructs.includes(placed.south().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x} ${block.y - 1} ${block.z + 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 4){
			if(!repBlocks.includes(placed.west().typeId) && !longStructs.includes(placed.west().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x - 1} ${block.y - 1} ${block.z} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 5){
			if(!repBlocks.includes(placed.east().typeId) && !longStructs.includes(placed.east().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x + 1} ${block.y - 1} ${block.z} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
	}
	if(dir == 'North'){
		if(plRot == 3 || plRot == 2){
			rmvBlock(dir, dim, block);
		}
		if(plRot == 4){
			if(!repBlocks.includes(placed.west().typeId) && !longStructs.includes(placed.west().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x - 1} ${block.y} ${block.z - 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 5){
			if(!repBlocks.includes(placed.east().typeId) && !longStructs.includes(placed.east().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x + 1} ${block.y} ${block.z - 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
	}
	if(dir == 'South'){
		if(plRot == 2 || plRot == 3){
			rmvBlock(dir, dim, block);
		}
		if(plRot == 4){
			if(!repBlocks.includes(placed.west().typeId) && !longStructs.includes(placed.west().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x - 1} ${block.y} ${block.z + 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 5){
			if(!repBlocks.includes(placed.east().typeId) && !longStructs.includes(placed.east().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x + 1} ${block.y} ${block.z + 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
	}
	if(dir == 'East'){
		if(plRot == 4 || plRot == 5){
			rmvBlock(dir, dim, block);
		}
		if(plRot == 2){
			if(!repBlocks.includes(placed.north().typeId) && !longStructs.includes(placed.north().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x + 1} ${block.y} ${block.z - 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 3){
			if(!repBlocks.includes(placed.south().typeId) && !longStructs.includes(placed.south().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x + 1} ${block.y} ${block.z + 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
	}
	if(dir == 'West'){
		if(plRot == 4 || plRot == 5){
			rmvBlock(dir, dim, block);
		}
		if(plRot == 2){
			if(!repBlocks.includes(placed.north().typeId) && !longStructs.includes(placed.north().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x - 1} ${block.y} ${block.z - 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
		if(plRot == 3){
			if(!repBlocks.includes(placed.south().typeId) && !longStructs.includes(placed.south().typeId)){ rmvBlock(dir, dim, block); return; }
			dim.runCommand(`setblock ${block.x - 1} ${block.y} ${block.z + 1} ${sup} ["raigen:type":1, "raigen:rotation":${plRot}]`);
		}
	}
}

function rmvBlock(dir, dim, block){
	if(dir == 'Up'){ dim.runCommand(`setblock ${block.x} ${block.y + 1} ${block.z} air destroy`); }
	if(dir == 'Down'){ dim.runCommand(`setblock ${block.x} ${block.y - 1} ${block.z} air destroy`); }
	if(dir == 'North'){ dim.runCommand(`setblock ${block.x} ${block.y} ${block.z - 1} air destroy`); }
	if(dir == 'East'){ dim.runCommand(`setblock ${block.x + 1} ${block.y} ${block.z} air destroy`); }
	if(dir == 'South'){ dim.runCommand(`setblock ${block.x} ${block.y} ${block.z + 1} air destroy`); }
	if(dir == 'West'){ dim.runCommand(`setblock ${block.x - 1} ${block.y} ${block.z} air destroy`); }
}

world.afterEvents.playerBreakBlock.subscribe(ed =>{
	let {block, player} = ed;
	let {location} = block;
	let {x, y, z} = location;
	system.run(() =>{
		var bTyp = ed.brokenBlockPermutation.getState('raigen:type');
		var bRot = ed.brokenBlockPermutation.getState('raigen:rotation');
		if(bTyp == null) return;
		if(tallStructs.includes(block.above().typeId) && bTyp == 0 && getType(block.above()) == 1 && bRot == getRotation(block.above())){
			player.runCommand(`fill ${x} ${y + 1} ${z} ${x} ${y + 1} ${z} air [] replace ${block.above().typeId}`);
		}
		if(tallStructs.includes(block.below().typeId) && bTyp == 1 && getType(block.below()) == 0 && bRot == getRotation(block.below())){
			player.runCommand(`fill ${x} ${y - 1} ${z} ${x} ${y - 1} ${z} air [] replace ${block.below().typeId}`);
		}
		
		if(longStructs.includes(block.north().typeId)){
			player.runCommand(`fill ${x} ${y} ${z - 1} ${x} ${y} ${z - 1} air [] replace ${block.north().typeId}`);
		}
		if(longStructs.includes(block.east().typeId)){
			player.runCommand(`fill ${x + 1} ${y} ${z} ${x + 1} ${y} ${z} air [] replace ${block.east().typeId}`);
		}
		if(longStructs.includes(block.south().typeId)){
			player.runCommand(`fill ${x} ${y} ${z + 1} ${x} ${y} ${z + 1} air [] replace ${block.south().typeId}`);
		}
		if(longStructs.includes(block.west().typeId)){
			player.runCommand(`fill ${x - 1} ${y} ${z} ${x - 1} ${y} ${z} air [] replace ${block.west().typeId}`);
		}
	});
});

function getType(b){ return b.permutation.getState('raigen:type'); }
function getRotation(b){ return b.permutation.getState('raigen:rotation'); }

system.afterEvents.scriptEventReceive.subscribe(event => {
  const eb = event.sourceEntity;
	let {x, y, z} = eb.location;
  if(event.id == 'raigen:build') {
		let struct = eb.dimension.getBlock({x, y, z}).typeId.toString().split(':')[1];
		let rot = eb.getComponent('mark_variant').value;
		switch(rot){
			case 0:
				rot = 180;
				break;
			case 1:
				rot = 270;
				break;
			case 2:
				rot = 0;
				break;
			case 3:
				rot = 90;
				break;
		}
		eb.runCommand(`structure load minigen:${struct} ~ ~ ~ ${rot}_degrees none`);
  }
})