import { system, world, ItemStack } from "@minecraft/server";

const recentlyConverted = new Set();
const fallingItems = new Set();

class Convertable {
	static cauldronItems = [
		{
			// Dirt
			"minecraft:dirt": { output: "minecraft:mud", wait: false },

			// Concrete Powder
			"minecraft:white_concrete_powder": {
				output: "minecraft:white_concrete",
				wait: false,
			},
			"minecraft:orange_concrete_powder": {
				output: "minecraft:orange_concrete",
				wait: false,
			},
			"minecraft:magenta_concrete_powder": {
				output: "minecraft:magenta_concrete",
				wait: false,
			},
			"minecraft:light_blue_concrete_powder": {
				output: "minecraft:light_blue_concrete",
				wait: false,
			},
			"minecraft:yellow_concrete_powder": {
				output: "minecraft:yellow_concrete",
				wait: false,
			},
			"minecraft:lime_concrete_powder": {
				output: "minecraft:lime_concrete",
				wait: false,
			},
			"minecraft:pink_concrete_powder": {
				output: "minecraft:pink_concrete",
				wait: false,
			},
			"minecraft:gray_concrete_powder": {
				output: "minecraft:gray_concrete",
				wait: false,
			},
			"minecraft:light_gray_concrete_powder": {
				output: "minecraft:light_gray_concrete",
				wait: false,
			},
			"minecraft:cyan_concrete_powder": {
				output: "minecraft:cyan_concrete",
				wait: false,
			},
			"minecraft:purple_concrete_powder": {
				output: "minecraft:purple_concrete",
				wait: false,
			},
			"minecraft:blue_concrete_powder": {
				output: "minecraft:blue_concrete",
				wait: false,
			},
			"minecraft:brown_concrete_powder": {
				output: "minecraft:brown_concrete",
				wait: false,
			},
			"minecraft:green_concrete_powder": {
				output: "minecraft:green_concrete",
				wait: false,
			},
			"minecraft:red_concrete_powder": {
				output: "minecraft:red_concrete",
				wait: false,
			},
			"minecraft:black_concrete_powder": {
				output: "minecraft:black_concrete",
				wait: false,
			},

			// Copper Block
			"minecraft:copper_block": {
				output: "minecraft:exposed_copper",
				wait: true,
			},
			"minecraft:exposed_copper": {
				output: "minecraft:weathered_copper",
				wait: true,
			},
			"minecraft:weathered_copper": {
				output: "minecraft:oxidized_copper",
				wait: true,
			},

			// Cut Copper
			"minecraft:cut_copper": {
				output: "minecraft:exposed_cut_copper",
				wait: true,
			},
			"minecraft:exposed_cut_copper": {
				output: "minecraft:weathered_cut_copper",
				wait: true,
			},
			"minecraft:weathered_cut_copper": {
				output: "minecraft:oxidized_cut_copper",
				wait: true,
			},

			// Cut Copper Slab
			"minecraft:cut_copper_slab": {
				output: "minecraft:exposed_cut_copper_slab",
				wait: true,
			},
			"minecraft:exposed_cut_copper_slab": {
				output: "minecraft:weathered_cut_copper_slab",
				wait: true,
			},
			"minecraft:weathered_cut_copper_slab": {
				output: "minecraft:oxidized_cut_copper_slab",
				wait: true,
			},

			// Cut Copper Stair
			"minecraft:cut_copper_stairs": {
				output: "minecraft:exposed_cut_copper_stairs",
				wait: true,
			},
			"minecraft:exposed_cut_copper_stairs": {
				output: "minecraft:weathered_cut_copper_stairs",
				wait: true,
			},
			"minecraft:weathered_cut_copper_stairs": {
				output: "minecraft:oxidized_cut_copper_stairs",
				wait: true,
			},

			// Copper Grate
			"minecraft:copper_grate": {
				output: "minecraft:exposed_copper_grate",
				wait: true,
			},
			"minecraft:exposed_copper_grate": {
				output: "minecraft:weathered_copper_grate",
				wait: true,
			},
			"minecraft:weathered_copper_grate": {
				output: "minecraft:oxidized_copper_grate",
				wait: true,
			},

			// Chiseled Copper
			"minecraft:chiseled_copper": {
				output: "minecraft:exposed_chiseled_copper",
				wait: true,
			},
			"minecraft:exposed_chiseled_copper": {
				output: "minecraft:weathered_chiseled_copper",
				wait: true,
			},
			"minecraft:weathered_chiseled_copper": {
				output: "minecraft:oxidized_chiseled_copper",
				wait: true,
			},

			// Lightning Rod
			"minecraft:lightning_rod": {
				output: "minecraft:exposed_lightning_rod",
				wait: true,
			},
			"minecraft:exposed_lightning_rod": {
				output: "minecraft:weathered_lightning_rod",
				wait: true,
			},
			"minecraft:weathered_lightning_rod": {
				output: "minecraft:oxidized_lightning_rod",
				wait: true,
			},

			// Copper Trapdoor
			"minecraft:copper_trapdoor": {
				output: "minecraft:exposed_copper_trapdoor",
				wait: true,
			},
			"minecraft:exposed_copper_trapdoor": {
				output: "minecraft:weathered_copper_trapdoor",
				wait: true,
			},
			"minecraft:weathered_copper_trapdoor": {
				output: "minecraft:oxidized_copper_trapdoor",
				wait: true,
			},

			// Copper Door
			"minecraft:copper_door": {
				output: "minecraft:exposed_copper_door",
				wait: true,
			},
			"minecraft:exposed_copper_door": {
				output: "minecraft:weathered_copper_door",
				wait: true,
			},
			"minecraft:weathered_copper_door": {
				output: "minecraft:oxidized_copper_door",
				wait: true,
			},

			// Copper Lantern
			"minecraft:copper_lantern": {
				output: "minecraft:exposed_copper_lantern",
				wait: true,
			},
			"minecraft:exposed_copper_lantern": {
				output: "minecraft:weathered_copper_lantern",
				wait: true,
			},
			"minecraft:weathered_copper_lantern": {
				output: "minecraft:oxidized_copper_lantern",
				wait: true,
			},

			// Copper Bulb
			"minecraft:copper_bulb": {
				output: "minecraft:exposed_copper_bulb",
				wait: true,
			},
			"minecraft:exposed_copper_bulb": {
				output: "minecraft:weathered_copper_bulb",
				wait: true,
			},
			"minecraft:weathered_copper_bulb": {
				output: "minecraft:oxidized_copper_bulb",
				wait: true,
			},

			// Copper Chest
			"minecraft:copper_chest": {
				output: "minecraft:exposed_copper_chest",
				wait: true,
			},
			"minecraft:exposed_copper_chest": {
				output: "minecraft:weathered_copper_chest",
				wait: true,
			},
			"minecraft:weathered_copper_chest": {
				output: "minecraft:oxidized_copper_chest",
				wait: true,
			},

			// Copper Golem Statue
			"minecraft:copper_golem_statue": {
				output: "minecraft:exposed_copper_golem_statue",
				wait: true,
			},
			"minecraft:exposed_copper_golem_statue": {
				output: "minecraft:weathered_copper_golem_statue",
				wait: true,
			},
			"minecraft:weathered_copper_golem_statue": {
				output: "minecraft:oxidized_copper_golem_statue",
				wait: true,
			},

			// Copper Bars
			"minecraft:copper_bars": {
				output: "minecraft:exposed_copper_bars",
				wait: true,
			},
			"minecraft:exposed_copper_bars": {
				output: "minecraft:weathered_copper_bars",
				wait: true,
			},
			"minecraft:weathered_copper_bars": {
				output: "minecraft:oxidized_copper_bars",
				wait: true,
			},

			// Copper Chain
			"minecraft:copper_chain": {
				output: "minecraft:exposed_copper_chain",
				wait: true,
			},
			"minecraft:exposed_copper_chain": {
				output: "minecraft:weathered_copper_chain",
				wait: true,
			},
			"minecraft:weathered_copper_chain": {
				output: "minecraft:oxidized_copper_chain",
				wait: true,
			},

			/*
			"namespace:input_block_name": {
				"output": "namespace:output_block_name",
				"wait": true/false
			},
			('wait' is for blocks with multiple conversions ie. copper to exposed to weathered)
			*/
		},
	];

