import { system, world, BlockVolume, ItemStack, BlockPermutation } from "@minecraft/server";

const blackPuddleComponent = {
  onStepOn({ block }) {
    const center = block.center();
    try {
      block.dimension.spawnParticle("hb_hr:black_puddle_walk_thru", { x: center.x, y: center.y + 0.6, z: center.z });
    } catch (error) {}
  },
  onTick({ block }) {
    const blockAbove = block.above();
    let newStates;
    if (blockAbove == undefined || blockAbove.typeId != "minecraft:air") {
      newStates = {
        "hb_hr:block_above_is_air": false,
      };
    } else {
      newStates = {
        "hb_hr:block_above_is_air": true,
      };
    }

    // 6. Apply the updated permutation
    const newPerm = BlockPermutation.resolve(block.typeId, newStates);
    block.setPermutation(newPerm);

    // const testBlockVolume = new BlockVolume({ x: blockPos.x, y: blockPos.y, z: blockPos.z }, { x: blockPos.x, y: blockPos.y - 1, z: blockPos.z });

    // Get players within a 1 block radius of the block center
    const players = block.dimension.getEntities({
      location: {
        x: block.location.x, //  X
        y: block.location.y + 1, // one block up
        z: block.location.z, //  Z
      },
      volume: {
        x: 1.0, // full block width
        y: 1.0, // one block tall
        z: 1.0, // full block depth
      },
      type: "minecraft:player",
      excludeTags: ["hb_hr:testing"],
    });

    for (const player of players) {
      const blockBelow = player.dimension.getBlock({
        x: player.location.x,
        y: player.location.y,
        z: player.location.z,
      });
      if (blockBelow.typeId == "hb_hr:black_puddle") {
        player.addEffect("slowness", 20, { amplifier: 0 });
      }
    }
  },
};

const customComponents = {
  "hb_hr:black_puddle": blackPuddleComponent,
};

export class blockHandlerB3 {
  static initialized = false;
  static playerBiomeMap = new Map(); // Speichert zuletzt erkannte Biome für jeden Spieler

  constructor() {
    this.initialize();
  }

  initialize() {
    if (!blockHandlerB3.initialized) {
      blockHandlerB3.initialized = true;
      this.processSubscriptions();
    }
  }

