import { world, system, Player, EntityDamageCause } from "@minecraft/server";
import { fireBlaster } from './blasters'

system.afterEvents.scriptEventReceive.subscribe(event => {

	const { sourceEntity } = event;
	const id = event.id.split(':')[1]

	if (!sourceEntity) return;

	const { dimension, location } = sourceEntity;
	const headLocation = sourceEntity.getHeadLocation();
	const viewDirection = sourceEntity.getViewDirection();

	switch (id) {
		case 'mine_block': {

			const rayHit = sourceEntity.dimension.getBlockFromRay(headLocation, viewDirection, { includePassableBlocks: false, includeLiquidBlocks: false, maxDistance: 3 })
			if (!rayHit) return;

			let block = rayHit.block;
			const entityY = Math.floor(sourceEntity.location.y);

			if (block.y + 1 == entityY && !block.below()?.isAir) block = block.below(); // Prioritize breaking the lower block to allow the entity to crawl

			sourceEntity.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`)

			break;
		}
		case 'trap_burst': {

			const standingAbove = dimension.getBlock(location);
			if (!standingAbove) return;
			[standingAbove.west(), standingAbove.east(), standingAbove.north(), standingAbove.south()].forEach(block => { sourceEntity.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`) })

			break;
		}
		case 'shoot_machine_laser': {
			fireBlaster(sourceEntity, { damage: 3, deviation: 0.035, maxDistance: 64, soundId: "cc.blaster", pitch: 1.5, offset: [0, 1, 0], gravity: 0, speed: 1, particleId: 'compycraft_alien:laser_red' })
			break;
		}
		case 'shoot_martian_laser': {
			fireBlaster(sourceEntity, { damage: 3, deviation: 0.035, maxDistance: 64, soundId: "cc.blaster", pitch: 1.5, offset: [0, 1, 0], gravity: 0, speed: 1, particleId: 'compycraft_alien:laser_green' })
			break;
		}
		case 'has_sniper': {
			sourceEntity.isSneaking ? sourceEntity.runCommand("effect @s slowness 1 6 true") : null;
			break;
		}
	}

}, { namespaces: ['compycraft_alien'] })

world.afterEvents.entityHurt.subscribe(async event => {

	const { hurtEntity: player, damageSource } = event;
	const { damagingEntity: entity } = damageSource;

	if (!entity || !(player instanceof Player) || !entity.isValid()) return;

	const { dimension } = entity;

	switch (entity.typeId) {
		case 'compycraft_alien:mutant_entity':
		case 'compycraft_alien:entity': {

			entity.addEffect('slowness', (2.0417 - 0.5) * 20, { amplifier: 250, showParticles: false })
			player.teleport(player.location)
			const viewDirection = entity.getViewDirection()
			player.inputPermissions.movementEnabled = false;
			await system.waitTicks(1);
			player.applyKnockback(0, 0, 0, 0.2)
			await system.waitTicks(32);
			player.applyKnockback(-viewDirection.z, viewDirection.x, - 2, 0.3)
			player.applyDamage(5, { cause: EntityDamageCause.entityAttack })
			player.inputPermissions.movementEnabled = true;

			break;

		}
		case 'compycraft_alien:stomper': {
			entity.addEffect('slowness', 20, { amplifier: 255, showParticles: false })
			entity.runCommand('camerashake add @a[r=7] 0.6 0.3')
			let block = dimension.getBlock(player.location)
			if (!block) return;
			const neighbours = [block.west(), block.east(), block.north(), block.south(), block.offset({ x: 1, y: 0, z: -1 }), block.offset({ x: -1, y: 0, z: -1 }), block.offset({ x: 1, y: 0, z: 1 }), block.offset({ x: -1, y: 0, z: 1 })]
			neighbours.forEach(neighbour => {
				if (!neighbour) return;
				if (neighbour.getTags().some(tag => tag.endsWith('destructible'))) dimension.runCommand(`setblock ${neighbour.x} ${neighbour.y} ${neighbour.z} air destroy`)
				if (neighbour.above()?.getTags().some(tag => tag.endsWith('destructible'))) dimension.runCommand(`setblock ${neighbour.x} ${neighbour.y + 1} ${neighbour.z} air destroy`)
			})
		}
	}

}, { entityTypes: ['minecraft:player'] })