import { Direction } from '@minecraft/server';
import { spawnEntityRotatedByBlock } from '../util/utils';
import { directionState } from '../util/globalVariables';

export class McfSwitchUse {
	onUse(e) {
		const { source, itemStack } = e;
		const block = source.getBlockFromViewDirection({ includeTags: [ "mc:is_unit" ], maxDistance: 20, includePassableBlocks: true, includeLiquidBlocks: false });
		if (itemStack && source.isSneaking && !block) {
			itemStack.clearDynamicProperties();
			itemStack.setLore(undefined);
			source.getComponent("inventory").container.setItem(source.selectedSlotIndex, itemStack);
			source.onScreenDisplay.setActionBar({ translate: "mcf.switch.remove_units" });
		}
	}
	onUseOn(e) {
		const { source, itemStack, block, blockFace } = e;
		if (!block.hasTag("mc:is_unit") && blockFace !== Direction.Up && blockFace !== Direction.Down) {
			const switchBlock = block[blockFace.toLowerCase()]();
			const dir = switchBlock.permutation.getState(directionState);
			if (switchBlock.isAir || !dir) return;
			const switchProp = itemStack.getDynamicProperty("mc:connected_units");
			const connectedUnits = switchProp ? JSON.parse(switchProp) : [];
			const validUnits = [];
			for (const u of connectedUnits) {
				const unitBlock = source.dimension.getBlock({ x: u.x, y: u.y, z: u.z });
				if (!unitBlock || !unitBlock.hasTag("mc:is_unit")) continue;
				if (Math.abs(u.x - switchBlock.x) + Math.abs(u.y - switchBlock.y) + Math.abs(u.z - switchBlock.z) > 64) continue;
				validUnits.push(u);
			}
			const switchEntity = spawnEntityRotatedByBlock("mc:empty", switchBlock, dir, { z: 0.4 });
			if (validUnits.length) switchEntity.setDynamicProperty("mc:connected_units", JSON.stringify(validUnits));
			const removed = connectedUnits.length - validUnits.length;
			if (removed > 0) source.onScreenDisplay.setActionBar({ translate: "mcf.switch.remove_on_place", with: [ `${removed}` ] });
		} else {
			if (!block.hasTag("mc:is_unit")) return;
			const data = itemStack.getDynamicProperty("mc:connected_units");
			const connectedUnits =  data ? JSON.parse(data) : [];
			if (connectedUnits.length >= 20) {
				source.onScreenDisplay.setActionBar({ translate: "mcf.switch.no_more_devices" });
				return;
			}
			const exists = connectedUnits.some(u => u.x === block.x && u.y === block.y && u.z === block.z);
			if (exists) {
				source.onScreenDisplay.setActionBar({ translate: "mcf.switch.already_connected" });
				return;
			}
			connectedUnits.push( {
				x: block.x,
				y: block.y,
				z: block.z
			} );
			const lore = itemStack.getLore() ?? [];
			if (lore.length < 5) {
				lore.push(`§7${block.typeId.split(":")[1].split("_").map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(" ")}`);
			} else {
				lore[5] = `§b+${connectedUnits.length - 5} Devices`
			}
			itemStack.setLore(lore);
			itemStack.setDynamicProperty("mc:connected_units", JSON.stringify(connectedUnits));
			source.getComponent("inventory").container.setItem(source.selectedSlotIndex, itemStack);
			source.onScreenDisplay.setActionBar({ translate: "%%1\n%%2 %%3", with: { rawtext: [ { translate: "mcf.switch.new_device" }, { translate: `tile.${block.typeId}.name` }, { text: `(${block.x}, ${block.y}, ${block.z})` } ] } });
		}
	}
}
export class McfSwitchPlace {
	beforeOnPlayerPlace(e) {
		e.permutationToPlace = e.permutationToPlace.withState(directionState, e.face.toLowerCase());
	}
	onPlayerInteract(e) {
		const { player, block, dimension } = e;
		const powered = block.permutation.getState("mc:powered");
		const newPowered = !powered
		block.setPermutation(block.permutation.withState("mc:powered", newPowered));
		const switchEntity = dimension.getEntitiesAtBlockLocation(block.location).find(en => en.typeId === "mc:empty");
		if (!switchEntity) return;
		const data = switchEntity.getDynamicProperty("mc:connected_units");
        const connectedUnits = data ? JSON.parse(data) : [];
        const validUnits = connectedUnits.filter(u => {
			try {
				const unitBlock = dimension.getBlock({ x: u.x, y: u.y, z: u.z });
				if (!unitBlock || !unitBlock.hasTag("mc:is_unit")) return false;
				unitBlock.setPermutation(unitBlock.permutation.withState("mc:powered", newPowered));
				return true;
			} catch {
				return false;
			}
		});
		dimension.playSound("mcf.light_switch", block.center(), { pitch: powered ? 0.8 : 1.0 })
		const removed = connectedUnits.length - validUnits.length;
		if (removed > 0) player.onScreenDisplay.setActionBar({ translate: "mcf.switch.remove_on_interact", with: [ `${removed}` ] });
		switchEntity.setDynamicProperty("mc:connected_units", JSON.stringify(validUnits));
	}
}
export class McfDeviceUse {
	onPlayerInteract(e) {
		const { dimension, block } = e;
		const powered = block.permutation.getState("mc:powered");
		block.setPermutation(block.permutation.withState("mc:powered", !powered))
		dimension.playSound("random.lever_click", block.center(), { pitch: powered ? 0.5 : 0.6 });
	}
}