  processSubscriptions() {
    world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
      if (!event.itemStack) return;
      if (event.itemStack.typeId !== "hb_hr:black_vine") return;
      if (event.block.typeId !== "hb_hr:black_vine") return;

      // Defer the actual permutation change until after the interaction
      system.run(() => {
        // 1. Grab the two block positions
        const basePos = event.block.location;
        // //world.sendMessage("base lbock " + event.block.typeId);
        // //world.sendMessage("hitBlock " + event.player.getBlockFromViewDirection({ excludeTypes: ["hb_hr:black_vine"] }).block.typeId);
        const hitBlock = event.player.getBlockFromViewDirection({ excludeTypes: ["hb_hr:black_vine"] }).block;
        const hitPos = hitBlock.location;

        // 2. Compute delta
        const dx = hitPos.x - basePos.x;
        const dy = hitPos.y - basePos.y;
        const dz = hitPos.z - basePos.z;

        // 3. Determine which face that corresponds to
        let face;
        if (dx === 1 && dy === 0 && dz === 0) face = "east";
        else if (dx === -1 && dy === 0 && dz === 0) face = "west";
        else if (dy === 1 && dx === 0 && dz === 0) face = "up";
        else if (dy === -1 && dx === 0 && dz === 0) face = "down";
        else if (dz === 1 && dx === 0 && dy === 0) face = "south";
        else if (dz === -1 && dx === 0 && dy === 0) face = "north";
        else {
          // Unexpected; not adjacent?
          // //world.sendMessage(`Unknown face delta: (${dx},${dy},${dz})`);
          return;
        }

        // 4. Map that face to your vine‐state key
        const faceToStateProp = {
          down: "hb_hr:floor_vine",
          north: "hb_hr:north_vine",
          east: "hb_hr:east_vine",
          south: "hb_hr:south_vine",
          west: "hb_hr:west_vine",
          // we ignore "down" here, or you could map it if desired
        };

        const stateKey = faceToStateProp[face];
        if (!stateKey) {
          // clicked the bottom face, or something unmapped
          return;
        }

        // 5. Pull current permutation, flip only that face’s state to true
        const perm = event.block.permutation;
        const newStates = {
          "hb_hr:floor_vine": perm.getState("hb_hr:floor_vine"),
          "hb_hr:north_vine": perm.getState("hb_hr:north_vine"),
          "hb_hr:east_vine": perm.getState("hb_hr:east_vine"),
          "hb_hr:south_vine": perm.getState("hb_hr:south_vine"),
          "hb_hr:west_vine": perm.getState("hb_hr:west_vine"),
        };
        const oldState = perm.getState(stateKey);
        newStates[stateKey] = true;

        // Wenn es vorher false war, also wirklich neu gesetzt wird:
        if (!oldState) {
          // Inventory-Component holen
          const invComp = event.player.getComponent("minecraft:inventory");
          const container = invComp.container;

          // Slotweise durchsuchen, first match
          for (let slot = 0; slot < container.size; slot++) {
            const stack = container.getItem(slot);
            if (stack && stack.typeId === "hb_hr:black_vine") {
              // nur dekrementieren, wenn tatsächlich noch mindestens 1 im Stack ist
              if (stack.amount > 1) {
                stack.amount--;
                container.setItem(slot, stack);
              } else {
                // Stack ist 0 → Slot leeren
                container.setItem(slot, undefined);
              }

              break;
            }
          }
        }

        // 6. Apply the updated permutation
        const newPerm = BlockPermutation.resolve(event.block.typeId, newStates);
        event.block.setPermutation(newPerm);

        // (optional) debug print
        // //world.sendMessage(`Set ${stateKey} via face “${face}”`);
      });

      // Prevent the normal interact/placement behavior
      event.cancel = true;
    });

    // Use this world initialization event to register all custom components
    world.beforeEvents.worldInitialize.subscribe(({ blockComponentRegistry }) => {
      for (const [componentName, componentImplementation] of Object.entries(customComponents)) {
        blockComponentRegistry.registerCustomComponent(componentName, componentImplementation);
      }
    });
    world.beforeEvents.itemUseOn.subscribe((event) => {
      const block = event.block;
      const player = event.source;
      const itemStack = event.itemStack;
      // if (player.typeId !== "minecraft:player") return;

      if (!(itemStack.typeId.includes("hb_hr:") && itemStack.typeId.includes("black_vine"))) return;
      if (!itemStack) return;

      // system.run(() => {
      //   // 1. Grab the two block positions
      //   const basePos = player.getBlockFromViewDirection().block.location;
      //   // const basePos = event.block.location;
      //   const hitBlock = block;
      //   const hitPos = hitBlock.location;

      //   //world.sendMessage("event  lbock " + event.block.typeId);
      //   //world.sendMessage("base lbock " + player.getBlockFromViewDirection().block.typeId);
      //   //world.sendMessage("hitBlock " + player.getBlockFromViewDirection({ excludeTypes: ["hb_hr:black_vine"] }).block.typeId);

      //   // 2. Compute delta
      //   const dx = hitPos.x - basePos.x;
      //   const dy = hitPos.y - basePos.y;
      //   const dz = hitPos.z - basePos.z;

      //   // 3. Determine which face that corresponds to
      //   let face;
      //   if (dx === 1 && dy === 0 && dz === 0) face = "east";
      //   else if (dx === -1 && dy === 0 && dz === 0) face = "west";
      //   else if (dy === 1 && dx === 0 && dz === 0) face = "up";
      //   else if (dy === -1 && dx === 0 && dz === 0) face = "down";
      //   else if (dz === 1 && dx === 0 && dy === 0) face = "south";
      //   else if (dz === -1 && dx === 0 && dy === 0) face = "north";
      //   else {
      //     // Unexpected; not adjacent?
      //     //world.sendMessage(`Unknown face delta: (${dx},${dy},${dz})`);
      //     return;
      //   }

      //   // 4. Map that face to your vine‐state key
      //   const faceToStateProp = {
      //     down: "hb_hr:floor_vine",
      //     north: "hb_hr:north_vine",
      //     east: "hb_hr:east_vine",
      //     south: "hb_hr:south_vine",
      //     west: "hb_hr:west_vine",
      //     // we ignore "down" here, or you could map it if desired
      //   };
      //   //world.sendMessage(face);
      //   //world.sendMessage(block.typeId);

      //   const stateKey = faceToStateProp[face];
      //   if (!stateKey) {
      //     // clicked the bottom face, or something unmapped
      //     return;
      //   }
      //   const newVine = player.getBlockFromViewDirection().block;
      //   // 5. Pull current permutation, flip only that face’s state to true
      //   const perm = newVine.permutation;
      //   const newStates = {
      //     "hb_hr:floor_vine": perm.getState("hb_hr:floor_vine"),
      //     "hb_hr:north_vine": perm.getState("hb_hr:north_vine"),
      //     "hb_hr:east_vine": perm.getState("hb_hr:east_vine"),
      //     "hb_hr:south_vine": perm.getState("hb_hr:south_vine"),
      //     "hb_hr:west_vine": perm.getState("hb_hr:west_vine"),
      //   };
      //   newStates[stateKey] = true;

      //   // 6. Apply the updated permutation
      //   const newPerm = BlockPermutation.resolve(newVine.typeId, newStates);
      //   newVine.setPermutation(newPerm);

      //   // (optional) debug print
      //   //world.sendMessage(`Set ${stateKey} via face “${face}”`);
      // });
    });
    world.beforeEvents.itemUse.subscribe((event) => {
      const player = event.source;
      const item = event.itemStack;

      if (item.typeId != "hb_hr:black_vine") return;

      // system.run(() => {
      //   // Map each direction to the vine‐face we need to set on the neighbor
      //   const oppositeFace = {
      //     north: "south_vine",
      //     south: "north_vine",
      //     east: "west_vine",
      //     west: "east_vine",
      //   };
      //   // Which block the player is looking at
      //   const interacted = player.getBlockFromViewDirection({ excludeTypes: ["hb_hr:black_vine"] }).block;
      //   //world.sendMessage(interacted.typeId);
      //   // Gather the four neighbors
      //   const neighbors = {
      //     north: interacted.north(),
      //     south: interacted.south(),
      //     east: interacted.east(),
      //     west: interacted.west(),
      //   };
      //   const blockFace = player.getBlockFromViewDirection().face;
      //   //world.sendMessage(blockFace);
      //   //world.sendMessage(interacted.typeId);

      //   if (blockFace == "Up") {
      //     //world.sendMessage("up facing block");
      //     const perm = interacted.permutation;
      //     const baseStates = {
      //       "hb_hr:floor_vine": true,
      //       "hb_hr:north_vine": perm.getState("hb_hr:north_vine"),
      //       "hb_hr:east_vine": perm.getState("hb_hr:east_vine"),
      //       "hb_hr:south_vine": perm.getState("hb_hr:south_vine"),
      //       "hb_hr:west_vine": perm.getState("hb_hr:west_vine"),
      //     };
      //     const newPerm = BlockPermutation.resolve(interacted.typeId, baseStates);
      //     interacted.setPermutation(newPerm);
      //     //world.sendMessage(interacted.permutation.getState("hb_hr:floor_vine").toString());

      //     return;
      //   }
      //   //world.sendMessage("face not up");

      //   for (const [dir, block] of Object.entries(neighbors)) {
      //     if (!block || block.typeId !== "hb_hr:black_vine") continue;

      //     // Grab its current permutation states
      //     const perm = block.permutation;
      //     const baseStates = {
      //       "hb_hr:floor_vine": perm.getState("hb_hr:floor_vine"),
      //       "hb_hr:north_vine": perm.getState("hb_hr:north_vine"),
      //       "hb_hr:east_vine": perm.getState("hb_hr:east_vine"),
      //       "hb_hr:south_vine": perm.getState("hb_hr:south_vine"),
      //       "hb_hr:west_vine": perm.getState("hb_hr:west_vine"),
      //     };

      //     // Set the one facing the clicked block to true
      //     const faceKey = `hb_hr:${oppositeFace[dir]}`;
      //     baseStates[faceKey] = true;

      //     // Build and apply the new permutation
      //     const newPerm = BlockPermutation.resolve(block.typeId, baseStates);
      //     block.setPermutation(newPerm);
      //   }
      // });
    });
    world.afterEvents.playerPlaceBlock.subscribe((event) => {
      const block = event.block;
      const player = event.player;

      breakVines(event.block);

      // //world.sendMessage(block.above().typeId);

      switch (block.typeId) {
        case "hb_hr:black_vine":
          break;
        case "hb_hr:gravestone":
          const randomTexture = Math.floor(Math.random() * 3);
          const baseStates = {
            "hb_hr:random_texture": randomTexture,
            "hb_hr:open": block.permutation.getState("hb_hr:open"),
            "hb_hr:waterlogged": block.permutation.getState("hb_hr:waterlogged"),
            "hb_hr:powered": block.permutation.getState("hb_hr:powered"),
            "minecraft:cardinal_direction": block.permutation.getState("minecraft:cardinal_direction"),
            "minecraft:vertical_half": block.permutation.getState("minecraft:vertical_half"),
          };
          const newPerm = BlockPermutation.resolve(block.typeId, baseStates);
          block.setPermutation(newPerm);
          break;
      }
    });
    world.afterEvents.playerBreakBlock.subscribe((event) => {
      const block = event.brokenBlockPermutation;
      const usedItem = event.itemStackAfterBreak;
      const player = event.player;
      let dropSelector = Math.random();
      let blockItem = "empty";

      switch (block.type.id) {
        case "hb_hr:black_leaves":
          if (usedItem) {
            if (dropSelector < 0.05) {
              blockItem = new ItemStack("minecraft:stick");
            } else if (dropSelector > 0.95) {
              blockItem = new ItemStack("hb_hr:black_sapling");
            }
            if (blockItem != "empty") world.getDimension(player.dimension.id).spawnItem(blockItem, event.block.location);
            break;
          }
          if (usedItem == undefined) {
            if (dropSelector < 0.05) {
              blockItem = new ItemStack("minecraft:stick");
            } else if (dropSelector > 0.95) {
              blockItem = new ItemStack("hb_hr:black_sapling");
            }
            if (blockItem != "empty") world.getDimension(player.dimension.id).spawnItem(blockItem, event.block.location);
            break;
          }
          if (usedItem.hasTag("minecraft:is_shears") || usedItem.typeId.includes("shears")) {
            blockItem = new ItemStack("hb_hr:black_leaves");
          }
          if (usedItem.getComponent("enchantable") != undefined) {
            const enchants = usedItem.getComponent("enchantable");
            if (enchants.getEnchantment("silk_touch") != undefined) {
              break;
            }
          }
          if (blockItem != "empty") world.getDimension(player.dimension.id).spawnItem(blockItem, event.block.location);
          break;
      }

      // if (event.block.typeId == "hb_hr:black_vine") {
      //   const perm = event.block.permutation;
      //   // system.run(() => {
      //   // // 1) Positionen für Face-Berechnung
      //   // const basePos = event.block.location;
      //   // const hitInfo = event.player.getBlockFromViewDirection({
      //   // excludeTypes: ["hb_hr:black_vine"],
      //   // });
      //   // if (!hitInfo) return;
      //   // const hitPos = hitInfo.block.location;

      //   // // 2) Delta berechnen
      //   // const dx = hitPos.x - basePos.x;
      //   // const dy = hitPos.y - basePos.y;
      //   // const dz = hitPos.z - basePos.z;

      //   // // 3) Face bestimmen
      //   // let face;
      //   // if (dx === 1 && dy === 0 && dz === 0) face = "east";
      //   // else if (dx === -1 && dy === 0 && dz === 0) face = "west";
      //   // else if (dy === 1 && dx === 0 && dz === 0) face = "up";
      //   // else if (dy === -1 && dx === 0 && dz === 0) face = "down";
      //   // else if (dz === 1 && dx === 0 && dy === 0) face = "south";
      //   // else if (dz === -1 && dx === 0 && dy === 0) face = "north";
      //   // else return; // nicht angrenzend

      //   // // 4) Face → State-Key Map
      //   // const faceToStateKey = {
      //   // up: "hb_hr:floor_vine",
      //   // north: "hb_hr:north_vine",
      //   // east: "hb_hr:east_vine",
      //   // south: "hb_hr:south_vine",
      //   // west: "hb_hr:west_vine",
      //   // // down kannst du ignorieren oder extra behandeln
      //   // };
      //   // const stateKey = faceToStateKey[face];
      //   // if (!stateKey) return;

      //   // // 5) Alle Zustände auslesen und nur das eine Flag auf false setzen
      //   // const currentStates = event.block.permutation.getAllStates();
      //   // currentStates[stateKey] = false;

      //   // // 6) Neue Permutation anwenden
      //   // const newPerm = BlockPermutation.resolve(event.block.typeId, currentStates);
      //   // event.block.setPermutation(newPerm);

      //   // //world.sendMessage(`Vine-State ${stateKey} auf false gesetzt, rest unverändert.`);
      //   // });
      //   system.run(() => {
      //     const allStates = perm.getAllStates();
      //     //world.sendMessage(allStates.toString());
      //     let counter = 0;
      //     // 2) Or using a for…of loop:
      //     for (const [key, value] of Object.entries(allStates)) {
      //       //world.sendMessage(key + "=" + value);
      //       if (key.includes("_vine") && value == true) {
      //         counter++;
      //       }
      //     }
      //     //world.sendMessage(counter.toString());
      //     if (counter == 1) {
      //       //world.sendMessage("break full block");
      //     } else {
      //       // 1. Grab the two block positions
      //       const basePos = event.player.getBlockFromViewDirection().block.location;
      //       // const basePos = event.block.location;
      //       const hitBlock = event.block;
      //       const hitPos = hitBlock.location;

      //       //world.sendMessage("event  lbock " + event.block.typeId);
      //       //world.sendMessage("base lbock " + event.player.getBlockFromViewDirection().block.typeId);
      //       //world.sendMessage("base lbock " + event.block.typeId);
      //       //world.sendMessage("hitBlock " + event.player.getBlockFromViewDirection({ excludeTypes: ["hb_hr:black_vine"] }).block.typeId);
      //       //world.sendMessage("hitBlock " + hitBlock.typeId);

      //       // 2. Compute delta
      //       const dx = hitPos.x - basePos.x;
      //       const dy = hitPos.y - basePos.y;
      //       const dz = hitPos.z - basePos.z;

      //       // 3. Determine which face that corresponds to
      //       let face;
      //       if (dx === 1 && dy === 0 && dz === 0) face = "east";
      //       else if (dx === -1 && dy === 0 && dz === 0) face = "west";
      //       else if (dy === 1 && dx === 0 && dz === 0) face = "up";
      //       else if (dy === -1 && dx === 0 && dz === 0) face = "down";
      //       else if (dz === 1 && dx === 0 && dy === 0) face = "south";
      //       else if (dz === -1 && dx === 0 && dy === 0) face = "north";
      //       else {
      //         // Unexpected; not adjacent?
      //         //world.sendMessage(`Unknown face delta: (${dx},${dy},${dz})`);
      //         return;
      //       }

      //       // 4. Map that face to your vine‐state key
      //       const faceToStateProp = {
      //         up: "hb_hr:floor_vine",
      //         south: "hb_hr:north_vine",
      //         west: "hb_hr:east_vine",
      //         north: "hb_hr:south_vine",
      //         east: "hb_hr:west_vine",
      //         // we ignore "down" here, or you could map it if desired
      //       };
      //       // //world.sendMessage(face);
      //       // //world.sendMessage(block.typeId);

      //       const stateKey = faceToStateProp[face];
      //       if (!stateKey) {
      //         //world.sendMessage("return statekey err");
      //         // clicked the bottom face, or something unmapped
      //         return;
      //       }
      //       event.block.setType("hb_hr:black_vine");
      //       const newVine = event.block;
      //       //world.sendMessage("newvbine: " + newVine.typeId);
      //       // 5. Pull current permutation, flip only that face’s state to true
      //       const perm = newVine.permutation;
      //       const newStates = {
      //         "hb_hr:floor_vine": event.block.permutation.getState("hb_hr:north_vine"),
      //         "hb_hr:north_vine": event.block.permutation.getState("hb_hr:north_vine"),
      //         "hb_hr:east_vine": event.block.permutation.getState("hb_hr:east_vine"),
      //         "hb_hr:south_vine": event.block.permutation.getState("hb_hr:south_vine"),
      //         "hb_hr:west_vine": event.block.permutation.getState("hb_hr:west_vine"),
      //       };
      //       newStates[stateKey] = false;

      //       // 6. Apply the updated permutation
      //       const newPerm = BlockPermutation.resolve(event.block.typeId, newStates);
      //       newVine.setPermutation(newPerm);

      //       //world.sendMessage("hb_hr:floor_vine: " + event.block.permutation.getState("hb_hr:floor_vine"));
      //       //world.sendMessage("hb_hr:north_vine: " + event.block.permutation.getState("hb_hr:north_vine"));
      //       //world.sendMessage("hb_hr:east_vine: " + event.block.permutation.getState("hb_hr:east_vine"));
      //       //world.sendMessage("hb_hr:south_vine: " + event.block.permutation.getState("hb_hr:south_vine"));
      //       //world.sendMessage("hb_hr:west_vine: " + event.block.permutation.getState("hb_hr:west_vine"));
      //       //world.sendMessage(event.block.typeId);

      //       // (optional) debug print
      //       //world.sendMessage(`Set ${stateKey} via face “${face}”`);

      //       // event.block.setType("dirt");
      //       //world.sendMessage("break side vine and set block ");
      //     }
      //   });
      // }
    });
    world.afterEvents.playerBreakBlock.subscribe((event) => {
      const block = event.brokenBlockPermutation;
      const usedItem = event.itemStackAfterBreak;
      const player = event.player;
      let blockItem = "empty";
      const seedDropChance = 0.875;

      switch (block.type.id) {
        case "hb_hr:black_short_grass":
          if (usedItem == undefined) {
            if (Math.random() > seedDropChance) {
              blockItem = new ItemStack("minecraft:wheat_seeds");
            }
          }
          if (usedItem) {
            switch (usedItem.typeId) {
              case undefined:
                if (Math.random() > seedDropChance) blockItem = new ItemStack("minecraft:wheat_seeds");
                break;
              case "minecraft:shears":
                blockItem = new ItemStack("hb_hr:black_short_grass");
                break;
              default:
                if (Math.random() > seedDropChance) {
                  blockItem = new ItemStack("minecraft:wheat_seeds");
                }
                break;
            }
          }
          if (blockItem != "empty") {
            world.getDimension(player.dimension.id).spawnItem(blockItem, event.block.location);
          }
          break;
        case "hb_hr:black_grass_block":
          if (usedItem == undefined) {
            blockItem = new ItemStack("minecraft:dirt");
          }
          if (usedItem) {
            switch (usedItem.typeId) {
              case undefined:
                blockItem = new ItemStack("minecraft:dirt");
                break;
              default:
                blockItem = new ItemStack("minecraft:dirt");
                break;
            }
            if (usedItem.getComponent("enchantable") != undefined) {
              const enchants = usedItem.getComponent("enchantable");
              if (enchants.getEnchantment("silk_touch") != undefined) {
                return;
              }
            }
          }
          if (blockItem != "empty") {
            world.getDimension(player.dimension.id).spawnItem(blockItem, event.block.location);
          }
          break;
        default:
          break;
      }
    });
  }

  spawnItemFromBlock(player, block, SpawnItemName) {
    // //world.sendMessage("spawn 3");
    let blockItem = new ItemStack(SpawnItemName);
    world.getDimension(player.dimension.id).spawnItem(blockItem, block.location);
  }
}

