import * as mc from '@minecraft/server';
import * as main from '../main';

export const EVENTID = 4;

const TEAPARTY_EVENT_REWARDS = [
	{ id: "minecraft:red_tulip", amount: 1, xp: 40 },
	{ id: "minecraft:diamond", amount: 3, xp: 30 },
	{ id: "minecraft:diamond_block", amount: 1, xp: 3 }
];

const TEAPARTY_EVENT_REWARDS_manuallyStart = [
	{ id: "minecraft:red_tulip", amount: 1, xp: 30 },
	{ id: "minecraft:red_tulip", amount: 1, xp: 30 },
	{ id: "minecraft:red_tulip", amount: 1, xp: 30 },
	{ id: "minecraft:red_tulip", amount: 1, xp: 30 },
	{ id: "minecraft:diamond", amount: 1, xp: 10 },
	{ id: null, amount: 0, xp: 29 }
];

export default class TeapartyEvent {
	eventID = EVENTID;
	name = "Tea Party";
	description = "text.blocklab_friend_exe:emoticon.teaparty";
	progress = "§c0/1";
	completeText = "text.blocklab_friend_exe:emoticon.teaparty_complete";
	completeTestCrepy = "text.blocklab_friend_exe:emoticon.teaparty_complete_creepy";
	failed = "text.blocklab_friend_exe:emoticon.teaparty_failed";
	ruined = "text.blocklab_friend_exe:emoticon.teaparty_ruined";
	glitch = "text.blocklab_friend_exe:emoticon.teaparty_glitch";
	time = 180;
	isActive = true;
	manuallyStart = false;
	complete = false;

	cake;
	cakeBlock;
	cakeLocation;
	bite_counter = 0;
	glitchTimer = 0;
	sit = false;
	completed = false;
	particleTime = 0;
	isDarknessEvent = false;

	constructor() { }

	activate(friend_exe) {
		if (this.manuallyStart == false)
			this.sendProgressMessage();
		friend_exe.triggerEvent("blocklab_friend_exe:find_cake");

		this.isDarknessEvent = main.Mood(friend_exe) <= 50;

	}

	deactivate(friend_exe) {
		this.isActive = false;
	}

	tick(friend_exe, mood, moodStage) {
		if (!this.isActive) return;
		this.time--;

		if ([60, 30].includes(this.time)) main.playTimeclockSound();

		if (this.sit) {
			this.orientToCake(friend_exe);
			friend_exe.runCommand("effect @s resistance 25 10 true");
			friend_exe.runCommand(`effect @s slowness 2 7 true`);

			this.particleTime--;

			if (this.particleTime == 0) {
				this.particleTime = 2;
				if (this.isDarknessEvent) {
					friend_exe.runCommand(`particle blocklab_friend_exe:aura`);
				} else {
					friend_exe.runCommand(`particle blocklab_friend_exe:dance`);
				}
			}

			if (this.isDarknessEvent)
				this.performGlitchEffects(friend_exe, mood);

			if (this.time === 0) {
				this.completed = true;
				this.triggerStandUp(friend_exe);
				mc.system.runTimeout(() => {
					friend_exe.triggerEvent("blocklab_friend_exe:stand_up");
				}, 20);
				this.cakeBlock.dimension.playSound("random.burp", this.cakeBlock.location);
				this.cakeBlock?.setType("air");
				this.isActive = false;
				this.complete = true;
				if (this.isDarknessEvent) {
					this.sendTranslatedMessage(this.completeTestCrepy);
				} else {
					this.sendTranslatedMessage(this.completeText);
				}

				main.PlayEmoteSound("happy");

				main.rewardPlayer(this.manuallyStart ? TEAPARTY_EVENT_REWARDS_manuallyStart : TEAPARTY_EVENT_REWARDS);
			} else if (!this.completed && this.time > 0 && (!this.cakeBlock?.isValid() || this.cakeBlock.typeId !== "minecraft:cake")) {
				this.stopAllSounds(friend_exe);
				this.triggerStandUp(friend_exe);
				mc.system.runTimeout(() => {
					friend_exe.triggerEvent("blocklab_friend_exe:stand_up");
				}, 20);
				main.setMood(friend_exe, mood - (this.manuallyStart ? 4 : 20));
				this.isActive = false;
				this.complete = false;
				this.sendTranslatedMessage(this.ruined);
				friend_exe.runCommand("effect @s clear resistance");
			}
		} else if (this.cake?.isValid) {
			const distance = main.Distance(friend_exe.location, this.cake.location);

			if (this.cakeBlock.typeId !== "minecraft:cake") {
				if (!this.manuallyStart) {
					this.sendTranslatedMessage(this.ruined);
					main.setMood(friend_exe, mood - 8);
				}
				if (this.cake) {
					this.cake.runCommand("teleport ~ ~ -30 ~");
					this.cake.kill();
				}
				main.PlayEmoteSound("unhappy")
				this.isActive = false;
				this.complete = false;
			} else if (distance <= 2) {
				friend_exe.runCommand("playsound mob.ai-friend.friend_exe_party_troete @a ~ ~1 ~");

				this.cake.runCommand("teleport ~ ~ -30 ~");
				this.cake.kill();
				this.particleTime = 3;
				if (!this.isDarknessEvent) {
					this.time = 23;
					mc.system.runTimeout(() => {
						friend_exe.runCommand("playsound mob.ai-friend.friend_exe_party_happy @a ~ ~1 ~ 0.2 1");
					}, 30);
				} else {
					this.time = 26;
					mc.system.runTimeout(() => {
						friend_exe.runCommand("playsound mob.ai-friend.friend_exe_party_unhappy @a ~ ~1 ~ 0.2 1");
					}, 30);
					mc.system.runTimeout(() => {
						friend_exe.runCommand("playanimation @s animation.blocklab_friend_exe.stage1_headtwitch.1");
					}, 180);
				}

				if (this.isDarknessEvent) {
					mc.system.runTimeout(() => {
						if (this.isActive)
							mc.world.getPlayers().forEach(player => {
								player.addEffect("darkness", 20 * 13);
							});
					}, 10 * 20);
				}

				friend_exe.triggerEvent("blocklab_friend_exe:remove_find_cake");
				friend_exe.triggerEvent("blocklab_friend_exe:sit_down");
				friend_exe.runCommand(`effect @s slowness 2 7 true`);
				mc.system.runTimeout(() => {
					friend_exe.triggerEvent("blocklab_friend_exe:sit_down_bool");
					if (moodStage <= 3 && Math.random() < 0.5) {
						friend_exe.runCommand("playanimation @s animation.blocklab_friend_exe.stage0_headshiver");
					}
				}, 10);

				this.sit = true;
				mc.system.runTimeout(() => this.eatCakeStep(), 60);
			}
		} else if (this.time === 0 && !this.completed) {
			if (!this.manuallyStart) {
				main.setMood(friend_exe, mood - 20);
				this.sendTranslatedMessage(this.failed);
				main.PlayEmoteSound("unhappy");
			}
			this.isActive = false;
		}
	}

