import { 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 ancientLanternHandler {
  static initialized = false;
  constructor() {
    this.initialize();
  }

  initialize() {
    if (!ancientLanternHandler.initialized) {
      ancientLanternHandler.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, "ancient_lantern");
              this.holdAncientLantern(player);
              this.sneakAbility(player);
            }
          });
        }
        curTick++;
      } catch (e) {
        console.warn(e);
      }
    }, 0);

    world.afterEvents.playerInteractWithEntity.subscribe((event) => {
      const player = event.player;
      const typeId = player.typeId;
      if (typeId !== "minecraft:player") {
        return;
      }
      if (event.target.typeId == "hb_cb:ancient_lantern") {
        const ancientLantern = event.target;
        //////////world.sendMessage("test interact");
        this.interactAbility(player, ancientLantern);
      } else return;
    });
    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:ancient_lantern_item") this.spawnAncientLantern(player, holdingItem);
    });
    system.afterEvents.scriptEventReceive.subscribe((event) => {
      if (event.sourceEntity == undefined) return;
      else {
        if (event.sourceEntity.typeId.includes("hb_cb:") && event.sourceEntity.typeId.includes("ancient_lantern")) {
          let ancient_lantern = event.sourceEntity;
          switch (event.id) {
            case "hb_cb:despawn_tick_hit_trigger":
              if (ancient_lantern.getProperty("hb_cb:despawn_tick") < 4) {
                ancient_lantern.runCommand("/playsound block.lantern.break @a[r=10] ~~~ 1 1");
                ancient_lantern.runCommand("/playanimation @s animation.hb_cb.ancient_lantern.break");
                ancient_lantern.runCommand("/event entity @s hb_cb:despawn_tick_hit");
              }
              break;
            case "hb_cb:ancient_lantern_despawn":
              this.despawnAncientLantern(ancient_lantern);
              break;
            default:
              break;
          }
        }
      }
    });
  }

  sneakAbility(player) {
    const item = player.getComponent("equippable").getEquipment("Mainhand");
    const itemOffhand = player.getComponent("equippable").getEquipment("Offhand");
    // Proceed only if at least one of them is defined
    if (item !== undefined || itemOffhand !== undefined) {
      // Your code here will execute if either item or itemOffhand is defined
      // Add your additional logic here
      this.handleItemSneak(item, player);
      this.handleItemSneak(itemOffhand, player);
    }
  }
  interactAbility(player, ancient_lantern) {
    if (ancient_lantern.getProperty("hb_cb:cooldown")) return;

    player.playSound("hb_cb:ancient_lantern_shot");
    world.getDimension(player.dimension.id).spawnEntity("hb_cb:ancient_lantern_use_entity_fake_light", ancient_lantern.location);
    ancient_lantern.runCommand("/event entity @s hb_cb:add_cooldown");
    try {
      ancient_lantern.dimension.spawnParticle("hb_cb:lantern_flash", { x: ancient_lantern.location.x, y: ancient_lantern.location.y + 0.3, z: ancient_lantern.location.z });
      ancient_lantern.dimension.spawnParticle("hb_cb:lantern_active", { x: ancient_lantern.location.x, y: ancient_lantern.location.y + 0.3, z: ancient_lantern.location.z });
    } catch (error) {}
    let nearbyEntities = world.getDimension(ancient_lantern.dimension.id).getEntities({
      exludeFamilies: ["hb_cb_ancient_lantern_fake_light", "hb_cb_ancient_lantern_use_fake_light", "hb_cb_roof", "hb_cb_tent"],
      excludeTypes: [
        "hb_cb:t1_black_roof",
        "hb_cb:t1_blue_roof",
        "hb_cb:t1_brown_roof",
        "hb_cb:t1_cyan_roof",
        "hb_cb:t1_gray_roof",
        "hb_cb:t1_green_roof",
        "hb_cb:t1_light_blue_roof",
        "hb_cb:t1_light_gray_roof",
        "hb_cb:t1_lime_roof",
        "hb_cb:t1_magenta_roof",
        "hb_cb:t1_orange_roof",
        "hb_cb:t1_pink_roof",
        "hb_cb:t1_purple_roof",
        "hb_cb:t1_red_roof",
        "hb_cb:t1_white_roof",
        "hb_cb:t1_yellow_roof",
        "hb_cb:t2_black_roof",
        "hb_cb:t2_blue_roof",
        "hb_cb:t2_brown_roof",
        "hb_cb:t2_cyan_roof",
        "hb_cb:t2_gray_roof",
        "hb_cb:t2_green_roof",
        "hb_cb:t2_light_blue_roof",
        "hb_cb:t2_light_gray_roof",
        "hb_cb:t2_lime_roof",
        "hb_cb:t2_magenta_roof",
        "hb_cb:t2_orange_roof",
        "hb_cb:t2_pink_roof",
        "hb_cb:t2_purple_roof",
        "hb_cb:t2_red_roof",
        "hb_cb:t2_white_roof",
        "hb_cb:t2_yellow_roof",
        "hb_cb:black_t1_tent",
        "hb_cb:blue_t1_tent",
        "hb_cb:brown_t1_tent",
        "hb_cb:cyan_t1_tent",
        "hb_cb:gray_t1_tent",
        "hb_cb:green_t1_tent",
        "hb_cb:light_blue_t1_tent",
        "hb_cb:light_gray_t1_tent",
        "hb_cb:lime_t1_tent",
        "hb_cb:magenta_t1_tent",
        "hb_cb:orange_t1_tent",
        "hb_cb:pink_t1_tent",
        "hb_cb:purple_t1_tent",
        "hb_cb:red_t1_tent",
        "hb_cb:white_t1_tent",
        "hb_cb:yellow_t1_tent",
        "hb_cb:black_t2_tent",
        "hb_cb:blue_t2_tent",
        "hb_cb:brown_t2_tent",
        "hb_cb:cyan_t2_tent",
        "hb_cb:gray_t2_tent",
        "hb_cb:green_t2_tent",
        "hb_cb:light_blue_t2_tent",
        "hb_cb:light_gray_t2_tent",
        "hb_cb:lime_t2_tent",
        "hb_cb:magenta_t2_tent",
        "hb_cb:orange_t2_tent",
        "hb_cb:pink_t2_tent",
        "hb_cb:purple_t2_tent",
        "hb_cb:red_t2_tent",
        "hb_cb:white_t2_tent",
        "hb_cb:yellow_t2_tent",
        "hb_cb:black_t3_tent",
        "hb_cb:blue_t3_tent",
        "hb_cb:brown_t3_tent",
        "hb_cb:cyan_t3_tent",
        "hb_cb:gray_t3_tent",
        "hb_cb:green_t3_tent",
        "hb_cb:light_blue_t3_tent",
        "hb_cb:light_gray_t3_tent",
        "hb_cb:lime_t3_tent",
        "hb_cb:magenta_t3_tent",
        "hb_cb:orange_t3_tent",
        "hb_cb:pink_t3_tent",
        "hb_cb:purple_t3_tent",
        "hb_cb:red_t3_tent",
        "hb_cb:white_t3_tent",
        "hb_cb:yellow_t3_tent",
        "minecraft:item",
        "minecraft:player",
        "minecraft:falling_block",
        "minecraft:xp_orb",
        "minecraft:arrow",
        "hb_cb:ancient_lantern",
        "hb_cb:diamond_poppy",
        "hb_cb:ancient_lantern",
        "hb_cb:kettle",
        "hb_cb:bench",
        "hb_cb:ancient_lantern_fake_light",
        "hb_cb:ancient_lantern_use_entity_fake_light",
        "hb_cb:ancient_lantern_use_fake_light",
        "hb_cb:7x7_backpack",
        "hb_cb:9x9_backpack",
        "hb_cb:11x11_backpack",
        "hb_cb:block_highlight",
      ],
      location: ancient_lantern.location,
      maxDistance: 10,
    });
    if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
      return;
    } else {
      nearbyEntities.forEach((foundEntity) => {
        try {
          foundEntity.dimension.spawnParticle("hb_cb:lantern_stun", foundEntity.getHeadLocation());
        } catch (error) {}
        if (foundEntity.typeId.includes("hb_cb:")) return;
        foundEntity.addEffect("slowness", 120, { amplifier: 250, showParticles: true });
      });
    }
  }

  handleItemSneak(item, player) {
    if (!item) return; // Early exit if the item is undefined

    if (item.typeId == "hb_cb:ancient_lantern_item") {
      const cooldownComp = item.getComponent("cooldown");
      if (!cooldownComp) return;

      if (player.getItemCooldown(cooldownComp.cooldownCategory) > 0) return;

      if (player.isSneaking) {
        cooldownComp.startCooldown(player);
        player.playSound("hb_cb:ancient_lantern_shot");
        world.getDimension(player.dimension.id).spawnEntity("hb_cb:ancient_lantern_use_fake_light", { x: player.location.x, y: player.location.y, z: player.location.z });
        world.getDimension(player.dimension.id).spawnEntity("hb_cb:ancient_lantern_use_fake_light", { x: player.location.x, y: player.location.y + 1, z: player.location.z });
        world.getDimension(player.dimension.id).spawnEntity("hb_cb:ancient_lantern_use_fake_light", { x: player.location.x, y: player.location.y + 2, z: player.location.z });
        try {
          player.dimension.spawnParticle("hb_cb:lantern_flash", { x: player.location.x, y: player.location.y + 0.3, z: player.location.z });
          player.dimension.spawnParticle("hb_cb:lantern_active", { x: player.location.x, y: player.location.y + 0.3, z: player.location.z });
        } catch (error) {}

        let nearbyEntities = world.getDimension(player.dimension.id).getEntities({
          exludeFamilies: ["hb_cb_ancient_lantern_fake_light", "hb_cb_ancient_lantern_use_fake_light", "hb_cb_roof", "hb_cb_tent"],
          excludeTypes: [
            "hb_cb:t1_black_roof",
            "hb_cb:t1_blue_roof",
            "hb_cb:t1_brown_roof",
            "hb_cb:t1_cyan_roof",
            "hb_cb:t1_gray_roof",
            "hb_cb:t1_green_roof",
            "hb_cb:t1_light_blue_roof",
            "hb_cb:t1_light_gray_roof",
            "hb_cb:t1_lime_roof",
            "hb_cb:t1_magenta_roof",
            "hb_cb:t1_orange_roof",
            "hb_cb:t1_pink_roof",
            "hb_cb:t1_purple_roof",
            "hb_cb:t1_red_roof",
            "hb_cb:t1_white_roof",
            "hb_cb:t1_yellow_roof",
            "hb_cb:t2_black_roof",
            "hb_cb:t2_blue_roof",
            "hb_cb:t2_brown_roof",
            "hb_cb:t2_cyan_roof",
            "hb_cb:t2_gray_roof",
            "hb_cb:t2_green_roof",
            "hb_cb:t2_light_blue_roof",
            "hb_cb:t2_light_gray_roof",
            "hb_cb:t2_lime_roof",
            "hb_cb:t2_magenta_roof",
            "hb_cb:t2_orange_roof",
            "hb_cb:t2_pink_roof",
            "hb_cb:t2_purple_roof",
            "hb_cb:t2_red_roof",
            "hb_cb:t2_white_roof",
            "hb_cb:t2_yellow_roof",
            "hb_cb:black_t1_tent",
            "hb_cb:blue_t1_tent",
            "hb_cb:brown_t1_tent",
            "hb_cb:cyan_t1_tent",
            "hb_cb:gray_t1_tent",
            "hb_cb:green_t1_tent",
            "hb_cb:light_blue_t1_tent",
            "hb_cb:light_gray_t1_tent",
            "hb_cb:lime_t1_tent",
            "hb_cb:magenta_t1_tent",
            "hb_cb:orange_t1_tent",
            "hb_cb:pink_t1_tent",
            "hb_cb:purple_t1_tent",
            "hb_cb:red_t1_tent",
            "hb_cb:white_t1_tent",
            "hb_cb:yellow_t1_tent",
            "hb_cb:black_t2_tent",
            "hb_cb:blue_t2_tent",
            "hb_cb:brown_t2_tent",
            "hb_cb:cyan_t2_tent",
            "hb_cb:gray_t2_tent",
            "hb_cb:green_t2_tent",
            "hb_cb:light_blue_t2_tent",
            "hb_cb:light_gray_t2_tent",
            "hb_cb:lime_t2_tent",
            "hb_cb:magenta_t2_tent",
            "hb_cb:orange_t2_tent",
            "hb_cb:pink_t2_tent",
            "hb_cb:purple_t2_tent",
            "hb_cb:red_t2_tent",
            "hb_cb:white_t2_tent",
            "hb_cb:yellow_t2_tent",
            "hb_cb:black_t3_tent",
            "hb_cb:blue_t3_tent",
            "hb_cb:brown_t3_tent",
            "hb_cb:cyan_t3_tent",
            "hb_cb:gray_t3_tent",
            "hb_cb:green_t3_tent",
            "hb_cb:light_blue_t3_tent",
            "hb_cb:light_gray_t3_tent",
            "hb_cb:lime_t3_tent",
            "hb_cb:magenta_t3_tent",
            "hb_cb:orange_t3_tent",
            "hb_cb:pink_t3_tent",
            "hb_cb:purple_t3_tent",
            "hb_cb:red_t3_tent",
            "hb_cb:white_t3_tent",
            "hb_cb:yellow_t3_tent",
            "minecraft:item",
            "minecraft:player",
            "minecraft:falling_block",
            "minecraft:xp_orb",
            "minecraft:arrow",
            "hb_cb:ancient_lantern",
            "hb_cb:diamond_poppy",
            "hb_cb:ancient_lantern",
            "hb_cb:kettle",
            "hb_cb:bench",
            "hb_cb:ancient_lantern_fake_light",
            "hb_cb:ancient_lantern_use_entity_fake_light",
            "hb_cb:ancient_lantern_use_fake_light",
            "hb_cb:7x7_backpack",
            "hb_cb:9x9_backpack",
            "hb_cb:11x11_backpack",
            "hb_cb:block_highlight",
          ],
          location: player.location,
          maxDistance: 10,
        });
        if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
          return;
        } else {
          nearbyEntities.forEach((foundEntity) => {
            try {
              foundEntity.dimension.spawnParticle("hb_cb:lantern_stun", foundEntity.getHeadLocation());
            } catch (error) {}
            if (foundEntity.typeId.includes("hb_cb:")) return;
            foundEntity.addEffect("slowness", 120, { amplifier: 250, showParticles: true });
          });
        }
      }
    } else return;
  }

  handleItemHold(item, player) {
    if (!item) {
      if (player.hasTag("hb_cb:trigger_light")) player.removeTag("hb_cb:trigger_light");
      return;
    } // Early exit if the item is undefined

    if (item.typeId.includes("hb_cb:ancient_lantern_item")) {
      player.addTag("hb_cb:trigger_light");
    } else {
      player.removeTag("hb_cb:trigger_light");
    }
  }

  spawnAncientLantern(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 placeLoc = getLocationbyFacingBlock(face, location);
      if (checkLocation(placeLoc, player, placeLoc, 0)) return;

      // let ancient_lantern = world.getDimension(player.dimension.id).spawnEntity(item.typeId, placeLoc);
      let yRotation = getEntityRotation(player);

      let block = world.getDimension(player.dimension.id).getBlock({ x: placeLoc.x, y: placeLoc.y, z: placeLoc.z });
      block.setType("hb_cb:ancient_lantern_light_block");
      player.runCommand("/setblock " + placeLoc.x.toString() + " " + placeLoc.y.toString() + " " + placeLoc.z.toString() + " hb_cb:ancient_lantern_light_block");
      // player.runCommand("/playsound block.lantern.place @a[r=10] ~~~ 1 1");
      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");
      }
    }
  }

  despawnAncientLantern(ancient_lantern) {
    ancient_lantern.runCommand("/playanimation @s animation.hb_cb.ancient_lantern.despawn");
    system.waitTicks(1).then(() => {
      if (ancient_lantern.isValid()) {
        if (ancient_lantern.hasTag("hb_cb:start_block_despawn")) {
          try {
            ancient_lantern.teleport({ x: ancient_lantern.location.x, y: ancient_lantern.location.y + 0.5, z: ancient_lantern.location.z });
          } catch (error) {}
        }
      }
      let block = world.getDimension(ancient_lantern.dimension.id).getBlock({ x: ancient_lantern.location.x, y: ancient_lantern.location.y, z: ancient_lantern.location.z });
      block.setType("minecraft:air");
      let spawnedItem = new ItemStack("hb_cb:ancient_lantern_item");
      world.getDimension(ancient_lantern.dimension.id).spawnItem(spawnedItem, ancient_lantern.location);
      ancient_lantern.remove();
    });
  }

  /*
TODO: check if both hands are filled with ancient lantern,
then play one animation for both hands,
if only one is ancient lantern then play that specific hand animation
  */

  holdAncientLantern(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:ancient_lantern_item";
    const isOffhandLantern = itemOffhand && itemOffhand.typeId == "hb_cb:ancient_lantern_item";

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