export function vineCheckBlockBelow(block) {
  if (block.below().typeId == "minecraft:air" || block.below().typeId == "hb_hr:hive_carpet" || block.below().typeId == "minecraft:structure_void" || block.below().typeId == "hb_hr:small_hive_egg" || block.below().typeId == "hb_hr:large_hive_egg") {
    if (block.permutation.getState("hb_hr:full_block") == false) return;
    const newPermutationAbove = BlockPermutation.resolve(block.typeId, {
      "minecraft:block_face": block.permutation.getState("minecraft:block_face"),
      "hb_hr:full_block": false,
    });
    block.setPermutation(newPermutationAbove);
  }
}

export function breakVines(block) {
  // if (block.typeId == "hb_hr:black_vine" && block.above().typeId == "minecraft:air") {
  //   block.dimension.runCommand("/fill " + block.location.x + " " + block.location.y + " " + block.location.z + " " + block.location.x + " " + block.location.y + " " + block.location.z + " air destroy");
  // }
  if (block.typeId == "minecraft:air" && block.above().typeId == "hb_hr:black_vine") {
    // If the event block is air and the block above is a hive vine, update the above block's permutation.
    const newPermutationAbove = BlockPermutation.resolve("hb_hr:black_vine", {
      "minecraft:block_face": block.above().permutation.getState("minecraft:block_face"),
      "hb_hr:full_block": false,
    });
    block.above().setPermutation(newPermutationAbove);
  }

  // if (block.typeId == "hb_hr:black_vine" && block.above().typeId == "minecraft:air") {
  //   // Cast a ray downward from the event block to find the last vine block.
  //   const lastVineBlock = block.dimension.getBlockFromRay(
  //     block.location,
  //     { x: 0, y: -100, z: 0 },
  //     {
  //       excludeTypes: ["hb_hr:black_vine"],
  //     }
  //   );
  //   // Create a volume from the event block's location to the last vine block's location.
  //   const volume = new BlockVolume({ x: block.location.x, y: block.location.y, z: block.location.z }, { x: block.location.x, y: lastVineBlock.block.location.y + 1, z: block.location.z });
  //   // Iterate over each block location in the volume and replace the block with air.
  //   const locations = volume.getBlockLocationIterator();
  //   for (const location of locations) {
  //     const vineBlock = block.dimension.getBlock(location);
  //     //world.sendMessage("break here");
  //     block.dimension.runCommand("/fill " + vineBlock.location.x + " " + vineBlock.location.y + " " + vineBlock.location.z + " " + vineBlock.location.x + " " + vineBlock.location.y + " " + vineBlock.location.z + " air destroy");
  //   }
  // }
}