	placeCake(event, player, friend_exe) {
		if (this.cake) return;
		this.cakeBlock = event.block;
		const cakePos = this.cakeBlock.center();
		const aiPos = friend_exe.location;
		this.cakeLocation = this.cakeBlock.center();

		friend_exe.runCommand(`particle blocklab_friend_exe:confetti ${cakePos.x} ${cakePos.y} ${cakePos.z}`);
		friend_exe.runCommand(`playsound firework.blast @a ${cakePos.x} ${cakePos.y} ${cakePos.z}`);

		const dir = { x: cakePos.x - aiPos.x, y: 0, z: cakePos.z - aiPos.z };
		let length = Math.sqrt(dir.x ** 2 + dir.z ** 2);
		if (length < 1) {
			dir.x = 1;
			dir.z = 0;
			length = 1;
		}
		const normalized = { x: dir.x / length, z: dir.z / length };
		const offsetDistance = 1;
		const spawnPos = {
			x: cakePos.x - normalized.x * offsetDistance,
			y: cakePos.y,
			z: cakePos.z - normalized.z * offsetDistance
		};

		const target = mc.world.getDimension(player.dimension.id).spawnEntity("blocklab_friend_exe:ai_friend_target", spawnPos);
		this.cake = target;
	}

	eatCakeStep() {
		if (!this.cakeBlock?.isValid() || this.cakeBlock.typeId !== "minecraft:cake") {
			return;
		}

		const state = this.cakeBlock.permutation.getAllStates();
		this.bite_counter = state["bite_counter"] ?? 0;

		if (this.bite_counter < 6) {
			this.bite_counter++;
			this.cakeBlock.setPermutation(
				this.cakeBlock.permutation.withState("bite_counter", this.bite_counter)
			);
			this.cakeBlock.dimension.playSound("random.eat", this.cakeBlock.location);

			if (this.isActive && this.sit) {
				mc.system.runTimeout(() => this.eatCakeStep(), 80);
			}
		}
	}

	orientToCake(friend_exe) {
		if (!this.cakeLocation) return;
		const dx = this.cakeLocation.x - friend_exe.location.x;
		const dz = this.cakeLocation.z - friend_exe.location.z;
		let yaw = Math.atan2(-dx, dz) * (180 / Math.PI);
		//let yaw = Math.atan2(dx, dz) * (180 / Math.PI);
		//if (yaw < 0) yaw += 360;
		let rot_y = friend_exe.getRotation().x;
		friend_exe.setRotation({ x: rot_y, y: yaw });
	}

	sendGlitchText = false;

	performGlitchEffects(friend_exe, mood) {
		if (this.glitchTimer > 0) {
			this.glitchTimer--;
			return;
		}

		if (Math.random() < (mood < 30 ? 0.8 : 0.5)) {
			const animations = [
				"animation.blocklab_friend_exe.stage1_armtwitch",
				"animation.blocklab_friend_exe.stage0_headshiver",
				"animation.blocklab_friend_exe.stage1_headtwitch.1"
			];
			const anim = animations[main.randInt(0, animations.length - 1)];
			friend_exe.runCommand(`playanimation @s ${anim}`);
			let glitch_text = this.glitch + String(main.randInt(1, 3))
			if (!this.sendGlitchText) {
				this.sendTranslatedMessage(glitch_text);
				this.sendGlitchText = true;
			}
		}

		this.glitchTimer = main.randInt(1, 2);
	}

	triggerStandUp(friend_exe) {
		friend_exe.triggerEvent("blocklab_friend_exe:stand_up_bool");
	}

	stopAllSounds(friend_exe) {
		friend_exe.runCommand("stopsound @a mob.ai-friend.friend_exe_party_happy");
		friend_exe.runCommand("stopsound @a mob.ai-friend.friend_exe_party_unhappy");
	}

	sendProgressMessage() {
		mc.world.sendMessage({
			rawtext: [
				{ translate: this.description },
				{ text: " §c(" },
				{ text: this.progress },
				{ text: "§c)" }
			]
		});
	}

	sendTranslatedMessage(key) {
		mc.world.sendMessage({ rawtext: [{ translate: key }] });
	}
}
