import { EquipmentSlot } from '@minecraft/server';
import { addOrReplaceItem } from '../util/utils';
import { McfSit } from './Global';
import { directionState, getBackBlock, getFrontBlock } from '../util/globalVariables';

const SINK_RULES = {
	"minecraft:water_bucket": {
		condition: (waterLevel, maxLevel) => waterLevel < maxLevel,
		newState: (waterLevel) => waterLevel + 1,
		sound: "bucket.empty_water",
		newItem: "minecraft:bucket"
	},
	"minecraft:bucket": {
		condition: (waterLevel, maxLevel) => waterLevel > 0,
		newState: (waterLevel) => waterLevel - 1,
		sound: "bucket.fill_water",
		newItem: "minecraft:water_bucket"
	},
	"minecraft:glass_bottle": {
		condition: (waterLevel, maxLevel) => waterLevel > 0,
		newState: (waterLevel) => Math.random() < 0.5 ? waterLevel - 1 : waterLevel,
		sound: "bottle.dragonbreath",
		newItem: "minecraft:potion",
		extraSound: "bucket.fill_water"
	},
	"minecraft:fill_water": {
		newState: (waterLevel) => waterLevel + 1,
		sound: "bucket.empty_water"
	}
};
export class McfSink {
	constructor() {
		this.onPlayerInteract = this.onPlayerInteract.bind(this);
	}
	static updateItem(player, dimension, rule) {
		if (rule.newItem) addOrReplaceItem(player, rule.newItem, 1);
		if (rule.extraSound) dimension.playSound(rule.extraSound, player.location);
	}
	static updateWaterLevel(block, dimension, newState, rule) {
		block.setPermutation(block.permutation.withState("mr:water_level", newState));
		dimension.playSound(rule.sound, block.center());
	}
	static findWaterBelow(block) {
		const checkWater = block.offset({ x: 0, y: -2, z: 0 });
		if (checkWater.typeId === "minecraft:water" && checkWater.permutation.getState("liquid_depth") === 0) return checkWater;
		return null;
	}
	onPlayerInteract(e, p) {
		const { player, block, dimension } = e;
		const item = player.getComponent("equippable")?.getEquipment(EquipmentSlot.Mainhand);
		const waterLevel = block.permutation.getState("mr:water_level");
		const maxLevel = p.params.max_level;
		const rule = SINK_RULES[item?.typeId];
		if (!rule && waterLevel < maxLevel) {
			const checkWater = McfSink.findWaterBelow(block);
			if (checkWater) {
				McfSink.updateWaterLevel(block, dimension, waterLevel + 1, SINK_RULES["minecraft:fill_water"]);
				McfSink.updateItem(player, dimension, SINK_RULES["minecraft:fill_water"]);
				checkWater.setType("minecraft:air");
			}
			return;
		}
		if (rule && rule.condition(waterLevel, maxLevel)) {
			McfSink.updateWaterLevel(block, dimension, rule.newState(waterLevel), rule);
			McfSink.updateItem(player, dimension, rule);
		}
	}
}
export class McfBath {
	constructor() {
		this.onPlayerInteract = this.onPlayerInteract.bind(this);
	}
	onPlayerInteract(e, p) {
		const { player, block, dimension } = e;
		const item = player.getComponent("equippable")?.getEquipment(EquipmentSlot.Mainhand);
		const waterLevel = block.permutation.getState("mr:water_level");
		const blockPart = block.permutation.getState("mc:block_parts");
		const maxLevel = p.params.max_level;
		const rule = SINK_RULES[item?.typeId];
		if (!rule && player.isSneaking)
			return McfSit.sit(block, player, "mr:chair_entity", { y: -0.2, z: blockPart === 1 ? -0.2 : 0, old: blockPart === 1 });
		const direction = block.permutation.getState(directionState);
		const otherPart = blockPart === 1 ? getBackBlock(block, direction) : getFrontBlock(block, direction);
		if (!rule && waterLevel < maxLevel && !player.isSneaking) {
			const checkWater = McfSink.findWaterBelow(block);
			if (checkWater) {
				[block, otherPart].forEach(b => McfSink.updateWaterLevel(b, dimension, waterLevel + 1, SINK_RULES["minecraft:fill_water"]));
				McfSink.updateItem(player, dimension, SINK_RULES["minecraft:fill_water"]);
				checkWater.setType("minecraft:air");
			}
			return;
		}
		if (rule && rule.condition(waterLevel, maxLevel)) {
			const newState = rule.newState(waterLevel);
			[block, otherPart].forEach(b => McfSink.updateWaterLevel(b, dimension, newState, rule));
			McfSink.updateItem(player, dimension, rule);
		}
	}
}
export class McfTap {
	onPlayerInteract(e) {
		const { player, block, dimension } = e;
		const item = player.getComponent("equippable")?.getEquipment(EquipmentSlot.Mainhand);
		const rule = SINK_RULES[item?.typeId];
		if (rule) {
			const checkWater = McfSink.findWaterBelow(block);
			if (checkWater) {
				rule.extraSound = rule.sound;
				McfSink.updateItem(player, dimension, rule);
				checkWater.setType("minecraft:air");
			} else {
				player.sendMessage("no hay agua XD");
			}
		}
	}
}