export function placeFarmland() {
  const farmlandBlocks = ["hb_hr:black_grass_block", "hb_hr:dried_black_grass_block"];

  world.beforeEvents.itemUseOn.subscribe((event) => {
    const block = event.block;
    const player = event.source;
    const itemStack = event.itemStack;
    if (player.typeId !== "minecraft:player") return;

    if (!(itemStack.typeId.includes("minecraft:") && itemStack.typeId.includes("hoe"))) return;
    if (!itemStack) return;

    system.run(() => {
      const testBlock = world.getDimension(player.dimension.id).getBlock(block.location);
      if (farmlandBlocks.includes(testBlock.typeId)) {
        world
          .getDimension(player.dimension.id)
          .getBlock({ x: testBlock.location.x + 0.5, y: testBlock.location.y, z: testBlock.location.z + 0.5 })
          .setType("minecraft:farmland");
      }
    });
  });
}

function destroyAllSideVines(player, startBlock) {
}
function destroySingleSideVines(player, startBlock, directionToDestroy) {
  // Cast a ray downward from the event block to find the last vine block.
  let currentBlock = startBlock;
  if (currentBlock.below().typeId == "hb_hr:black_vine") {
    destroySingleSideVines(player, currentBlock.below(), directionToDestroy);
  }
  if (currentBlock.typeId == "hb_hr:black_vine") {
    if (checkBlockBehindVineBlock(player, currentBlock, directionToDestroy) == false) {
      return;
    }
    const perm = currentBlock.permutation;
    // //world.sendMessage("current: +++++++" + currentBlock.typeId);
    // //world.sendMessage("abovew: +++++++" + currentBlock.above().typeId);

    if (currentBlock.above().typeId == "hb_hr:black_vine") {
      // //world.sendMessage("######black_vine above");
      return;
    }
    if (currentBlock.above().typeId == "minecraft:air") {
      // currentBlock.setType("dirt");
      // //world.sendMessage("####air above");
      // list out all five possible vine‐states
      const dirs = ["hb_hr:floor_vine", "hb_hr:north_vine", "hb_hr:east_vine", "hb_hr:south_vine", "hb_hr:west_vine"];
      const newStates = dirs.reduce((map, dir) => {
        const key = dir;
        // if this is the side to destroy, always false, otherwise keep old
        map[key] = dir === directionToDestroy ? false : perm.getState(key);
        return map;
      }, {});
      // 6. Apply the updated permutation
      try {
        const newPerm = BlockPermutation.resolve(currentBlock.typeId, newStates);
        currentBlock.setPermutation(newPerm);
        // //world.sendMessage("sssssssssabove " + currentBlock.typeId.toString());
        // currentBlock.setType("dirt");
        // check block behind if that is solid then break
        destroyVineWithZeroVineStates(player, currentBlock, directionToDestroy);
      } catch (error) {
        // //world.sendMessage(directionToDestroy + " ERRRR########");
        // currentBlock.setType("gold_block");
        player.dimension.runCommand("/fill " + currentBlock.location.x + " " + currentBlock.location.y + " " + currentBlock.location.z + " " + currentBlock.location.x + " " + currentBlock.location.y + " " + currentBlock.location.z + " air destroy");
      }
    }
  }
}
// const lastVineBlock = player.dimension.getBlockFromRay(
//   startBlock.location,
//   { x: 0, y: -100, z: 0 },
//   {
//     excludeTypes: ["hb_hr:black_vine"],
//   }
// );

