import { Direction, ItemStack, world } from '@minecraft/server';
import { decrementItemInHand } from '../util/utils';
import { COOKING_RECIPES } from './Recipes';

const GRILL_OFFSETS = [
	{ x: -0.2, y: 0.4, z: 0.2 },
	{ x: 0.2, y: 0.4, z: 0.2 },
	{ x: -0.2, y: 0.4, z: -0.2 },
	{ x: 0.2, y: 0.4, z: -0.2 },
];
export class McfGrill {
	constructor() {
		this.onPlayerInteract = this.onPlayerInteract.bind(this);
	}
	getGrillArea({ x, z }) {
		return (x < 0.5 ? (z < 0.5 ? 3 : 1) : (z < 0.5 ? 2 : 0));
	}
	manageGrillEntity(player, dimension, spawnPos, area) {
		const entities = dimension.getEntitiesAtBlockLocation(spawnPos);
		const hasGrillEntity = entities.some(entity => entity.getProperty("mr:area") === area);
		if (hasGrillEntity) return;
		const inventory = player.getComponent("inventory").container;
		const item = inventory.getItem(player.selectedSlotIndex);
		if (!item || !COOKING_RECIPES[item.typeId]) return;
		const cookedFood = COOKING_RECIPES[item.typeId];
		const food = dimension.spawnEntity("mr:food", spawnPos);
		food.setDynamicProperty("mr:grill_data", JSON.stringify({
			food: item.typeId,
			cooked: cookedFood
		}));
		food.setProperty("mr:area", area);
		food.setRotation({ x: 0, y: player.getRotation().y });
		dimension.playSound("block.itemframe.add_item", spawnPos);
		decrementItemInHand(player);
		food.runCommand(`replaceitem entity @s slot.weapon.mainhand 0 ${item.typeId}`);
	}
	onPlayerInteract(e) {
		const { player, block, dimension, faceLocation, face } = e;
		if (face !== Direction.Up) return;
		const area = this.getGrillArea(faceLocation);
		const blockCenter = block.center();
		const spawnPos = {
			x: blockCenter.x + GRILL_OFFSETS[area].x,
			y: blockCenter.y + GRILL_OFFSETS[area].y,
			z: blockCenter.z + GRILL_OFFSETS[area].z
		};
		this.manageGrillEntity(player, dimension, spawnPos, area);
	}
	static registerEvent() {
		world.afterEvents.dataDrivenEntityTrigger.subscribe(({ entity, eventId }) => {
			const foodData = entity.getDynamicProperty("mr:grill_data");
			if (!foodData) return;
			const { cooked, food } = JSON.parse(foodData);
			const { dimension, location } = entity;
			switch (eventId) {
				case "mr:final_cooked":
					entity.runCommand(`replaceitem entity @s slot.weapon.mainhand 0 ${cooked}`);
					break;
				case "mr:remove_food":
					dimension.spawnItem(new ItemStack(cooked, 1), location);
					entity.remove();
					break;
				case "mr:despawn":
					const shouldDropCooked = entity.getProperty("mr:flipped") && entity.getProperty("mr:cooked");
					dimension.spawnItem(new ItemStack(shouldDropCooked ? cooked : food, 1), location);
					entity.remove();
					break;
			}
		}, {
			entityTypes: [ "mr:food" ],
			eventTypes: [ "mr:final_cooked", "mr:remove_food", "mr:despawn" ]
		});
	}
}