import { world, system, ItemStack, BlockPermutation, EquipmentSlot, EntityComponentTypes } from "@minecraft/server";
import * as mc from "@minecraft/server";
import { setCinematicActive } from "../state.js";
import { goodHubSummon } from "../hubs/good.js";

function toRadians(degrees) {
  return degrees * (Math.PI / 180);
}

let introMessage1 = {
  translate: "float_ad.introcinematic.good.1",
};
let introMessage2 = {
  translate: "float_ad.introcinematic.good.2",
};
let introMessage3 = {
  translate: "float_ad.introcinematic.good.3",
};
let introMessage4 = {
  translate: "float_ad.introcinematic.good.4",
};

export function thirdPersonFront(player, offset, isCameraReset) {
  if (isCameraReset) return; // Skip if camera is reset
  const rotation = player.getRotation();
  rotation.x = Math.min(90, Math.max(-90, rotation.x));
  const yawRadians = toRadians(rotation.y);
  const sinYaw = Math.sin(yawRadians);
  const cosYaw = Math.cos(yawRadians);
  const cameraPosition = {
    x: player.location.x - offset * sinYaw,
    y: player.location.y + 2, // Slightly above the player
    z: player.location.z + offset * cosYaw,
  };
  player.camera.setCamera("minecraft:free", {
    rotation: { x: rotation.x, y: rotation.y + 180 }, // Look at the player
    location: cameraPosition,
    easeOptions: {
      easeTime: 0.2,
      easeType: mc.EasingType.Linear,
    },
  });
}

export default function intro_good(npc) {
  const players = world.getPlayers();
  let closestPlayer = null;
  let closestDistance = Infinity;

  players.forEach((player) => {
    const distance = Math.sqrt(
      Math.pow(npc.location.x - player.location.x, 2) +
        Math.pow(npc.location.y - player.location.y, 2) +
        Math.pow(npc.location.z - player.location.z, 2)
    );
    if (distance < closestDistance) {
      closestDistance = distance;
      closestPlayer = player;
    }
  });

  if (closestPlayer) {
    // Custom camera logic to show the player levitating into the air
    system.run(() => {
      // Add initial fade
      closestPlayer.runCommand(`camera "${closestPlayer.name}" fade time 0.5 1 0.5`);
      closestPlayer.runCommand(`inputpermission set "${closestPlayer.name}" movement disabled`);
      closestPlayer.runCommand(`effect "${closestPlayer.name}" Resistance 10 10 true`);

      // Record player's initial position
      const initialPosition = { ...closestPlayer.location };

      // Set cinematic active flag
      setCinematicActive(true);

      // Delay setting the camera by 10 ticks to allow fade to complete
      system.runTimeout(() => {
        closestPlayer.runCommand(`camera "${closestPlayer.name}" set "${closestPlayer.name}"`);
        closestPlayer.runCommand(
          `summon float_ad:intro_cloud_good ${closestPlayer.location.x} ${closestPlayer.location.y} ${closestPlayer.location.z}`
        );
        closestPlayer.runCommand(`effect "${closestPlayer.name}" levitation 11 1 true`);
        closestPlayer.runCommand(`effect @e[type=float_ad:intro_cloud_good] levitation 11 1 true`);
        closestPlayer.runCommand(
          `fill ${closestPlayer.location.x - 1} ${closestPlayer.location.y + 1} ${closestPlayer.location.z - 1} ${
            closestPlayer.location.x + 1
          } ${closestPlayer.location.y + 6} ${closestPlayer.location.z + 1} air`
        );
        thirdPersonFront(closestPlayer, 7);

        let elapsedTime = 0;
        let isCameraReset = false;

        system.runTimeout(() => {
          closestPlayer.sendMessage(introMessage1);
        }, 10);

        system.runTimeout(() => {
          closestPlayer.sendMessage(introMessage2);
        }, 50);

        system.runTimeout(() => {
          closestPlayer.sendMessage(introMessage3);
        }, 110);

        system.runTimeout(() => {
          closestPlayer.sendMessage(introMessage4);
        }, 170);

        system.runTimeout(() => {
          // Check if the player is already wearing a helmet
          const equipment = closestPlayer.getComponent(EntityComponentTypes.Equippable);
          const helmet = equipment.getEquipment(EquipmentSlot.Head);
          if (helmet && helmet.typeId !== "float_ad:good_1_helmet") {
            // Drop the existing helmet at the initial position
            const itemStack = new ItemStack(helmet.typeId, helmet.amount);
            world.getDimension("overworld").spawnItem(itemStack, initialPosition);
          }
          // Set the new helmet if not already wearing good_1_helmet
          if (!helmet || helmet.typeId !== "float_ad:good_1_helmet") {
            const newHelmet = new ItemStack("float_ad:good_1_helmet", 1);
            equipment.setEquipment(EquipmentSlot.Head, newHelmet);
            const headPosition = closestPlayer.getHeadLocation();
            closestPlayer.runCommand(
              `particle float_ad:intro_equip_good ${headPosition.x} ${headPosition.y + 0.5} ${headPosition.z}`
            );
          }
        }, 60);

        // Update camera position to follow the player up as it levitates
        const intervalId = system.runInterval(() => {
          thirdPersonFront(closestPlayer, 7, isCameraReset);
          elapsedTime += 1;

          if (elapsedTime == 180) {
            closestPlayer.runCommand(`camera "${closestPlayer.name}" fade time 1 1 0.5`);
          }
          // Reset camera after 10 seconds
          if (elapsedTime >= 190) {
            system.clearRun(intervalId);
            closestPlayer.runCommand("event entity @e[type=float_ad:intro_cloud_good] float_ad:despawn");
            isCameraReset = true; // Set flag to true after camera reset

            // Teleport player back to initial position 0.5 seconds after fade
            system.runTimeout(() => {
              closestPlayer.runCommand(
                `tp "${closestPlayer.name}" ${initialPosition.x} ${initialPosition.y} ${initialPosition.z}`
              );
              goodHubSummon(closestPlayer);
              closestPlayer.runCommand(`inputpermission set "${closestPlayer.name}" movement enabled`);
              // Give player good_hub_pearl
              const inventory = closestPlayer.getComponent(EntityComponentTypes.Inventory).container;
              let hasPearl = false;

              for (let i = 0; i < inventory.size; i++) {
                const item = inventory.getItem(i);
                if (item && item.typeId === "float_ad:good_hub_pearl") {
                  hasPearl = true;
                  break;
                }
              }

              if (!hasPearl) {
                const evilHubPearl = new ItemStack("float_ad:good_hub_pearl", 1);
                evilHubPearl.setLore(["§8Use to Teleport to the Angel Hub Cloud"]);
                inventory.addItem(evilHubPearl);
              }
            }, 25);

            // Clear camera 0.5 seconds after fade
            system.runTimeout(() => {
              closestPlayer.runCommand(`camera "${closestPlayer.name}" clear`);
            }, 25);
            system.runTimeout(() => {
              // Reset cinematic active flag
              setCinematicActive(false);
            }, 80);
          }
        }, 1);
      }, 8);
    });
  }

  return closestPlayer;
}