// //world.sendMessage(startBlock.typeId);
// //world.sendMessage(lastVineBlock.block.typeId);
// // Create a volume from the event block's location to the last vine block's location.
// const volume = new BlockVolume({ x: startBlock.location.x, y: startBlock.location.y - 1, z: startBlock.location.z }, { x: startBlock.location.x, y: lastVineBlock.block.location.y + 1, z: startBlock.location.z });

// // Iterate over each block location in the volume and replace the block with air.
// const locations = volume.getBlockLocationIterator();
// for (const location of locations) {
//   const vineBlock = player.dimension.getBlock(location);
// if (vineBlock.typeId == "hb_hr:black_vine") {
//   if (checkBlockBehindVineBlock(player, vineBlock, directionToDestroy) == false) {
//     //world.sendMessage("STOP BREAKING");
//     break;
//   }
// }
// const perm = vineBlock.permutation;
// //world.sendMessage("current: +++++++" + vineBlock.typeId);
// //world.sendMessage("abovew: +++++++" + vineBlock.above().typeId);

// if (vineBlock.above().typeId == "hb_hr:black_vine") {
//   //world.sendMessage("######black_vine above");
//   break;
// }
// if (vineBlock.above().typeId == "minecraft:air") {
//   // vineBlock.setType("dirt");
//   //world.sendMessage("####air above");
//   // list out all five possible vine‐states
//   const dirs = ["hb_hr:floor_vine", "hb_hr:north_vine", "hb_hr:east_vine", "hb_hr:south_vine", "hb_hr:west_vine"];
//   const newStates = dirs.reduce((map, dir) => {
//     const key = dir;
//     // if this is the side to destroy, always false, otherwise keep old
//     map[key] = dir === directionToDestroy ? false : perm.getState(key);
//     return map;
//   }, {});
//   // 6. Apply the updated permutation
//   try {
//     const newPerm = BlockPermutation.resolve(vineBlock.typeId, newStates);
//     vineBlock.setPermutation(newPerm);
//     //world.sendMessage("sssssssssabove " + vineBlock.typeId.toString());
//     // vineBlock.setType("dirt");
//     // check block behind if that is solid then break
//     destroyVineWithZeroVineStates(player, vineBlock, directionToDestroy);
//   } catch (error) {
//     //world.sendMessage(directionToDestroy + " ERRRR########");
//     // vineBlock.setType("gold_block");
//     player.dimension.runCommand("/fill " + vineBlock.location.x + " " + vineBlock.location.y + " " + vineBlock.location.z + " " + vineBlock.location.x + " " + vineBlock.location.y + " " + vineBlock.location.z + " air destroy");
//   }
// }
//   }
// }

