import { BlockPermutation, TimeOfDay, system, world, ItemStack, StructureAnimationMode, StructureRotation, StructureSaveMode } from "@minecraft/server";
import { checkBelowEntityDespawn, getStringBefore, checkLocation, getEntityRotation, getLocationbyFacingBlock, stringBetween, getGamemode, getElementPosition, getElementPositionArrayWithObjects } from "./helpers";
import { cameraCutscene } from "../events/camera";
import { ActionFormData } from "@minecraft/server-ui";

export class bellStaffHandler {
  static initialized = false;
  constructor() {
    this.initialize();
  }

  initialize() {
    if (!bellStaffHandler.initialized) {
      bellStaffHandler.initialized = true;
      this.processSubscriptions();
    } else {
    }
  }
  processSubscriptions() {
    let curTick = 0;
    const INIT_TIME = 0;

    system.runInterval(() => {
      try {
        if (curTick > INIT_TIME) {
          const allPlayers = world.getAllPlayers();
          allPlayers.forEach((player) => {
            if (!player.isValid()) return;
            else {
              checkBelowEntityDespawn(player, "bell_staff");
              this.holdBellStaff(player);
            }
          });
        }
        curTick++;
      } catch (e) {
        console.warn(e);
      }
    }, 0);
    world.afterEvents.itemUse.subscribe((event) => {
      const player = event.source;
      const typeId = player.typeId;
      if (typeId !== "minecraft:player") {
        return;
      }
      const holdingItem = player.getComponent("equippable").getEquipment("Mainhand");
      if (holdingItem == undefined) {
        return;
      }
      if (holdingItem.typeId == "hb_cb:bell_staff_item") this.spawnBellStaff(player, holdingItem);
    });
    system.afterEvents.scriptEventReceive.subscribe((event) => {
      if (event.sourceEntity == undefined) return;
      else {
        if (event.sourceEntity.typeId.includes("hb_cb:") && event.sourceEntity.typeId.includes("bell_staff")) {
          let bell_staff = event.sourceEntity;
          switch (event.id) {
            case "hb_cb:despawn_tick_hit_trigger":
              if (bell_staff.getProperty("hb_cb:despawn_tick") < 4) {
                bell_staff.runCommand("/playsound hb_cb:bell_staff_hit @a[r=10] ~~~ 1 1");
                bell_staff.runCommand("/playanimation @s animation.hb_cb.bell_staff.break");
                bell_staff.runCommand("/event entity @s hb_cb:despawn_tick_hit");
              }
              break;
            case "hb_cb:bell_staff_despawn":
              this.despawnBellStaff(bell_staff);
              break;
            case "hb_cb:ring_on_entity":
              world.getDimension(bell_staff.dimension.id).playSound("hb_cb:bell_staff_hit", bell_staff.location);
              bell_staff.runCommand("/playanimation @s animation.hb_cb.bell_staff.bell_ring");
              break;
            default:
              break;
          }
        }
      }
    });
  }
  handleItemHold(item, player) {
    if (!item) return; // Early exit if the item is undefined

    if (item.typeId == "hb_cb:bell_staff_item") {
      let nearbyEntities = world.getDimension(player.dimension.id).getEntities({
        families: ["monster"],
        maxDistance: 10,
        location: player.location,
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
        return;
      } else {
        if (system.currentTick % 40 == 0) {
          player.playSound("hb_cb:bell_staff_hit", player.location);
        }
      }
    } else return;
  }

  spawnBellStaff(player, item) {
    const raycastBlock = player.getBlockFromViewDirection({ includeLiquidBlocks: false, includePassableBlocks: false, maxDistance: 8 });
    if (raycastBlock == undefined) return;
    else {
      let gamemodeCreative = getGamemode(player, 1);
      const location = raycastBlock.block.location;
      const face = raycastBlock.face;

      let yRotation = getEntityRotation(player);
      let orientation;
      switch (yRotation) {
        case 0:
          orientation = "north";
          break;
        case 90:
          orientation = "east";
          break;
        case 180:
          orientation = "south";
          break;
        case 270:
          orientation = "west";
          break;

        default:
          break;
      }

      let placeLoc = getLocationbyFacingBlock(face, location);
      if (checkLocation(placeLoc, player, placeLoc, 1)) return;
      let block = world.getDimension(player.dimension.id).getBlock({ x: placeLoc.x, y: placeLoc.y, z: placeLoc.z });
      let block2 = world.getDimension(player.dimension.id).getBlock({ x: placeLoc.x, y: placeLoc.y + 1, z: placeLoc.z });
      block.setType("hb_cb:bell_staff_block");
      block2.setType("hb_cb:bell_staff_block");
      block.setPermutation(
        BlockPermutation.resolve("hb_cb:bell_staff_block", {
          "minecraft:block_face": orientation,
        })
      );
      block2.setPermutation(
        BlockPermutation.resolve("hb_cb:bell_staff_block", {
          "minecraft:block_face": orientation,
        })
      );

      // let bell_staff = world.getDimension(player.dimension.id).spawnEntity(item.typeId, placeLoc);
      player.runCommand("/summon " + getStringBefore(item.typeId, "_item") + " " + placeLoc.x.toString() + " " + placeLoc.y.toString() + " " + placeLoc.z.toString() + " " + yRotation.toString() + " 0");
      if (!gamemodeCreative) {
        player.runCommand("/clear @s " + item.typeId + " 0 1");
      }
    }
  }

  despawnBellStaff(bell_staff) {
    bell_staff.runCommand("/playanimation @s animation.hb_cb.bell_staff.despawn");
    system.waitTicks(1).then(() => {
      if (bell_staff.hasTag("hb_cb:start_block_despawn")) {
        bell_staff.teleport({ x: bell_staff.location.x, y: bell_staff.location.y + 0.5, z: bell_staff.location.z });
      }
      let block = world.getDimension(bell_staff.dimension.id).getBlock({ x: bell_staff.location.x, y: bell_staff.location.y, z: bell_staff.location.z });
      let block2 = world.getDimension(bell_staff.dimension.id).getBlock({ x: bell_staff.location.x, y: bell_staff.location.y + 1, z: bell_staff.location.z });
      block.setType("minecraft:air");
      block2.setType("minecraft:air");
      let spawnedItem = new ItemStack("hb_cb:bell_staff_item");
      world.getDimension(bell_staff.dimension.id).spawnItem(spawnedItem, bell_staff.location);
      bell_staff.remove();
    });
  }
  holdBellStaff(player) {
    const itemMainhand = player.getComponent("equippable").getEquipment("Mainhand");
    const itemOffhand = player.getComponent("equippable").getEquipment("Offhand");

    // Check if both hands are holding the ancient lantern
    const isMainhandLantern = itemMainhand && itemMainhand.typeId == "hb_cb:bell_staff_item";
    const isOffhandLantern = itemOffhand && itemOffhand.typeId == "hb_cb:bell_staff_item";

    if (isMainhandLantern && isOffhandLantern) {
      // //////////world.sendMessage("both");
      // player.playAnimation("animation.hb_cb.bell_staff.player_hold_both");
      this.handleItemHold(itemMainhand, player);
      return;
    } else if (isMainhandLantern) {
      // //////////world.sendMessage("isMainhandLantern");
      // player.playAnimation("animation.hb_cb.bell_staff.player_hold_mainhand");
      this.handleItemHold(itemMainhand, player);
    } else if (isOffhandLantern) {
      // //////////world.sendMessage("isOffhandLantern");
      // player.playAnimation("animation.hb_cb.bell_staff.player_hold_offhand");
      this.handleItemHold(itemOffhand, player);
    }
  }
}
