import { system, world, ItemStack, StructureAnimationMode, StructureRotation, StructureSaveMode } from "@minecraft/server";
import { getGamemode, stringBetween } from "../utilities/helpers";
import { saveOldTerrainToEntity } from "../entity/structure_controller";

// export function saveCampStructure(backpack, campSize) {
//   //////////world.sendMessage("SAVE CAMP STRUCTURE");
//   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 structureUUID = "hb_cb:" + backpack.id.toString();
//   world.structureManager.delete(structureUUID + "Backpack");
//   world.structureManager.delete(structureUUID + "Camp");
//   system.waitTicks(30).then(() => {
//     world.structureManager.createFromWorld(structureUUID + "Backpack", backpack.dimension, backpack.location, backpack.location, { saveMode: StructureSaveMode.World, includeEntities: true });
//     world.structureManager.createFromWorld(structureUUID + "Camp", backpack.dimension, pos1, pos2, { saveMode: StructureSaveMode.World, includeEntities: false });
//   });
//   return structureUUID;
// }

export function backpackDespawn(player, backpack) {
  let campSize = parseInt(stringBetween(backpack.typeId, "hb_cb:", "x"), 10);
  // let campSize = 3;
  //////////world.sendMessage("backpackDespawn");

  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") : "";
  // camp structure in structureUUID
  let structureUUID = backpack.getDynamicProperty("hb_cb_structure_name");
  // is the camp open
  if (backpack.getProperty("hb_cb:camp_state") == true) {
    backpack.removeTag("hb_cb:first_hit");
    backpack.removeTag("hb_cb:sneak_first_hit");
    backpack.setProperty("hb_cb:camp_state", false);
    //////////world.sendMessage("SAVE OPENED CAMP STRUCTURE");
    system.waitTicks(30).then(() => {
      structureUUID = saveCampStructure(backpack, campSize);
    });
    // old terrain structure is saved
    system.waitTicks(60).then(() => {
      if (oldTerrainStructureName != "") {
        //////////world.sendMessage("PLACE OLD TERRAIN");
        world.structureManager.place(oldTerrainStructureName, player.dimension, replaceLoc, {
          animationMode: StructureAnimationMode.Layers,
          animationSeconds: 0.1,
          rotation: StructureRotation.None,
        });
      }
    });
  } else {
    // old terrain structure is NOT saved || is the camp closed
    //////////world.sendMessage("no replace structre foudn || camp packed up");
  }
  system.waitTicks(100).then(() => {
    let campStructureName = structureUUID;
    let spawnedItem = new ItemStack("hb_cb:backpack");
    spawnedItem.setDynamicProperty("hb_cb_structure_name", campStructureName);
    world.getDimension(player.dimension.id).spawnItem(spawnedItem, backpack.location);

    backpack.remove();
  });
}
export function backpackSpawn(player, item) {
  //////////world.sendMessage("backpackSpawn");
  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_structure_name") ? item.getDynamicProperty("hb_cb_structure_name") : "TEST EMPTY";

    //TODO:
    // check for new static entities to spawn
    // - ancient lantern
    // - diamond poppy
    // - bell staff

    //////////world.sendMessage("SAVED: ->>>>>>>>>>>>> " + campStructureName);

    // Old Camp is NOT saved on item aka new backpack/camp
    if (campStructureName == "TEST EMPTY") {
      //////////world.sendMessage("ITEM HAS NO CAMP SAVED");
      backpack = world.getDimension(player.dimension.id).spawnEntity(item.typeId, placeLoc);
      backpack.setDynamicProperty("hb_cb_structure_name", campStructureName);
      saveOldTerrainToEntity(backpack, campSize);
      backpack.setProperty("hb_cb:camp_state", false);
    }
    // Old Camp is saved on item aka old backpack/camp
    else {
      //////////world.sendMessage("ITEM HAS CAMP SAVED");
      //////////world.sendMessage(campStructureName + "Backpack");
      world.structureManager.place(campStructureName + "Backpack", player.dimension, placeLoc, {
        animationMode: StructureAnimationMode.Layers,
        // animationSeconds: 0.1,
        rotation: StructureRotation.None,
      });
      let nearbyEntities = world.getDimension(player.dimension.id).getEntities({
        families: ["hb_cb_backpack"],
        location: location.location,
        closest: 1,
      });
      if (nearbyEntities.length === 0 || nearbyEntities[0] == undefined) {
        return;
      } else {
        system.waitTicks(30).then(() => {
          //////////world.sendMessage(nearbyEntities[0].typeId);
          //////////world.sendMessage("old structure: " + campStructureName);
          // saveOldTerrainToEntity(nearbyEntities[0], campSize);
          nearbyEntities[0].setDynamicProperty("hb_cb_structure_name", campStructureName);
          nearbyEntities[0].removeTag("hb_cb:first_hit");
          nearbyEntities[0].removeTag("hb_cb:sneak_first_hit");
          nearbyEntities[0].setProperty("hb_cb:camp_state", false);
          saveOldTerrainToEntity(nearbyEntities[0], campSize);
          //////////world.sendMessage(nearbyEntities[0].getProperty("hb_cb:camp_state").toString());
        });
      }
    }
    // if (!gamemodeCreative) {
    //   player.runCommand("/clear @s " + item.typeId + " 0 1");
    // }
  }
  return;
}