function checkBlockBehindVineBlock(player, block, directionToDestroy) {
  // 1) extract e.g. "west" from "hb_hr:west_vine"
  //    split off the namespace, then strip the "_vine" suffix
  const [, rawDir] = directionToDestroy.split(":"); // ["hb_hr","west_vine"]
  const dirName = rawDir.replace("_vine", ""); // "west"

  // 2) map each direction name to a vector offset
  const dirVectors = {
    north: { x: 0, y: 0, z: -1 },
    south: { x: 0, y: 0, z: 1 },
    west: { x: -1, y: 0, z: 0 },
    east: { x: 1, y: 0, z: 0 },
    up: { x: 0, y: 1, z: 0 },
    down: { x: 0, y: -1, z: 0 },
  };

  const vec = dirVectors[dirName];
  if (!vec) {
    //world.sendMessage("no VINES HERE");
    // unrecognized direction—debug message
    // player.dimension.runCommand(`say §cUnknown vine‐direction '${dirName}'`);
    return;
  }

  // 3) compute the target position one block “behind” in that direction
  const behindPos = { x: block.location.x + vec.x, y: block.location.y + vec.y, z: block.location.z + vec.z };

  // 4) fetch that block and, if it’s air, destroy it
  const dim = player.dimension;
  const behindBlock = dim.getBlock(behindPos);
  //world.sendMessage("BLOCK BEHIND IS: " + behindBlock.typeId);
  if (behindBlock.typeId != "minecraft:air") {
    //world.sendMessage("block behind is no air");
    return false;
  } else {
    //world.sendMessage("block behind is  air");
    return true;
  }
}
function destroyVineWithZeroVineStates(player, block, directionToDestroy) {
  const perm = block.permutation;
  const allStates = perm.getAllStates();
  let counter = 0;
  // 2) Or using a for…of loop:
  for (const [key, value] of Object.entries(allStates)) {
    //world.sendMessage(key + "=" + value);
    if (key.includes("_vine") && value == true) {
      counter++;
    }
  }
  if (counter === 0) {
    // 1) extract e.g. "west" from "hb_hr:west_vine"
    //    split off the namespace, then strip the "_vine" suffix
    const [, rawDir] = directionToDestroy.split(":"); // ["hb_hr","west_vine"]
    const dirName = rawDir.replace("_vine", ""); // "west"

    // 2) map each direction name to a vector offset
    const dirVectors = {
      north: { x: 0, y: 0, z: -1 },
      south: { x: 0, y: 0, z: 1 },
      west: { x: -1, y: 0, z: 0 },
      east: { x: 1, y: 0, z: 0 },
      up: { x: 0, y: 1, z: 0 },
      down: { x: 0, y: -1, z: 0 },
    };

    const vec = dirVectors[dirName];
    if (!vec) {
      //world.sendMessage("no VINES HERE");
      // unrecognized direction—debug message
      // player.dimension.runCommand(`say §cUnknown vine‐direction '${dirName}'`);
      return;
    }

    // 3) compute the target position one block “behind” in that direction
    const behindPos = { x: block.location.x + vec.x, y: block.location.y + vec.y, z: block.location.z + vec.z };

    // 4) fetch that block and, if it’s air, destroy it
    const dim = player.dimension;
    const behindBlock = dim.getBlock(behindPos);
    //world.sendMessage;

    system.runTimeout(() => {
      if (behindBlock.typeId === "minecraft:air") {
        //world.sendMessage("air");
        player.dimension.runCommand("/fill " + block.location.x + " " + block.location.y + " " + block.location.z + " " + block.location.x + " " + block.location.y + " " + block.location.z + " air destroy");
        //world.sendMessage("##############above " + block.above().typeId);
        //world.sendMessage("##############current " + block.typeId);
        // destroys the air block (no-op) but clears any tile entity/etc.
        // dim.runCommand(`/fill ${behindPos.x} ${behindPos.y} ${behindPos.z} ` + `${behindPos.x} ${behindPos.y} ${behindPos.z} air destroy`);
      } else {
        //world.sendMessage("full block ");
        //world.sendMessage("##############above " + block.above().typeId);
        //world.sendMessage("##############current " + block.typeId);
      }
    }, 5);
  }
}

