import { EquipmentSlot, system, world, ItemStack, StructureAnimationMode, StructureRotation, StructureSaveMode, BlockVolume } from "@minecraft/server";
import { checkLocation, getEntityRotation, getLocationbyFacingBlock, stringBetween, getGamemode } from "../utilities/helpers";

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

  initialize() {
    if (!backpackHandler.initialized) {
      backpackHandler.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 {
              // this.checkBpState(player);
              this.checkPropertyAndWriteLore(player);
              this.checkLoreAndWriteProperty(player);
              this.replaceArmorItem(player);
              // this.checkBlockBelow(player);
              this.handleArmorPieceSneak(player);
              this.handleArmorPiecePassive(player);
              this.PlaceCooldown(player);
            }
          });
        }
        curTick++;
      } catch (e) {
        console.warn(e);
      }
    }, 0);
    system.afterEvents.scriptEventReceive.subscribe((event) => {
      if (event.sourceEntity == undefined) {
        return;
      } else {
        if (event.sourceEntity.typeId.includes("hb_cb:") && event.sourceEntity.typeId.includes("backpack")) {
          let backpack = event.sourceEntity;
          let campSize = parseInt(stringBetween(backpack.typeId, "hb_cb:", "x"), 10) / 2 - 0.5;
          let campState = backpack.getProperty("hb_cb:camp_state");
          if (event.id == "hb_cb:box_hint" && backpack.hasTag("hb_cb:show_camp_box_hint")) {
            if (!campState && !backpack.hasTag("hb_cb:wait_camp_despawn_trigger")) {
              // world.sendMessage("BOX HINT");
              // world.sendMessage("here");
              // world.sendMessage("campState: " + campState.toString());
              // world.sendMessage("campStatetrigger: " + backpack.getProperty("hb_cb:camp_state_trigger").toString());
              backpack.runCommand('/titleraw @a[r=10] actionbar {"rawtext": [{"translate":"hb_cb.show_camp_box_hint_' + ((campSize + 0.5) * 2).toString() + "x" + ((campSize + 0.5) * 2).toString() + '"}]}');

              // //world.sendMessage(campSize.toString());
              const volume = new BlockVolume({ x: event.sourceEntity.location.x + campSize, y: event.sourceEntity.location.y + campSize * 2, z: event.sourceEntity.location.z + campSize }, { x: event.sourceEntity.location.x - campSize, y: event.sourceEntity.location.y, z: event.sourceEntity.location.z - campSize });
              // const volume = new BlockVolume({ x: event.sourceEntity.location.x + campSize, y: event.sourceEntity.location.y, z: event.sourceEntity.location.z + campSize }, { x: event.sourceEntity.location.x - campSize, y: event.sourceEntity.location.y, z: event.sourceEntity.location.z - campSize });
              const locations = volume.getBlockLocationIterator();
              for (const location of locations) {
                if (backpack.dimension.getBlock(location) == undefined) continue;
                if (backpack.dimension.getBlock(location).isAir || backpack.dimension.getBlock(location).typeId.includes("minecraft:light_block") || backpack.dimension.getBlock(location).typeId.includes("hb_cb:backpack_1_block") || backpack.dimension.getBlock(location).typeId.includes("hb_cb:backpack_2_block")) continue;
                else {
                  const airPlaceholder = backpack.dimension.getEntitiesAtBlockLocation(backpack.dimension.getBlock(location));
                  if (!airPlaceholder[0]) {
                    const loc = backpack.dimension.getBlock(location);
                    // world.sendMessage("spawn here!");
                    backpack.dimension.spawnEntity("hb_cb:block_highlight", { x: loc.x + 0.5, y: loc.y, z: loc.z + 0.5 });
                  }
                }
              }
            } else backpack.runCommand('/titleraw @a[r=10] actionbar {"rawtext": [{"translate":"hb_cb.pack_up_camp_box_hint"}]}');
            return;
          }
          if (event.id == "hb_cb:first_hit_camp_state_trigger") {
            if (backpack.hasTag("hb_cb:delay_interact")) {
              // world.sendMessage("#############delay returnf");
              return;
            }
            // world.sendMessage("hb_cb:first_hit_camp_state_trigger");
            backpack.runCommand("/playsound step.cloth @a[r=10] ~~~ 1 1");
            backpack.playAnimation("entity_first_hit_camp");
            backpack.addTag("hb_cb:show_camp_box_hint");
            return;
          }
          if (event.id == "hb_cb:second_hit_camp_state_trigger") {
            if (backpack.hasTag("hb_cb:delay_interact")) {
              // world.sendMessage("#############delay returnf");
              return;
            }
            // world.sendMessage("hb_cb:second_hit_camp_state_trigger");
            backpack.runCommand("/playsound step.cloth @a[r=10] ~~~ 1 1");
            this.secondHitCampStateChange(backpack, campSize, campState);
            return;
          }
          if (event.id == "hb_cb:first_hit_camp_despawn_trigger") {
            if (backpack.hasTag("hb_cb:delay_interact")) {
              // world.sendMessage("#############delay returnf");
              return;
            }
            // world.sendMessage("hb_cb:first_hit_camp_despawn_trigger");
            backpack.runCommand("/playsound step.cloth @a[r=10] ~~~ 1 1");
            if (campState) {
              backpack.playAnimation("break");
              backpack.runCommand('/tellraw @a[r=10] {"rawtext": [{"translate":"hb_cb.despawn_camp_hint"}]}');
            } else {
              this.secondHitCampDespawn(backpack, campSize, campState);
            }
            return;
          }
          if (event.id == "hb_cb:second_hit_camp_despawn_trigger") {
            if (backpack.hasTag("hb_cb:delay_interact")) {
              // world.sendMessage("#############delay returnf");
              return;
            }
            // world.sendMessage("hb_cb:second_hit_camp_despawn_trigger");
            this.secondHitCampDespawn(backpack, campSize, campState);
          }
        }
      }
    });
    world.afterEvents.itemStartUse.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.includes("hb_cb:") && holdingItem.typeId.includes("bp") && holdingItem.typeId.includes("fake")) {
        const raycastBlock = player.getBlockFromViewDirection({ includeLiquidBlocks: false, includePassableBlocks: false, maxDistance: 8 });
        if (raycastBlock == undefined) {
          let armorItem = player.getComponent("equippable").getEquipment(EquipmentSlot.Chest);

          let newArmorItem = new ItemStack(holdingItem.typeId.replace("_fake", ""));
          let campStructureName = holdingItem.getDynamicProperty("hb_cb_camp_name");
          newArmorItem.setDynamicProperty("hb_cb_camp_name", campStructureName);
          let backpackStructureName = holdingItem.getDynamicProperty("hb_cb_backpack_name");
          newArmorItem.setDynamicProperty("hb_cb_backpack_name", backpackStructureName);
          player.getComponent("equippable").setEquipment(EquipmentSlot.Chest, newArmorItem);

          if (armorItem == undefined) {
            player.getComponent("equippable").setEquipment("Mainhand", null);
            return;
          } else {
            if (holdingItem.typeId.includes("hb_cb:") && holdingItem.typeId.includes("bp")) {
              let oldArmor = new ItemStack(armorItem.typeId.replace("_item", "_fake_item"));
              let campStructureName = holdingItem.getDynamicProperty("hb_cb_camp_name");
              oldArmor.setDynamicProperty("hb_cb_camp_name", campStructureName);
              let backpackStructureName = holdingItem.getDynamicProperty("hb_cb_backpack_name");
              oldArmor.setDynamicProperty("hb_cb_backpack_name", backpackStructureName);
              player.getComponent("equippable").setEquipment("Mainhand", oldArmor);

              if (armorItem.typeId.includes("hb_cb:") && armorItem.typeId.includes("bp")) {
                let newFakeItem = new ItemStack(armorItem.typeId.replace("_item", "_fake_item"));
                let campStructureName = armorItem.getDynamicProperty("hb_cb_camp_name");
                newFakeItem.setDynamicProperty("hb_cb_camp_name", campStructureName);
                let backpackStructureName = armorItem.getDynamicProperty("hb_cb_backpack_name");
                newFakeItem.setDynamicProperty("hb_cb_backpack_name", backpackStructureName);
                player.getComponent("equippable").setEquipment("Mainhand", newFakeItem);
              }
            } else {
              player.getComponent("equippable").setEquipment("Mainhand", armorItem);
            }
            return;
          }
        } else {
          this.backpackSpawn(player, holdingItem);
        }
      }
    });
  }

  PlaceCooldown(player) {
    if (player.hasTag("hb_cb:backpack_place_cd")) {
      system.waitTicks(40).then(() => {
        player.removeTag("hb_cb:backpack_place_cd");
      });
    }
  }
  replaceArmorItem(player) {
    for (let i = 0; i < 36; i++) {
      const item = player.getComponent("inventory").container.getItem(i);
      // const currentSlot = player.getComponent("inventory").container.getSlot(i);
      if (item == undefined) {
        continue;
      }
      if (item.typeId.includes("hb_cb:") && item.typeId.includes("bp") && !item.typeId.includes("fake")) {
        let newArmorItem = new ItemStack(item.typeId.replace("_item", "_fake_item"));
        let campStructureName = item.getDynamicProperty("hb_cb_camp_name");
        newArmorItem.setDynamicProperty("hb_cb_camp_name", campStructureName);
        let backpackStructureName = item.getDynamicProperty("hb_cb_backpack_name");
        newArmorItem.setDynamicProperty("hb_cb_backpack_name", backpackStructureName);
        player.getComponent("inventory").container.setItem(i, newArmorItem);

        // player.getComponent("inventory").setItem(inventory, new ItemStack("apple"));
      }
      // if (item.typeId.includes("hb_cb:") && item.typeId.includes("bp") && item.typeId.includes("fake")) {
      //   let campStructureName = item.getDynamicProperty("hb_cb_camp_name") ? item.getDynamicProperty("hb_cb_camp_name") : "empty CAMP";

      //   // player.getComponent("inventory").setItem(inventory, new ItemStack("apple"));
      // }
    }
  }
  checkPropertyAndWriteLore(player) {
    if (system.currentTick % 20 == 0) {
      // world.sendMessage("checkPropertyAndWriteLore");
      for (let i = 0; i < 36; i++) {
        const item = player.getComponent("inventory").container.getItem(i);
        const currentSlot = player.getComponent("inventory").container.getSlot(i);
        if (item == undefined) {
          continue;
        }
        let loreFlag = 0;
        let newLoreArray = [];
        if (item.typeId.includes("hb_cb:") && item.typeId.includes("bp") && item.typeId.includes("fake")) {
          // //world.sendMessage("bp found");
          let oldLore = item.getLore() ?? []; // Get the existing lore or an empty array
          // //world.sendMessage(oldLore.toString());
          oldLore.forEach((loreItem) => {
            const formatedLore = this.removeLoreMarkers(loreItem);
            // //world.sendMessage(formatedLore.toString());
            if (formatedLore.includes("hb_cb:") || formatedLore.includes("TEST EMPTY")) {
              newLoreArray.push(formatedLore);
              loreFlag++;
            }
          });
          if (loreFlag == 2) {
            // world.sendMessage("2 lores found from prop");
            continue;
          } else {
            // //world.sendMessage("added 2 lores from prop");
            let campStructureName = item.getDynamicProperty("hb_cb_camp_name");
            let backpackStructureName = item.getDynamicProperty("hb_cb_backpack_name");
            if (campStructureName == undefined && backpackStructureName == undefined) {
              continue;
            }
            // //world.sendMessage(campStructureName.toString());
            // //world.sendMessage(backpackStructureName.toString());
            oldLore.push(`§k§0CAMP_${campStructureName}§r`);
            oldLore.push(`§k§0PACK_${backpackStructureName}§r`);
            // world.sendMessage("CAMP_$" + campStructureName);
            // world.sendMessage("PACK_$" + backpackStructureName);
            item.setDynamicProperty("hb_cb_camp_name", campStructureName);
            item.setDynamicProperty("hb_cb_backpack_name", backpackStructureName);
            item.setLore(oldLore);
            player.getComponent("inventory").container.setItem(i, item);
          }
        }
      }
    }
  }
  checkLoreAndWriteProperty(player) {
    if (system.currentTick % 20 == 0) {
      // world.sendMessage("checkLoreAndWriteProperty");
      for (let i = 0; i < 36; i++) {
        const item = player.getComponent("inventory").container.getItem(i);
        const currentSlot = player.getComponent("inventory").container.getSlot(i);
        if (item == undefined) {
          continue;
        }
        let loreFlag = 0;
        let newLoreArray = [];
        if (item.typeId.includes("hb_cb:") && item.typeId.includes("bp") && item.typeId.includes("fake")) {
          let campStructureName = item.getDynamicProperty("hb_cb_camp_name");
          let backpackStructureName = item.getDynamicProperty("hb_cb_backpack_name");
          // //world.sendMessage(campStructureName.toString());
          // //world.sendMessage(backpackStructureName.toString());
          if (campStructureName == undefined && backpackStructureName == undefined) {
            //world.sendMessage("props not found from lore");
            let oldLore = item.getLore() ?? []; // Get the existing lore or an empty array
            oldLore.forEach((loreItem) => {
              if (loreItem.includes("hb_cb:")) {
                newLoreArray.push(loreItem);
                loreFlag++;
              }
            });
            if (loreFlag == 2) {
              //world.sendMessage("2 lores found from lore");
              item.setDynamicProperty("hb_cb_camp_name", this.removeLoreMarkers(newLoreArray[0]));
              item.setDynamicProperty("hb_cb_backpack_name", this.removeLoreMarkers(newLoreArray[1]));
              item.setLore(oldLore);
              player.getComponent("inventory").container.setItem(i, item);
            } else {
              // //world.sendMessage("added 2 lores from lore");
              return;
            }
          }
        }
      }
    }
  }
  handleItem(player) {
    const holdingItem = player.getComponent("equippable").getEquipment("Mainhand");

    if (!holdingItem) return; // Early exit if the item is undefined

    // if (holdingItem.typeId.includes("hb_cb:") && holdingItem.typeId.includes("bp")) {
    //   if (player.isSneaking && !player.hasTag("hb_cb:backpack_place_cd")) {
    //     this.backpackSpawn(player, holdingItem);
    //   }
    // } else return;
  }
  checkBlockBelow(player) {
    const nearbyEntities = world.getDimension(player.dimension.id).getEntities({
      families: ["hb_cb_backpack"],
      location: player.location,
      maxDistance: 200,
    });
    nearbyEntities.forEach((entity) => {
      if (!entity.isValid() || entity == undefined) return;
      else {
        let entityBlockBelow = { x: entity.location.x, y: entity.location.y - 0.5, z: entity.location.z };
        let blockBelow = world.getDimension(entity.dimension.id).getBlock(entityBlockBelow);
        if (!blockBelow) return;
        if (
          blockBelow.isAir ||
          blockBelow.isLiquid ||
          (blockBelow.typeId.includes("minecraft:") &&
            (blockBelow.typeId.includes("scaffolding") ||
              blockBelow.typeId.includes("ladder") ||
              blockBelow.typeId.includes("trapdoor") ||
              blockBelow.typeId.includes("coral") ||
              blockBelow.typeId.includes("dripstone") ||
              blockBelow.typeId.includes("bamboo") ||
              blockBelow.typeId.includes("reeds") ||
              blockBelow.typeId.includes("pitcher") ||
              blockBelow.typeId.includes("pink_petals") ||
              blockBelow.typeId.includes("deadbush") ||
              blockBelow.typeId.includes("amethyst_cluster") ||
              blockBelow.typeId.includes("spore_blossom") ||
              blockBelow.typeId.includes("dripleaf") ||
              blockBelow.typeId.includes("turtle_egg") ||
              blockBelow.typeId.includes("sniffer_egg") ||
              blockBelow.typeId.includes("frogspawn") ||
              blockBelow.typeId.includes("cobweb") ||
              blockBelow.typeId.includes("bed") ||
              blockBelow.typeId.includes("brewing_stand") ||
              blockBelow.typeId.includes("lectern") ||
              blockBelow.typeId.includes("grind_stone") ||
              blockBelow.typeId.includes("enchanting_table") ||
              blockBelow.typeId.includes("campfire") ||
              blockBelow.typeId.includes("candle") ||
              blockBelow.typeId.includes("sea_pickles") ||
              blockBelow.typeId.includes("sign") ||
              blockBelow.typeId.includes("skull") ||
              blockBelow.typeId.includes("conduit") ||
              blockBelow.typeId.includes("stone_cutter") ||
              blockBelow.typeId.includes("end_rod") ||
              blockBelow.typeId.includes("lightning_rod") ||
              blockBelow.typeId.includes("end_crystal") ||
              blockBelow.typeId.includes("torch") ||
              blockBelow.typeId.includes("redstone_wire") ||
              blockBelow.typeId.includes("lever") ||
              blockBelow.typeId.includes("repeater") ||
              blockBelow.typeId.includes("comparator") ||
              blockBelow.typeId.includes("sensor") ||
              blockBelow.typeId.includes("piston_head") ||
              blockBelow.typeId.includes("banner") ||
              blockBelow.typeId.includes("chain") ||
              blockBelow.typeId.includes("propagule") ||
              blockBelow.typeId.includes("sapling") ||
              blockBelow.typeId.includes("lantern") ||
              blockBelow.typeId.includes("bell") ||
              blockBelow.typeId.includes("pressure") ||
              blockBelow.typeId.includes("fence_gate") ||
              blockBelow.typeId.includes("ml_torch") ||
              blockBelow.typeId.includes("carpet") ||
              blockBelow.typeId.includes("flower_pot") ||
              blockBelow.typeId.includes("torchflower") ||
              blockBelow.typeId.includes("door") ||
              blockBelow.typeId.includes("lily_pad") ||
              blockBelow.typeId.includes("moss") ||
              blockBelow.typeId.includes("wither_rose") ||
              blockBelow.typeId.includes("soul_sand") ||
              blockBelow.typeId.includes("grass_path") ||
              blockBelow.typeId.includes("farm_land") ||
              blockBelow.typeId.includes("flower")))
        ) {
          if (!entity.hasTag("hb_cb:start_block_despawn")) {
            entity.teleport({ x: entity.location.x, y: entity.location.y + 0.5, z: entity.location.z });
            let campSize = parseInt(stringBetween(entity.typeId, "hb_cb:", "x"), 10) / 2 - 0.5;
            let campState = entity.getProperty("hb_cb:camp_state");
            this.secondHitCampDespawn(entity, campSize, campState);
            entity.addTag("hb_cb:start_block_despawn");
          }
          return;
        }
      }
    });
  }
  handleArmorPieceSneak(player) {
    let itemChestplate = player.getComponent("equippable").getEquipment(EquipmentSlot.Chest);

    if (!itemChestplate) return; // Early exit if the item is undefined

    if (itemChestplate.typeId.includes("hb_cb:") && itemChestplate.typeId.includes("bp")) {
      const cooldownComp = itemChestplate.getComponent("cooldown");
      if (!cooldownComp) return;

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

      if (player.isSneaking) {
        this.itemEffects(player, itemChestplate);
        cooldownComp.startCooldown(player);
      }
    } else return;
  }
  handleArmorPiecePassive(player) {
    let itemChestplate = player.getComponent("equippable").getEquipment(EquipmentSlot.Chest);

    if (!itemChestplate) return; // Early exit if the item is undefined

    if (itemChestplate.typeId.includes("hb_cb:") && itemChestplate.typeId.includes("bp")) {
      this.itemEffectsPassive(player, itemChestplate);
    } else return;
  }
  itemEffects(player, itemChestplate) {
    if (itemChestplate.typeId.includes("diamond_poppy")) {
      player.addEffect("absorption", 200, { amplifier: 0, showParticles: false });
      player.dimension.spawnParticle("hb_cb:diamond_poppy_active", { x: player.location.x, y: player.location.y + 0.3, z: player.location.z });
      player.dimension.spawnParticle("hb_cb:diamond_poppy_active_2_flipped", { x: player.location.x, y: player.location.y + 0.3, z: player.location.z });
    }
    if (itemChestplate.typeId.includes("ancient_lantern")) {
      world.getDimension(player.dimension.id).spawnEntity("hb_cb:ancient_lantern_use_fake_light", player.location);
      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: ["minecraft:item", "minecraft:player", "minecraft:falling_block", "minecraft:xp_orb", "minecraft:arrow", "hb_cb:ancient_lantern", "hb_cb:diamond_poppy", "hb_cb:bell_staff", "hb_cb:backpack", "hb_cb:bench", "hb_cb:ancient_lantern_fake_light", "hb_cb:ancient_lantern_use_entity_fake_light", "hb_cb:ancient_lantern_use_fake_light"],
        location: player.location,
        maxDistance: 10,
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
        return;
      } else {
        player.playSound("hb_cb:ancient_lantern_shot");
        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 });
        nearbyEntities.forEach((foundEntity) => {
          foundEntity.dimension.spawnParticle("hb_cb:lantern_stun", foundEntity.getHeadLocation());
          foundEntity.addEffect("slowness", 120, { amplifier: 250, showParticles: true });
        });
      }
    }
  }
  itemEffectsPassive(player, itemChestplate) {
    if (itemChestplate.typeId.includes("ancient_lantern")) {
      let playerIdTag = "hb_cb:" + player.id.toString();
      let nearbyFakeLights = world.getDimension(player.dimension.id).getEntities({
        type: "hb_cb:ancient_lantern_fake_light",
        tags: [playerIdTag],
        range: 2,
      });
      if (nearbyFakeLights.length <= 50) {
        let FakeLight = world.getDimension(player.dimension.id).spawnEntity("hb_cb:ancient_lantern_fake_light", { x: player.location.x, y: player.location.y + 1, z: player.location.z });
        FakeLight.addTag(playerIdTag);
      }
      player.runCommand("/event entity @e[type=hb_cb:ancient_lantern_fake_light,r=2] hb_cb:reset");
    }
    if (itemChestplate.typeId.includes("bell_staff")) {
      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);
        }
      }
    }
  }
  saveCampStructure(backpack, campSize) {
    let pos1 = { x: backpack.location.x + campSize, y: backpack.location.y - 1, z: backpack.location.z + campSize };
    let pos2 = { x: backpack.location.x - campSize, y: backpack.location.y + campSize * 2, z: backpack.location.z - campSize };
    let timeStamp = backpack.getDynamicProperty("hb_cb_camp_name") ? backpack.getDynamicProperty("hb_cb_camp_name") : "hb_cb:" + Date.now().toString() + "Camp";
    let structureUUID = timeStamp.toString();
    let newStructureUUID = "hb_cb:" + Date.now().toString();

    system.runTimeout(() => {
      if (world.structureManager.get(structureUUID)) {
        //////world.sendMessage("deleted: " + structureUUID);
        world.structureManager.delete(structureUUID);
        // this.countStructures();
      }
    }, 10);
    system.waitTicks(1).then(() => {
      world.structureManager.createFromWorld(newStructureUUID + "Camp", backpack.dimension, pos1, pos2, { saveMode: StructureSaveMode.World, includeEntities: true });
      let campStructureName = backpack.getDynamicProperty("hb_cb_camp_name") ? backpack.getDynamicProperty("hb_cb_camp_name") : "TEST_EMPTY";
      backpack.setDynamicProperty("hb_cb_camp_name", newStructureUUID);

      let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
        excludeFamilies: ["hb_cb_backpack"],
        volume: {
          x: campSize * 2,
          y: campSize * 2,
          z: campSize * 2,
        },
        location: {
          x: backpack.location.x - 0.5 - campSize,
          y: backpack.location.y,
          z: backpack.location.z - 0.5 - campSize,
        },
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
        return;
      } else {
        nearbyEntities.forEach((foundEntity) => {
          if (foundEntity.typeId != "minecraft:player") foundEntity.remove();
        });
      }
    });
  }
  saveBackpackStructure(backpack, campSize) {
    // world.sendMessage("save backpack strucutre");
    let timeStamp = backpack.getDynamicProperty("hb_cb_backpack_name") ? backpack.getDynamicProperty("hb_cb_backpack_name") : "hb_cb:" + Date.now().toString() + "Backpack";
    let structureUUID = timeStamp.toString();

    //////world.sendMessage("bakcpack streucurter: " + structureUUID);
    if (world.structureManager.get(structureUUID + "Backpack")) {
      //////world.sendMessage("deleted: " + structureUUID + "Backpack");
      world.structureManager.delete(structureUUID + "Backpack");
      // this.countStructures();
    }

    backpack.runCommand("event entity @e[r=0.5,type=hb_cb:block_highlight,c=1] hb_cb:despawn");
    let newStructureUUID = "hb_cb:" + Date.now().toString();
    system.waitTicks(10).then(() => {
      backpack.setProperty("hb_cb:camp_state", false);
      world.structureManager.createFromWorld(newStructureUUID + "Backpack", backpack.dimension, backpack.location, { x: backpack.location.x, y: backpack.location.y + 1, z: backpack.location.z }, { saveMode: StructureSaveMode.World, includeEntities: true });
      backpack.setDynamicProperty("hb_cb_backpack_name", newStructureUUID);
    });
    //   return structureUUID;
  }

  loadCampStructureFromEntity(backpack, campSize) {
    if (backpack == undefined) return;
    if (!backpack.isValid()) return;
    if (!backpack) return;
    let replaceLoc = { x: backpack.location.x - campSize, y: backpack.location.y - 1, z: backpack.location.z - campSize };
    let campStructureName = backpack.getDynamicProperty("hb_cb_camp_name") ? backpack.getDynamicProperty("hb_cb_camp_name") : "TEST_EMPTY";

    if (campStructureName == "TEST EMPTY") {
      // saveOldTerrainToEntity(backpack, campSize);
      world.structureManager.place("hb_cb/" + ((campSize + 0.5) * 2).toString() + "x" + ((campSize + 0.5) * 2).toString() + "_camp", backpack.dimension, replaceLoc, {
        animationMode: StructureAnimationMode.Layers,
        // animationSeconds: 0.1,
        rotation: StructureRotation.None,
      });
    } else {
      // saveOldTerrainToEntity(backpack, campSize);

      world.structureManager.place(campStructureName + "Camp", backpack.dimension, replaceLoc, {
        animationMode: StructureAnimationMode.Layers,
        // animationSeconds: 0.1,
        rotation: StructureRotation.None,
      });
      system.runTimeout(() => {
        //////world.sendMessage("deleted: " + campStructureName + "Camp");
        world.structureManager.delete(campStructureName + "Camp");
        // this.countStructures();
      }, 10);
    }
    this.playAnimation(backpack, campSize, "spawn");

    let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
      families: ["hb_cb_backpack"],
      volume: {
        x: campSize * 2,
        y: campSize * 2,
        z: campSize * 2,
      },
      location: {
        x: backpack.location.x - 0.5 - campSize,
        y: backpack.location.y,
        z: backpack.location.z - 0.5 - campSize,
      },
    });
    if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) return;
    else {
      nearbyEntities.forEach((foundEntity) => {
        if (foundEntity.id != backpack.id) {
          foundEntity.remove();
        }
      });
    }
  }

  loadBackpackStructure(backpack, campSize) {
    let replaceLoc = { x: backpack.location.x - campSize, y: backpack.location.y, z: backpack.location.z - campSize };
    let campStructureName = backpack.getDynamicProperty("hb_cb_backpack_name") ? backpack.getDynamicProperty("hb_cb_backpack_name") : "TEST_EMPTY";

    world.structureManager.place(campStructureName + "Backpack", backpack.dimension, replaceLoc, {
      animationMode: StructureAnimationMode.Layers,
      // animationSeconds: 0.1,
      rotation: StructureRotation.None,
    });

    system.runTimeout(() => {
      //////world.sendMessage("deleted: " + campStructureName + "Backpack");
      world.structureManager.delete(campStructureName + "Backpack");
      // this.countStructures();
    }, 10);
  }

  saveOldTerrainToEntity(backpack, campSize) {
    let timeStamp = backpack.getDynamicProperty("hb_cb_old_terrain") ? backpack.getDynamicProperty("hb_cb_old_terrain") : "hb_cb:" + Date.now().toString() + "OldTerrain";
    let structureUUID = timeStamp.toString();

    system.runTimeout(() => {
      if (world.structureManager.get(structureUUID)) {
        //////world.sendMessage("deleted: " + structureUUID);
        world.structureManager.delete(structureUUID);
        // this.countStructures();
      }
    }, 10);

    let newStructureUUID = "hb_cb:" + Date.now().toString();

    // let timeStamp = backpack.getDynamicProperty("hb_cb_old_terrain") ? backpack.getDynamicProperty("hb_cb_old_terrain") : "hb_cb:" + Date.now().toString() + "OldTerrain";
    // let structureUUID = timeStamp.toString();

    backpack.setDynamicProperty("hb_cb_old_terrain", newStructureUUID);
    system.waitTicks(10).then(() => {
      if (backpack == undefined) return;
      if (!backpack.isValid()) return;
      if (!backpack) return;
      let pos1 = { x: backpack.location.x + campSize, y: backpack.location.y - 1, z: backpack.location.z + campSize };
      let pos2 = { x: backpack.location.x - campSize, y: backpack.location.y + campSize * 2, z: backpack.location.z - campSize };

      world.structureManager.createFromWorld(newStructureUUID + "OldTerrain", backpack.dimension, pos1, pos2, { saveMode: StructureSaveMode.World, includeEntities: true });
      backpack.setDynamicProperty("hb_cb_old_terrain", newStructureUUID);

      let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
        excludeFamilies: ["hb_cb_backpack"],
        volume: {
          x: campSize * 2,
          y: campSize * 2,
          z: campSize * 2,
        },
        location: {
          x: backpack.location.x - 0.5 - campSize,
          y: backpack.location.y,
          z: backpack.location.z - 0.5 - campSize,
        },
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
        return;
      } else {
        nearbyEntities.forEach((foundEntity) => {
          if (foundEntity.typeId != "minecraft:player") foundEntity.remove();
        });
      }
    });
  }
  saveOldTerrainToEntityOnSpawn(backpack, campSize) {
    let timeStamp = backpack.getDynamicProperty("hb_cb_old_terrain") ? backpack.getDynamicProperty("hb_cb_old_terrain") : "hb_cb:" + Date.now().toString() + "OldTerrain";
    let structureUUID = timeStamp.toString();
    let newStructureUUID = "hb_cb:" + Date.now().toString() + "OldTerrain";
    backpack.setDynamicProperty("hb_cb_old_terrain", newStructureUUID);

    system.runTimeout(() => {
      if (world.structureManager.get(structureUUID)) {
        //////world.sendMessage("deleted 111: " + structureUUID);
        world.structureManager.delete(structureUUID);
        // this.countStructures();
      }
    }, 10);

    system.waitTicks(10).then(() => {
      let pos1 = { x: backpack.location.x + campSize, y: backpack.location.y - 1, z: backpack.location.z + campSize };
      let pos2 = { x: backpack.location.x - campSize, y: backpack.location.y + campSize * 2, z: backpack.location.z - campSize };

      world.structureManager.createFromWorld(newStructureUUID, backpack.dimension, pos1, pos2, { saveMode: StructureSaveMode.World, includeEntities: true });
      backpack.setDynamicProperty("hb_cb_old_terrain", newStructureUUID);
    });
  }

  loadOldTerrainFromEntity(backpack, campSize) {
    backpack.runCommand("execute as @a[r=" + (campSize + 1) + "] positioned as @s run tp ~~.1~");
    // backpack.runCommand("/execute as @a positioned as @s run tp ~~.1~");
    // let nearbyPlayers = world.getDimension(backpack.dimension.id).getEntities({
    //   families: ["player"],
    //   maxDistance: 60,
    //   location: backpack.location,
    // });
    // if (nearbyPlayers.length === 0 || nearbyPlayers[0] == undefined) {
    //   return;
    // } else {
    //   nearbyPlayers.forEach((foundPlayer) => {
    //     let loc = { x: foundPlayer.location.x, y: foundPlayer.location.y + 0.1, z: foundPlayer.location.z };
    //     foundPlayer.teleport(loc);
    //   });
    // }
    let replaceLoc = { x: backpack.location.x - campSize, y: backpack.location.y - 1, z: backpack.location.z - campSize };
    let oldTerrainStructureName = backpack.getDynamicProperty("hb_cb_old_terrain") ? backpack.getDynamicProperty("hb_cb_old_terrain") : "";

    world.structureManager.place(oldTerrainStructureName + "OldTerrain", backpack.dimension, replaceLoc, {
      animationMode: StructureAnimationMode.Layers,
      // animationSeconds: 0.1,
      rotation: StructureRotation.None,
    });

    system.waitTicks(10).then(() => {
      if (world.structureManager.get(oldTerrainStructureName + "OldTerrain")) {
        //////world.sendMessage("deleted 222: " + oldTerrainStructureName + "OldTerrain");
        world.structureManager.delete(oldTerrainStructureName + "OldTerrain");
        // this.countStructures();
      }
    });

    this.playAnimation(backpack, campSize, "spawn");

    let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
      families: ["hb_cb_backpack"],
      volume: {
        x: campSize * 2,
        y: campSize * 2,
        z: campSize * 2,
      },
      location: {
        x: backpack.location.x - 0.5 - campSize,
        y: backpack.location.y,
        z: backpack.location.z - 0.5 - campSize,
      },
    });
    if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) return;
    else {
      nearbyEntities.forEach((foundEntity) => {
        if (foundEntity.id != backpack.id) {
          foundEntity.remove();
        }
      });
    }
  }

  playAnimation(backpack, campSize, animationName) {
    let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
      excludeFamilies: ["hb_cb_backpack"],
      volume: {
        x: campSize * 2,
        y: campSize * 2,
        z: campSize * 2,
      },
      location: {
        x: backpack.location.x - 0.5 - campSize,
        y: backpack.location.y,
        z: backpack.location.z - 0.5 - campSize,
      },
    });
    if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) return;
    else {
      nearbyEntities.forEach((foundEntity) => {
        if (foundEntity.typeId.includes("hb_cb:")) foundEntity.addEffect("invisibility", 10, { amplifier: 0, showParticles: false });
      });
    }
    system.waitTicks(10).then(() => {
      if (backpack == undefined) return;
      if (!backpack.isValid()) return;
      if (!backpack) return;
      let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
        excludeFamilies: ["hb_cb_backpack"],
        volume: {
          x: campSize * 2,
          y: campSize * 2,
          z: campSize * 2,
        },
        location: {
          x: backpack.location.x - 0.5 - campSize,
          y: backpack.location.y,
          z: backpack.location.z - 0.5 - campSize,
        },
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
        return;
      } else {
        nearbyEntities.forEach((foundEntity) => {
          if (foundEntity.typeId.includes("hb_cb:")) foundEntity.playAnimation(animationName);
        });
      }
    });
  }

  saveStructureNameToItemAndSpawnItem(newItemName, backpack, campSize) {
    let itemLocation = backpack.location;
    let campStructureName = backpack.getDynamicProperty("hb_cb_camp_name");
    let backpackStructureName = backpack.getDynamicProperty("hb_cb_backpack_name");
    let spawnedItem = new ItemStack(newItemName);
    // const oldLore = spawnedItem.getLore() ?? [];
    spawnedItem.setDynamicProperty("hb_cb_camp_name", campStructureName);
    spawnedItem.setDynamicProperty("hb_cb_backpack_name", backpackStructureName);
    // world.sendMessage(campStructureName.toString());
    // world.sendMessage(backpackStructureName.toString());
    // oldLore.push(`§k§0CAMP_${campStructureName}§r`);
    // oldLore.push(`§k§0PACK_${backpackStructureName}§r`);
    // spawnedItem.setLore(oldLore);
    world.getDimension(backpack.dimension.id).spawnItem(spawnedItem, itemLocation);
  }
  removeLoreMarkers(text) {
    // replace texts
    return text
      .replace(/§kCAMP_/g, "")
      .replace(/§kPACK_/g, "")
      .replace(/§r/g, "")
      .replace(/§0/g, "");
  }
  secondHitCampStateChange(backpack, campSize, campState) {
    if (backpack.hasTag("hb_cb:deny_despawn_interact")) {
      return;
    }
    if (backpack.hasTag("hb_cb:wait_camp_despawn_trigger")) {
      // world.sendMessage("return because of TAG ############");
      return;
    }

    backpack.addTag("hb_cb:deny_despawn_interact");
    let cancelFlag = false;
    let diamond_poppy_in_camp = false;
    let bell_staff_in_camp = false;
    let ancient_lantern_in_camp = false;
    backpack.removeTag("hb_cb:first_hit");
    backpack.removeTag("hb_cb:show_camp_box_hint");
    //world.sendMessage(campSize.toString());

    if (campState == true) {
      let nearbyEntitiesBPCheck = world.getDimension(backpack.dimension.id).getEntities({
        families: ["hb_cb_backpack"],
        volume: {
          x: 1 + campSize * 2,
          y: backpack.location.y + campSize * 2,
          z: 1 + campSize * 2,
        },
        location: {
          x: backpack.location.x - 0.5 - campSize,
          y: backpack.location.y - 1,
          z: backpack.location.z - 0.5 - campSize,
        },
      });
      if (nearbyEntitiesBPCheck[0] == undefined || nearbyEntitiesBPCheck.length <= 1) {
        //world.sendMessage("no other backpack found");
      } else {
        nearbyEntitiesBPCheck.forEach((entity) => {
          if (entity.location.x == backpack.location.x && entity.location.y == backpack.location.y && entity.location.z == backpack.location.z) {
            //world.sendMessage("same backpack found");
          } else {
            //world.sendMessage("other backpack found");
            const airPlaceholder = world.getDimension(backpack.dimension.id).getEntitiesAtBlockLocation(entity.location);
            let highlightFlag = false;
            airPlaceholder.forEach((foundEntity) => {
              //world.sendMessage(foundEntity.typeId);
              if (foundEntity.typeId == "hb_cb:block_highlight") highlightFlag = true;
            });
            if (!highlightFlag) {
              //world.sendMessage("no highlight found");
              entity.runCommand("/summon hb_cb:block_highlight ~~~");
            }

            cancelFlag = true;
          }
        });
      }
      if (cancelFlag) {
        backpack.runCommand("/stopsound @a[r=10] hb_cb:backpack_camp_size");
        // backpack.removeTag("hb_cb:first_hit");
        // backpack.removeTag("hb_cb:sneak_first_hit");
        backpack.runCommand('/tellraw @a[r=10] {"rawtext": [{"translate":"hb_cb.other_backpack_inside_camp"}]}');

        backpack.removeTag("hb_cb:deny_despawn_interact");
        return;
      }
      backpack.removeTag("hb_cb:deny_despawn_interact");
      //world.sendMessage("PACKUP");
      backpack.runCommand("/stopsound @a[r=10] hb_cb:backpack_camp_size");
      let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
        excludeFamilies: ["hb_cb_backpack"],
        excludeTypes: ["minecraft:item", "minecraft:falling_block", "minecraft:xp_orb", "minecraft:arrow"],
        volume: {
          x: campSize * 2,
          y: campSize * 2,
          z: campSize * 2,
        },
        location: {
          x: backpack.location.x - 0.5 - campSize,
          y: backpack.location.y,
          z: backpack.location.z - 0.5 - campSize,
        },
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) return;
      else {
        nearbyEntities.forEach((foundEntity) => {
          if (foundEntity.typeId.includes("hb_cb:")) {
            ////world.sendMessage(foundEntity.typeId);
            if (foundEntity.typeId.includes("diamond_poppy")) diamond_poppy_in_camp = true;
            if (foundEntity.typeId.includes("bell_staff")) bell_staff_in_camp = true;
            if (foundEntity.typeId.includes("ancient_lantern")) ancient_lantern_in_camp = true;
          }
        });
      }
      ////world.sendMessage(diamond_poppy_in_camp.toString() + "diamond_poppy_in_camp");
      ////world.sendMessage(bell_staff_in_camp.toString() + "bell_staff_in_camp");
      ////world.sendMessage(ancient_lantern_in_camp.toString() + "ancient_lantern_in_camp");
      backpack.setProperty("hb_cb:bell_staff_attached_to_item", bell_staff_in_camp);
      backpack.setProperty("hb_cb:diamond_poppy_attached_to_item", diamond_poppy_in_camp);
      backpack.setProperty("hb_cb:ancient_lantern_attached_to_item", ancient_lantern_in_camp);

      backpack.playAnimation("packup");
      //world.sendMessage("save structures");
      this.saveCampStructure(backpack, campSize);
      this.saveBackpackStructure(backpack, campSize);
      system.waitTicks(20).then(() => {
        this.loadOldTerrainFromEntity(backpack, campSize);

        ////world.sendMessage(backpack.getProperty("hb_cb:diamond_poppy_attached_to_item").toString() + "diamond_poppy_in_camp");
        ////world.sendMessage(backpack.getProperty("hb_cb:bell_staff_attached_to_item").toString() + "bell_staff_in_camp");
        ////world.sendMessage(backpack.getProperty("hb_cb:ancient_lantern_attached_to_item").toString() + "ancient_lantern_in_camp");
      });
      backpack.setProperty("hb_cb:camp_state", false);

      backpack.removeTag("hb_cb:deny_despawn_interact");
      return;
    } else {
      backpack.playAnimation("setup");
      let blockFlag = false;
      for (let x = backpack.location.x - 0.5 - campSize; x <= backpack.location.x - 0.5 + campSize; x++) {
        for (let y = backpack.location.y; y <= backpack.location.y + campSize; y++) {
          for (let z = backpack.location.z - 0.5 - campSize; z <= backpack.location.z - 0.5 + campSize; z++) {
            let blockLoc = { x: x, y: y, z: z };
            let block = world.getDimension(backpack.dimension.id).getBlock(blockLoc);
            if (!block.typeId.includes("minecraft:light_block") && block.typeId != "minecraft:air" && block.typeId != "hb_cb:backpack_1_block" && block.typeId != "hb_cb:backpack_2_block" && block.typeId != "hb_cb:roof_1_block" && block.typeId != "hb_cb:roof_2_block" && block.typeId != "hb_cb:bell_staff_block" && block.typeId != "hb_cb:bench_block" && block.typeId != "hb_cb:diamond_poppy_block" && block.typeId != "hb_cb:backpack_block" && block.typeId != "hb_cb:ancient_lantern_light_block") {
              blockFlag = true;
            }
          }
        }
      }
      backpack.runCommand("/stopsound @a[r=10] hb_cb:backpack_camp_size");
      if (blockFlag) {
        backpack.playAnimation("break");
        backpack.runCommand("/playsound hb_cb:backpack_error @a[r=10] ~~~ 1 1");
        backpack.runCommand('/tellraw @a[r=10] {"rawtext": [{"translate":"hb_cb.show_camp_box_hint_fail_' + ((campSize + 0.5) * 2).toString() + "x" + ((campSize + 0.5) * 2).toString() + '"}]}');

        let nearbyEntitiesBPCheck = world.getDimension(backpack.dimension.id).getEntities({
          families: ["hb_cb_backpack"],
          volume: {
            x: 1 + campSize * 2,
            y: backpack.location.y + campSize * 2,
            z: 1 + campSize * 2,
          },
          location: {
            x: backpack.location.x - 0.5 - campSize,
            y: backpack.location.y - 1,
            z: backpack.location.z - 0.5 - campSize,
          },
        });
        if (nearbyEntitiesBPCheck[0] == undefined || nearbyEntitiesBPCheck.length <= 1) {
          //world.sendMessage("no other backpack found");
        } else {
          nearbyEntitiesBPCheck.forEach((entity) => {
            if (entity.location.x == backpack.location.x && entity.location.y == backpack.location.y && entity.location.z == backpack.location.z) {
              //world.sendMessage("same backpack found");
            } else {
              //world.sendMessage("other backpack found");
              const airPlaceholder = world.getDimension(backpack.dimension.id).getEntitiesAtBlockLocation(entity.location);
              let highlightFlag = false;
              airPlaceholder.forEach((foundEntity) => {
                //world.sendMessage(foundEntity.typeId);
                if (foundEntity.typeId == "hb_cb:block_highlight") highlightFlag = true;
              });
              if (!highlightFlag) entity.runCommand("/summon hb_cb:block_highlight ~~~");

              cancelFlag = true;
            }
          });
        }
        if (cancelFlag) {
          backpack.runCommand("/stopsound @a[r=10] hb_cb:backpack_camp_size");
          // backpack.removeTag("hb_cb:first_hit");
          // backpack.removeTag("hb_cb:sneak_first_hit");
          backpack.runCommand('/tellraw @a[r=10] {"rawtext": [{"translate":"hb_cb.other_backpack_inside_camp"}]}');

          backpack.removeTag("hb_cb:deny_despawn_interact");
          return;
        }

        backpack.removeTag("hb_cb:deny_despawn_interact");
        return;
      } else {
        let nearbyEntitiesBPCheck = world.getDimension(backpack.dimension.id).getEntities({
          families: ["hb_cb_backpack"],

          volume: {
            x: 1 + campSize * 2,
            y: backpack.location.y + campSize * 2,
            z: 1 + campSize * 2,
          },
          location: {
            x: backpack.location.x - 0.5 - campSize,
            y: backpack.location.y - 1,
            z: backpack.location.z - 0.5 - campSize,
          },
        });
        if (nearbyEntitiesBPCheck[0] == undefined || nearbyEntitiesBPCheck.length <= 1) {
          // //world.sendMessage("no other backpack found");
        } else {
          nearbyEntitiesBPCheck.forEach((entity) => {
            if (entity.location.x == backpack.location.x && entity.location.y == backpack.location.y && entity.location.z == backpack.location.z) {
              // //world.sendMessage("same backpack found");
            } else {
              // //world.sendMessage("other backpack found");
              const airPlaceholder = world.getDimension(backpack.dimension.id).getEntitiesAtBlockLocation(entity.location);
              let highlightFlag = false;
              airPlaceholder.forEach((foundEntity) => {
                // //world.sendMessage(foundEntity.typeId);
                if (foundEntity.typeId == "hb_cb:block_highlight") highlightFlag = true;
              });
              if (!highlightFlag) entity.runCommand("/summon hb_cb:block_highlight ~~~");

              cancelFlag = true;
            }
          });
        }
        if (cancelFlag) {
          backpack.runCommand("/stopsound @a[r=10] hb_cb:backpack_camp_size");
          // backpack.removeTag("hb_cb:first_hit");
          // backpack.removeTag("hb_cb:sneak_first_hit");
          backpack.runCommand('/tellraw @a[r=10] {"rawtext": [{"translate":"hb_cb.other_backpack_inside_camp"}]}');

          backpack.removeTag("hb_cb:deny_despawn_interact");
          return;
        }
        backpack.playAnimation("setup");
      }

      backpack.runCommand("/playsound hb_cb:backpack_build_up @a[r=10] ~~~ 1 1");
      backpack.playAnimation("setup");
      this.saveOldTerrainToEntity(backpack, campSize);
      // loadBackpackStructure(backpack, campSize);
      system.waitTicks(10).then(() => {
        this.loadCampStructureFromEntity(backpack, campSize);
        backpack.removeTag("hb_cb:deny_despawn_interact");
      });
      backpack.setProperty("hb_cb:camp_state", true);
      return;
    }
  }

  defineItemNamebyCampEntities(backpack, campSize) {
    let diamond_poppy_in_camp = false;
    let bell_staff_in_camp = false;
    let ancient_lantern_in_camp = false;

    let campState = backpack.getProperty("hb_cb:camp_state");
    let diamond_poppy_attached_to_item = backpack.getProperty("hb_cb:diamond_poppy_attached_to_item") ? backpack.getProperty("hb_cb:diamond_poppy_attached_to_item") : false;
    let bell_staff_attached_to_item = backpack.getProperty("hb_cb:bell_staff_attached_to_item") ? backpack.getProperty("hb_cb:bell_staff_attached_to_item") : false;
    let ancient_lantern_attached_to_item = backpack.getProperty("hb_cb:ancient_lantern_attached_to_item") ? backpack.getProperty("hb_cb:ancient_lantern_attached_to_item") : false;
    if (campState) {
      let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
        excludeFamilies: ["hb_cb_backpack"],
        excludeTypes: ["minecraft:item", "minecraft:falling_block", "minecraft:xp_orb", "minecraft:arrow"],
        volume: {
          x: campSize * 2,
          y: campSize * 2,
          z: campSize * 2,
        },
        location: {
          x: backpack.location.x - 0.5 - campSize,
          y: backpack.location.y,
          z: backpack.location.z - 0.5 - campSize,
        },
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
        return this.getBackpackItemName(backpack, diamond_poppy_attached_to_item, bell_staff_attached_to_item, ancient_lantern_attached_to_item, campSize);
      } else {
        nearbyEntities.forEach((foundEntity) => {
          if (foundEntity.typeId.includes("hb_cb:")) {
            if (foundEntity.typeId.includes("diamond_poppy")) diamond_poppy_in_camp = true;
            if (foundEntity.typeId.includes("bell_staff")) bell_staff_in_camp = true;
            if (foundEntity.typeId.includes("ancient_lantern")) ancient_lantern_in_camp = true;
          }
        });
        return this.getBackpackItemName(backpack, diamond_poppy_in_camp, bell_staff_in_camp, ancient_lantern_in_camp, campSize);
      }
    } else {
      return this.getBackpackItemName(backpack, diamond_poppy_attached_to_item, bell_staff_attached_to_item, ancient_lantern_attached_to_item, campSize);
    }
  }

  getBackpackItemName(backpack, diamond_poppy_in_camp, bell_staff_in_camp, ancient_lantern_in_camp, campSize) {
    if (!diamond_poppy_in_camp && !bell_staff_in_camp && !ancient_lantern_in_camp) {
      return "hb_cb:" + campSize + "x" + campSize + "_bp_empty_fake_item";
    }
    if (!diamond_poppy_in_camp && !bell_staff_in_camp && ancient_lantern_in_camp) {
      return "hb_cb:" + campSize + "x" + campSize + "_bp_ancient_lantern_fake_item";
    }
    if (!diamond_poppy_in_camp && bell_staff_in_camp && !ancient_lantern_in_camp) {
      return "hb_cb:" + campSize + "x" + campSize + "_bp_bell_staff_fake_item";
    }
    if (diamond_poppy_in_camp && !bell_staff_in_camp && !ancient_lantern_in_camp) {
      return "hb_cb:" + campSize + "x" + campSize + "_bp_diamond_poppy_fake_item";
    }
    if (!diamond_poppy_in_camp && bell_staff_in_camp && ancient_lantern_in_camp) {
      return "hb_cb:" + campSize + "x" + campSize + "_bp_ancient_lantern_bell_staff_fake_item";
    }
    if (diamond_poppy_in_camp && !bell_staff_in_camp && ancient_lantern_in_camp) {
      return "hb_cb:" + campSize + "x" + campSize + "_bp_diamond_poppy_ancient_lantern_fake_item";
    }
    if (diamond_poppy_in_camp && bell_staff_in_camp && !ancient_lantern_in_camp) {
      return "hb_cb:" + campSize + "x" + campSize + "_bp_diamond_poppy_bell_staff_fake_item";
    }
    if (diamond_poppy_in_camp && bell_staff_in_camp && ancient_lantern_in_camp) {
      return "hb_cb:" + campSize + "x" + campSize + "_bp_diamond_poppy_bell_staff_ancient_lantern_fake_item";
    }
    return "hb_cb:" + campSize + "x" + campSize + "_bp_empty_fake_item"; // Fallback, though all cases are covered above
  }

  secondHitCampDespawn(backpack, campSize, campState) {
    // world.sendMessage("DESPAWN CAMP");
    if (backpack.hasTag("hb_cb:deny_despawn_interact")) {
      return;
    }
    if (backpack.hasTag("hb_cb:wait_camp_despawn_trigger")) {
      // world.sendMessage("return because of TAG ############");
      return;
    }
    backpack.addTag("hb_cb:wait_camp_despawn_trigger");
    // system.waitTicks(30).then(() => {
    //   backpack.removeTag("hb_cb:wait_camp_despawn_trigger");
    // });

    // TODO: CHECK HERE THE HIEGHT it sohuldnt fail if a dirt block is 3 blocks aobvce the bp

    let cancelFlag = false;
    if (campState == true) {
      let nearbyEntities = world.getDimension(backpack.dimension.id).getEntities({
        families: ["hb_cb_backpack"],

        volume: {
          x: 1 + campSize * 2,
          y: backpack.location.y + campSize * 2,
          z: 1 + campSize * 2,
        },
        location: {
          x: backpack.location.x - 0.5 - campSize,
          y: backpack.location.y - 1,
          z: backpack.location.z - 0.5 - campSize,
        },

        // volume: {
        //   x: campSize,
        //   y: backpack.location.y + campSize * 2,
        //   z: campSize,
        // },
        // location: {
        //   x: backpack.location.x - 0.5 - campSize / 2,
        //   y: backpack.location.y - 1,
        //   z: backpack.location.z - 0.5 - campSize / 2,
        // },
      });
      if (nearbyEntities[0] == undefined || nearbyEntities.length <= 1) {
      } else {
        nearbyEntities.forEach((entity) => {
          if (entity.location.x == backpack.location.x && entity.location.y == backpack.location.y && entity.location.z == backpack.location.z) {
          } else {
            const airPlaceholder = world.getDimension(backpack.dimension.id).getEntitiesAtBlockLocation(entity.location);
            let highlightFlag = false;
            airPlaceholder.forEach((foundEntity) => {
              // //world.sendMessage(foundEntity.typeId);
              if (foundEntity.typeId == "hb_cb:block_highlight") highlightFlag = true;
            });
            if (!highlightFlag) {
              entity.runCommand("/summon hb_cb:block_highlight ~~~");
            }

            cancelFlag = true;
          }
        });
      }
      if (cancelFlag) {
        backpack.runCommand("/stopsound @a[r=10] hb_cb:backpack_camp_size");
        backpack.removeTag("hb_cb:first_hit");
        backpack.removeTag("hb_cb:sneak_first_hit");
        backpack.runCommand('/tellraw @a[r=10] {"rawtext": [{"translate":"hb_cb.other_backpack_inside_camp"}]}');

        backpack.removeTag("hb_cb:wait_camp_despawn_trigger");
        backpack.removeTag("hb_cb:deny_despawn_interact");
        return;
      }
      let newItemName = this.defineItemNamebyCampEntities(backpack, stringBetween(backpack.typeId, "hb_cb:", "x"));

      backpack.playAnimation("despawn");
      backpack.runCommand("/stopsound @a[r=10] hb_cb:backpack_camp_size");
      backpack.setProperty("hb_cb:camp_state", false);
      backpack.removeTag("hb_cb:first_hit");
      backpack.removeTag("hb_cb:sneak_first_hit");
      this.saveBackpackStructure(backpack, campSize);
      this.saveCampStructure(backpack, campSize);
      system.waitTicks(20).then(() => {
        this.loadOldTerrainFromEntity(backpack, campSize);
        backpack.runCommand("tag @a[r=12] add hb_cb:backpack_place_cd");
      });
      system.waitTicks(40).then(() => {
        this.saveStructureNameToItemAndSpawnItem(newItemName, backpack, campSize);
        // let allStructures = world.structureManager.getWorldStructureIds();
        // let test = 0;
        // allStructures.forEach((element) => {
        //   if (element.includes("hb_cb")) {
        //     test++;
        //   }
        // });
        if (backpack.hasTag("hb_cb:start_block_despawn")) backpack.runCommand("/fill ~~~ ~~2~ air");
        else backpack.runCommand("/fill ~~~ ~~1~ air");

        for (let x = backpack.location.x - 0.5 - campSize; x <= backpack.location.x - 0.5 + campSize; x++) {
          for (let y = backpack.location.y; y <= backpack.location.y + campSize * 2; y++) {
            for (let z = backpack.location.z - 0.5 - campSize; z <= backpack.location.z - 0.5 + campSize; z++) {
              let blockLoc = { x: x, y: y, z: z };
              const airPlaceholder = world.getDimension(backpack.dimension.id).getEntitiesAtBlockLocation(blockLoc);
              airPlaceholder.forEach((entity) => {
                if (entity.typeId == "hb_cb:block_highlight") entity.remove();
              });
            }
          }
        }

        backpack.removeTag("hb_cb:first_hit");
        backpack.removeTag("hb_cb:sneak_first_hit");
        backpack.removeTag("hb_cb:show_camp_box_hint");
        backpack.removeTag("hb_cb:wait_camp_despawn_trigger");
        backpack.setProperty("hb_cb:camp_state", false);
        backpack.setProperty("hb_cb:camp_state_trigger", "default");
        backpack.setProperty("hb_cb:camp_despawn_trigger", "default");
        backpack.removeTag("hb_cb:wait_camp_despawn_trigger");
        backpack.runCommand("event entity @e[r=0.5,type=hb_cb:block_highlight,c=1] hb_cb:despawn");
        backpack.remove();
      });
      return;
    } else {
      let newItemNameClosedCamp = this.defineItemNamebyCampEntities(backpack, stringBetween(backpack.typeId, "hb_cb:", "x"));

      backpack.playAnimation("despawn");
      backpack.setProperty("hb_cb:camp_state", false);
      backpack.removeTag("hb_cb:first_hit");
      backpack.removeTag("hb_cb:sneak_first_hit");
      this.saveBackpackStructure(backpack, campSize);
      // this.saveCampStructure(backpack, campSize);
      // ,,,,,,
      system.waitTicks(20).then(() => {
        if (backpack == undefined) return;
        if (!backpack) return;
        backpack.runCommand("tag @a[r=12] add hb_cb:backpack_place_cd");
      });
      system.waitTicks(40).then(() => {
        if (backpack == undefined) return;
        if (!backpack) return;
        this.saveStructureNameToItemAndSpawnItem(newItemNameClosedCamp, backpack, campSize);
        // let allStructures = world.structureManager.getWorldStructureIds();
        // let test = 0;
        // allStructures.forEach((element) => {
        //   if (element.includes("hb_cb")) {
        //     test++;
        //   }
        // });
        if (backpack.hasTag("hb_cb:start_block_despawn")) backpack.runCommand("/fill ~~~ ~~2~ air");
        else backpack.runCommand("/fill ~~~ ~~1~ air");

        for (let x = backpack.location.x - 0.5 - campSize; x <= backpack.location.x - 0.5 + campSize; x++) {
          for (let y = backpack.location.y; y <= backpack.location.y + campSize * 2; y++) {
            for (let z = backpack.location.z - 0.5 - campSize; z <= backpack.location.z - 0.5 + campSize; z++) {
              let blockLoc = { x: x, y: y, z: z };
              const airPlaceholder = world.getDimension(backpack.dimension.id).getEntitiesAtBlockLocation(blockLoc);
              airPlaceholder.forEach((entity) => {
                if (entity.typeId == "hb_cb:block_highlight") entity.remove();
              });
            }
          }
        }

        backpack.removeTag("hb_cb:first_hit");
        backpack.removeTag("hb_cb:sneak_first_hit");
        backpack.removeTag("hb_cb:show_camp_box_hint");
        backpack.removeTag("hb_cb:wait_camp_despawn_trigger");
        backpack.setProperty("hb_cb:camp_state", false);
        backpack.setProperty("hb_cb:camp_state_trigger", "default");
        backpack.setProperty("hb_cb:camp_despawn_trigger", "default");
        backpack.removeTag("hb_cb:wait_camp_despawn_trigger");
        backpack.remove();
      });
      return;
    }
  }

  backpackSpawn(player, item) {
    let diamond_poppy_attached_to_item = false;
    let bell_staff_attached_to_item = false;
    let ancient_lantern_attached_to_item = false;
    if (item.typeId.includes("diamond_poppy")) diamond_poppy_attached_to_item = true;
    if (item.typeId.includes("bell_staff")) bell_staff_attached_to_item = true;
    if (item.typeId.includes("ancient_lantern")) ancient_lantern_attached_to_item = true;
    let campSize = parseInt(stringBetween(item.typeId, "hb_cb:", "x"), 10) / 2 - 1;

    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;
      switch (face) {
        case "Up":
          placeLoc = { x: location.x + 0.5, y: location.y + 1, z: location.z + 0.5 };
          break;
        case "Down":
          placeLoc = { x: location.x + 0.5, y: location.y - 1, z: location.z + 0.5 };
          break;
        case "North":
          placeLoc = { x: location.x + 0.5, y: location.y, z: location.z - 0.5 };
          break;
        case "South":
          placeLoc = { x: location.x + 0.5, y: location.y, z: location.z + 1.5 };
          break;
        case "West":
          placeLoc = { x: location.x - 0.5, y: location.y, z: location.z + 0.5 };
          break;
        case "East":
          placeLoc = { x: location.x + 1.5, y: location.y, z: location.z + 0.5 };
          break;
        default:
          break;
      }

      let backpack;
      let campStructureName = item.getDynamicProperty("hb_cb_camp_name") ? item.getDynamicProperty("hb_cb_camp_name") : "TEST EMPTY";
      // let backpackStructureName = item.getDynamicProperty("hb_cb_backpack_name") ? item.getDynamicProperty("hb_cb_backpack_name") : "TEST EMPTY";
      // let backpackStructureName = item.getDynamicProperty("hb_cb_backpack_name") ? item.getDynamicProperty("hb_cb_backpack_name") : "hb_cb:" + Date.now().toString() + "Backpack";
      let backpackStructureName;
      let backpackStructureFlag;
      if (item.getDynamicProperty("hb_cb_backpack_name") == undefined) {
        backpackStructureFlag = false;
        backpackStructureName = "hb_cb:" + Date.now().toString() + "Backpack";
      } else {
        backpackStructureFlag = true;
        backpackStructureName = item.getDynamicProperty("hb_cb_backpack_name");
      }
      // world.sendMessage("SPAWN THIS BP: " + backpackStructureName.toString());
      // world.sendMessage("backpackStructureFlag: " + backpackStructureFlag.toString());
      let yRotation = getEntityRotation(player);
      // Old Camp is NOT saved on item aka new backpack/camp
      if (campStructureName == "TEST EMPTY" && !backpackStructureFlag) {
        let placeLoc = getLocationbyFacingBlock(face, location);
        if (checkLocation(placeLoc, player, placeLoc, 0)) 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:backpack_1_block");
        block2.setType("hb_cb:backpack_2_block");
        // let ancient_lantern = world.getDimension(player.dimension.id).spawnEntity(item.typeId, placeLoc);
        let backpackEntityName = "hb_cb:" + stringBetween(item.typeId, "hb_cb:", "x") + "x" + stringBetween(item.typeId, "hb_cb:", "x") + "_backpack";
        player.runCommand("/playsound step.cloth @a[r=10] ~~~ 1 1");
        player.runCommand("/summon " + backpackEntityName + " " + placeLoc.x.toString() + " " + placeLoc.y.toString() + " " + placeLoc.z.toString() + " " + yRotation.toString() + " 0");

        let nearbyEntities = world.getDimension(player.dimension.id).getEntities({
          families: ["hb_cb_backpack"],
          location: placeLoc,
          closest: 1,
        });
        if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
          return;
        } else {
          // nearbyEntities[0] = world.getDimension(player.dimension.id).spawnEntity(item.typeId, placeLoc);
          nearbyEntities[0].setDynamicProperty("hb_cb_camp_name", campStructureName);
          nearbyEntities[0].setDynamicProperty("hb_cb_backpack_name", backpackStructureName);
          nearbyEntities[0].setProperty("hb_cb:diamond_poppy_attached_to_item", diamond_poppy_attached_to_item);
          nearbyEntities[0].setProperty("hb_cb:bell_staff_attached_to_item", bell_staff_attached_to_item);
          nearbyEntities[0].setProperty("hb_cb:ancient_lantern_attached_to_item", ancient_lantern_attached_to_item);
          this.saveOldTerrainToEntityOnSpawn(nearbyEntities[0], campSize);
          nearbyEntities[0].setProperty("hb_cb:camp_state", false);
        }
      }
      // Old Camp is saved on item aka old backpack/camp
      else {
        let structureRotation;
        switch (yRotation) {
          case 0:
            structureRotation = StructureRotation.None;
            break;
          case 90:
            structureRotation = StructureRotation.Rotate90;
            break;
          case 180:
            structureRotation = StructureRotation.Rotate180;
            break;
          case 270:
            structureRotation = StructureRotation.Rotate270;
            break;
          default:
            break;
        }

        world.structureManager.place(backpackStructureName + "Backpack", player.dimension, placeLoc, {
          animationMode: StructureAnimationMode.Layers,
          // animationSeconds: 0.1,
          rotation: structureRotation,
        });
        system.runTimeout(() => {
          if (world.structureManager.get(backpackStructureName + "Backpack")) {
            //////world.sendMessage("deleted: " + backpackStructureName + "Backpack");
            world.structureManager.delete(backpackStructureName + "Backpack");
            // this.countStructures();
          }
        }, 10);
        let nearbyEntities = world.getDimension(player.dimension.id).getEntities({
          families: ["hb_cb_backpack"],
          location: placeLoc,
          closest: 1,
        });
        if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
          // world.sendMessage("NOTHUNG HFOUND ##########");
          return;
        } else {
          // world.sendMessage("HFOUND ##########");
          system.waitTicks(5).then(() => {
            // player.teleport(nearbyEntities[0].location);
            // world.sendMessage("HFOUND sssssssssss");
            // player.runCommand("/setblock " + nearbyEntities[0].location.x + " " + (nearbyEntities[0].location.y + 4) + " " + nearbyEntities[0].location.z + " dirt");
            // world.sendMessage("/setblock " + nearbyEntities[0].location.x + " " + (nearbyEntities[0].location.y + 4) + " " + nearbyEntities[0].location.z + " dirt");
            nearbyEntities[0].setDynamicProperty("hb_cb_camp_name", campStructureName);
            nearbyEntities[0].setDynamicProperty("hb_cb_backpack_name", backpackStructureName);
            nearbyEntities[0].setProperty("hb_cb:diamond_poppy_attached_to_item", diamond_poppy_attached_to_item);
            nearbyEntities[0].setProperty("hb_cb:bell_staff_attached_to_item", bell_staff_attached_to_item);
            nearbyEntities[0].setProperty("hb_cb:ancient_lantern_attached_to_item", ancient_lantern_attached_to_item);
            nearbyEntities[0].removeTag("hb_cb:first_hit");
            nearbyEntities[0].removeTag("hb_cb:sneak_first_hit");
            nearbyEntities[0].removeTag("hb_cb:show_camp_box_hint");
            nearbyEntities[0].removeTag("hb_cb:wait_camp_despawn_trigger");
            nearbyEntities[0].setProperty("hb_cb:camp_state", false);
            nearbyEntities[0].setProperty("hb_cb:camp_state_trigger", "default");
            nearbyEntities[0].setProperty("hb_cb:camp_despawn_trigger", "default");
            // let allTags = nearbyEntities[0].getTags();
            // allTags.forEach((element) => {
            //   world.sendMessage("tag: " + element);
            // });
            // let campState = nearbyEntities[0].getProperty("hb_cb:camp_state");
            // let camp_state_trigger = nearbyEntities[0].getProperty("hb_cb:camp_state_trigger");
            // let camp_despawn_trigger = nearbyEntities[0].getProperty("hb_cb:camp_despawn_trigger");
            // world.sendMessage("campstate: " + campState);
            // world.sendMessage("camp_state_trigger: " + camp_state_trigger);
            // world.sendMessage("camp_despawn_trigger: " + camp_despawn_trigger);
            this.saveOldTerrainToEntityOnSpawn(nearbyEntities[0], campSize);
          });
        }
      }
      // if (!gamemodeCreative) {
      player.runCommand("/replaceitem entity @s slot.weapon.mainhand 0 air");
      // player.runCommand("/clear @s " + item.typeId + " 0 1");
      // }
    }
    return;
  }

  // countStructures() {
  //   let AllStructures = world.structureManager.getWorldStructureIds();
  //   //////world.sendMessage("STRUCTURE COUNT: " + AllStructures.length);

  //   let filteredStructures = AllStructures.filter((structure) => structure.includes("hb_cb:"));

  //   //////world.sendMessage("STRUCTURE COUNT length hb: " + filteredStructures.length);
  //   // Get the last 5 elements
  //   let lastFive = filteredStructures.slice(-5);

  //   lastFive.forEach((structure) => {
  //     //////world.sendMessage(structure);
  //   });
  // }
}