	static isCauldron(block) {
		if (!block || block.typeId !== "minecraft:cauldron") return false;
		const fillLevel = block.permutation.getState("fill_level");
		const liquidType = block.permutation.getState("cauldron_liquid");
		return fillLevel >= 5 && liquidType === "water";
	}

	static getConversion(itemType) {
		for (const entry of Convertable.cauldronItems) {
			if (entry[itemType]) return entry[itemType];
		}
		return null;
	}
}

world.afterEvents.entitySpawn.subscribe((data) => {
	const item = data.entity
		? data.entity.typeId === "minecraft:item"
			? data.entity
			: null
		: null;
	if (!item) return;
	fallingItems.add(item);
});

system.runInterval(() => {
	for (const item of [...fallingItems]) {
		try {
			if (!item || !item.dimension) {
				fallingItems.delete(item);
				continue;
			}
			if (!item.isFalling) {
				const dimension = item.dimension;
				const itemStack = item.getComponent("item")?.itemStack;
				if (!itemStack) {
					fallingItems.delete(item);
					continue;
				}

				const block = dimension.getBlock(item.location);
				const conversionInfo = Convertable.getConversion(itemStack.typeId);
				if (!conversionInfo || !Convertable.isCauldron(block)) {
					fallingItems.delete(item);
					continue;
				}

				if (conversionInfo.wait && recentlyConverted.has(item.id)) {
					fallingItems.delete(item);
					continue;
				}

				const convertedItemType = conversionInfo.output;
				const newItemStack = new ItemStack(
					convertedItemType,
					itemStack.amount
				);
				const spawnLocation = item.location;
				item.remove();

				const spawnListener = world.afterEvents.entitySpawn.subscribe(
					(event) => {
						const newEntity = event.entity;
						if (
							newEntity.typeId === "minecraft:item" &&
							newEntity.location.Object === spawnLocation.Object &&
							conversionInfo.wait
						) {
							recentlyConverted.add(newEntity.id);
							system.runTimeout(
								() => recentlyConverted.delete(newEntity.id),
								40
							);
							world.afterEvents.entitySpawn.unsubscribe(spawnListener);
						}
					}
				);

				dimension.spawnItem(newItemStack, spawnLocation);
				dimension.playSound("cauldron.fillpotion", spawnLocation);
				dimension.spawnParticle("minecraft:crop_growth_emitter", {
					x: block.location.x + 0.5,
					y: block.location.y + 1,
					z: block.location.z + 0.5,
				});

				fallingItems.delete(item);
			}
		} catch (e) {
			fallingItems.delete(item);
		}
	}
}, 40);