function destroySideVines(player, startBlock) {
  // Cast a ray downward from the event block to find the last vine block.
  const lastVineBlock = player.dimension.getBlockFromRay(
    startBlock.location,
    { x: 0, y: -100, z: 0 },
    {
      excludeTypes: ["hb_hr:black_vine"],
    }
  );

  // Create a volume from the event block's location to the last vine block's location.
  const volume = new BlockVolume({ x: startBlock.location.x, y: startBlock.location.y, z: startBlock.location.z }, { x: startBlock.location.x, y: lastVineBlock.block.location.y + 1, z: startBlock.location.z });

  // Iterate over each block location in the volume and replace the block with air.
  const locations = volume.getBlockLocationIterator();
  for (const location of locations) {
    const vineBlock = player.dimension.getBlock(location);
    player.dimension.runCommand("/fill " + vineBlock.location.x + " " + vineBlock.location.y + " " + vineBlock.location.z + " " + vineBlock.location.x + " " + vineBlock.location.y + " " + vineBlock.location.z + " air destroy");
  }
}

function initDestroySideVines(player, block) {
  const northBlock = block.north();
  const southBlock = block.south();
  const eastBlock = block.east();
  const westBlock = block.west();
  if (northBlock && northBlock.typeId == "hb_hr:black_vine") destroySideVines(player, northBlock);
  if (southBlock && southBlock.typeId == "hb_hr:black_vine") destroySideVines(player, southBlock);
  if (eastBlock && eastBlock.typeId == "hb_hr:black_vine") destroySideVines(player, eastBlock);
  if (westBlock && westBlock.typeId == "hb_hr:black_vine") destroySideVines(player, westBlock);
  player.dimension.runCommand("/fill " + block.location.x + " " + block.location.y + " " + block.location.z + " " + block.location.x + " " + block.location.y + " " + block.location.z + " air destroy");
}

