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

const processedBlocks = new Map();

world.beforeEvents.worldInitialize.subscribe((eventData) => {
  eventData.blockComponentRegistry.registerCustomComponent("pu_biomes:doors", {
    onPlace(e) {
      const { block } = e;
      const above = block.above();
      const below = block.below();
      const { x, y, z } = block.location;

      if (processedBlocks.has(`${x},${y},${z}`)) return;

      const currentStates = block.permutation.getAllStates();
      const direction = currentStates["minecraft:cardinal_direction"];
      const isUpper = !!block.permutation.getState("pu_biomes:upper_block_bit");

      if (!isUpper) {
        if (
          above.typeId !== "minecraft:air" ||
          below.typeId === "minecraft:air"
        ) {
          block.dimension.runCommand(`setblock ${x} ${y} ${z} air destroy`);
          return;
        }

        if (block.hasTag("pu_biomes:custom_door")) {
          const upperPerm = BlockPermutation.resolve(block.typeId, {
            "pu_biomes:upper_block_bit": true,
            "minecraft:cardinal_direction": direction,
          });
          above.setPermutation(upperPerm);
          block.setPermutation(
            BlockPermutation.resolve(block.typeId, currentStates)
          );
        }

        const hingeCheck = (dir, offsetBlock, getOffsetAbove) => {
          if (
            direction === dir &&
            offsetBlock?.hasTag("pu_biomes:custom_door")
          ) {
            const offsetStates = offsetBlock.permutation.getAllStates();
            if (!offsetStates["pu_biomes:door_hinge_bit"]) {
              const updated = BlockPermutation.resolve(block.typeId, {
                ...currentStates,
                "pu_biomes:door_hinge_bit": true,
              });
              block.setPermutation(updated);
            }
            const aboveDir = above.permutation.getState(
              "minecraft:cardinal_direction"
            );
            const offsetAbove = getOffsetAbove();
            if (
              aboveDir === dir &&
              offsetAbove?.hasTag("pu_biomes:custom_door")
            ) {
              const offsetAboveStates = offsetAbove.permutation.getAllStates();
              if (!offsetAboveStates["pu_biomes:door_hinge_bit"]) {
                const updatedAbove = BlockPermutation.resolve(above.typeId, {
                  ...offsetAboveStates,
                  "pu_biomes:door_hinge_bit": true,
                });
                above.setPermutation(updatedAbove);
              }
            }
          }
        };

        hingeCheck("south", block.east(), () => above.east());
        hingeCheck("east", block.north(), () => above.north());
        hingeCheck("north", block.west(), () => above.west());
        hingeCheck("west", block.south(), () => above.south());
      } else {
        if (!below?.hasTag("pu_biomes:custom_door")) {
          block.setType("minecraft:air");
          return;
        }
      }

      processedBlocks.set(`${x},${y},${z}`, true);
    },

    onPlayerInteract(e) {
      const { block, player } = e;
      if (!block.hasTag("pu_biomes:custom_door")) return;

      const isUpper = block.permutation.getState("pu_biomes:upper_block_bit");
      const equipment = player.getComponent("equippable");
      const item = equipment.getEquipment("Mainhand");
      const target = isUpper ? block.below() : block.above();

      const newState = !block.permutation.getState("pu_biomes:open_bit");
      const newBlock = BlockPermutation.resolve(block.typeId, {
        ...block.permutation.getAllStates(),
        "pu_biomes:open_bit": newState,
      });
      const newTarget = BlockPermutation.resolve(target.typeId, {
        ...target.permutation.getAllStates(),
        "pu_biomes:open_bit": newState,
      });

      block.setPermutation(newBlock);
      target.setPermutation(newTarget);

      player.playSound(newState ? "open.wooden_door" : "close.wooden_door");

      if (item?.typeId === "minecraft:water_bucket") {
        player.playSound("bucket.empty_water");
        if (player.getGameMode() !== "creative") {
          equipment.setEquipment(
            "Mainhand",
            new ItemStack("minecraft:bucket", 1)
          );
        }
      }
    },
  });
});

world.afterEvents.playerBreakBlock.subscribe((eventData) => {
  const { block } = eventData;
  const { x, y, z } = block.location;

  processedBlocks.delete(`${x},${y},${z}`);

  const above = block.above();
  const below = block.below();

  if (below?.hasTag("pu_biomes:custom_door")) {
    below.setType("minecraft:air");
    processedBlocks.delete(`${x},${y - 1},${z}`);
  }
  if (above?.hasTag("pu_biomes:custom_door")) {
    above.setType("minecraft:air");
    processedBlocks.delete(`${x},${y + 1},${z}`);
  }
});