function checkForblackVinesAndChangeStates(testblock) {
  // for each of the four horizontal directions...
  const brokenBlock = testblock;
  //world.sendMessage(brokenBlock.typeId);
  const neighbors = [
    { dir: "south", block: brokenBlock.north() },
    { dir: "north", block: brokenBlock.south() },
    { dir: "west", block: brokenBlock.east() },
    { dir: "east", block: brokenBlock.west() },
  ];

  for (const { dir, block } of neighbors) {
    if (!block) continue;
    // only touch your black-vine blocks
    if (block.typeId === "hb_hr:black_vine") {
      //world.sendMessage("VINE HERE");
      removeVineAttachment(block, dir);
    }
  }
  // //world.sendMessage(" sdasad");
  // const northBlock = block.north();
  // const southBlock = block.south();
  // const eastBlock = block.east();
  // const westBlock = block.west();
  // if (northBlock) updateNearbyblackVine(player, northBlock);
  // if (southBlock) updateNearbyblackVine(player, southBlock);
  // if (eastBlock) updateNearbyblackVine(player, eastBlock);
  // if (westBlock) updateNearbyblackVine(player, westBlock);
}

// 2) Turn off the single face on the neighbour
function removeVineAttachment(block, brokenSide) {
  // pull out all five vine-states
  const perm = block.permutation;
  const states = {
    "hb_hr:floor_vine": perm.getState("hb_hr:floor_vine"),
    "hb_hr:north_vine": perm.getState("hb_hr:north_vine"),
    "hb_hr:east_vine": perm.getState("hb_hr:east_vine"),
    "hb_hr:south_vine": perm.getState("hb_hr:south_vine"),
    "hb_hr:west_vine": perm.getState("hb_hr:west_vine"),
  };

  // flip off the one corresponding to the broken side
  // e.g. if we’re updating the block north of the break, brokenSide === "north"
  states[`hb_hr:${brokenSide}_vine`] = false;

  // build and apply the new permutation
  const newPerm = BlockPermutation.resolve(block.typeId, states);
  block.setPermutation(newPerm);
}

// function removeVineAttachment(block) {
//   // Grab its current permutation states
//   const perm = block.permutation;
//   const baseStates = {
//     "hb_hr:floor_vine": perm.getState("hb_hr:floor_vine"),
//     "hb_hr:north_vine": perm.getState("hb_hr:north_vine"),
//     "hb_hr:east_vine": perm.getState("hb_hr:east_vine"),
//     "hb_hr:south_vine": perm.getState("hb_hr:south_vine"),
//     "hb_hr:west_vine": perm.getState("hb_hr:west_vine"),
//   };
//   const newPerm = BlockPermutation.resolve(interacted.typeId, baseStates);
//   interacted.setPermutation(newPerm);
// }
