// Import necessary modules from Minecraft server API
import { world, ItemStack } from "@minecraft/server";

// Helper function to find the adjacent block based on direction and side
function getAdjacentBlock(block, direction, side) {
  try {
    switch (side) {
      case "left":
        switch (direction) {
          case "north":
            return block.west(1);
          case "south":
            return block.east(1);
          case "east":
            return block.north(1);
          case "west":
            return block.south(1);
        }
        break;
      case "right":
        switch (direction) {
          case "north":
            return block.east(1);
          case "south":
            return block.west(1);
          case "east":
            return block.south(1);
          case "west":
            return block.north(1);
        }
        break;
    }
  } catch {
    return undefined;
  }
}

// Helper function to get the location in front of the block based on facing direction
function getFrontLocation(block, direction) {
  const location = block.location;
  switch (direction) {
    case "north":
      return { x: location.x, y: location.y, z: location.z + 1 };
    case "south":
      return { x: location.x, y: location.y, z: location.z - 1 };
    case "east":
      return { x: location.x - 1, y: location.y, z: location.z };
    case "west":
      return { x: location.x + 1, y: location.y, z: location.z };
    default:
      return location; // Default to the block location if direction is undefined
  }
}

// Subscribe to the 'worldInitialize' event to register custom components
world.beforeEvents.worldInitialize.subscribe((event) => {
  event.blockComponentRegistry.registerCustomComponent(
    "pb_dino:tank_interactions",
    {
      onPlayerInteract(int) {
        const { block, player } = int;
        const equipment = player.getComponent("equippable");
        const selectedItem = equipment.getEquipment("Mainhand");
        const connected = block.permutation.getState("pb_dino:mb_position");
        const oilQty = block.permutation.getState("pb_dino:oil_quantity");

        // Array of valid item IDs
        const validItems = [
          "pb_dino:dino_bone",
          "pb_dino:dino_meat",
          "pb_dino:bug_meat",
        ];

        ////////// SUCCESSFUL INTERACTIONS /////////////////////////////////////////////////
        // Check for empty hand - and fuel above 0 - to give runner ball
        if (connected !== "single" && !selectedItem && oilQty > 0) {
          player.onScreenDisplay.setActionBar(
            {translate:"action.hint.pb_dino:pyro_take_rubber"}
          );
          world.playSound("fall.slime", block.center());
          const newQty = oilQty - 1;
          block.setPermutation(
            block.permutation.withState("pb_dino:oil_quantity", newQty)
          );

          const facingDirection = block.permutation.getState(
            "minecraft:cardinal_direction"
          );
          const adjacentPosition = connected === "left" ? "right" : "left";
          const adjacentBlock = getAdjacentBlock(
            block,
            facingDirection,
            adjacentPosition
          );

          if (block.typeId == "pb_dino:pyrolyzer") {
            player.dimension.runCommand(
              `particle minecraft:basic_smoke_particle ${adjacentBlock.x} ${
                adjacentBlock.y + 1.8
              } ${adjacentBlock.z}`
            );
          }
          if (block.typeId == "pb_dino:pyrolyzer_tank") {
            player.dimension.runCommand(
              `particle minecraft:basic_smoke_particle ${block.x} ${
                block.y + 1.8
              } ${block.z}`
            );
          }

          if (adjacentBlock) {
            try {
              adjacentBlock.setPermutation(
                adjacentBlock.permutation.withState(
                  "pb_dino:oil_quantity",
                  newQty
                )
              );
            } catch (error) {}
          }

          // Spawn item in front of the block
          const spawnLocation = getFrontLocation(block, facingDirection);
          const itemToDrop = new ItemStack("pb_dino:rubber_ball", 1);
          block.dimension.spawnItem(itemToDrop, spawnLocation);

          return;
        }

        // Check if selected item is in validItems array - and fuel below 4 (max) - add fuel
        if (
          validItems.includes(selectedItem?.typeId) &&
          connected !== "single" &&
          oilQty < 6
        ) {
          player.onScreenDisplay.setActionBar(
            {translate:"action.hint.pb_dino:pyro_add_material"}
          );
          world.playSound("hit.honey_block", block.center());
          const newQty = oilQty + 1;
          block.setPermutation(
            block.permutation.withState("pb_dino:oil_quantity", newQty)
          );

          const facingDirection = block.permutation.getState(
            "minecraft:cardinal_direction"
          );
          const adjacentPosition = connected === "left" ? "right" : "left";
          const adjacentBlock = getAdjacentBlock(
            block,
            facingDirection,
            adjacentPosition
          );
          if (block.typeId == "pb_dino:pyrolyzer_tank") {
            player.dimension.runCommand(
              `particle minecraft:basic_flame_particle ${adjacentBlock.x} ${
                adjacentBlock.y + 1.8
              } ${adjacentBlock.z}`
            );
          }
          if (block.typeId == "pb_dino:pyrolyzer") {
            player.dimension.runCommand(
              `particle minecraft:basic_flame_particle ${block.x} ${
                block.y + 1.8
              } ${block.z}`
            );
          }
          if (adjacentBlock) {
            adjacentBlock.setPermutation(
              adjacentBlock.permutation.withState(
                "pb_dino:oil_quantity",
                newQty
              )
            );
          }
          if (player.getGameMode() !== "creative") {
            if (selectedItem.amount > 1) {
              selectedItem.amount -= 1;
              equipment.setEquipment("Mainhand", selectedItem);
            } else if (selectedItem.amount === 1) {
              equipment.setEquipment("Mainhand", undefined); // Clear the slot if only 1 item left
            }
          }
          return;
        }

        // Check if player has "pb_dino:fuel_can_empty" equipped and oilQty is 6 - swap empty can to full can
        if (
          connected !== "single" &&
          selectedItem?.typeId === "pb_dino:fuel_can_empty" &&
          oilQty === 6
        ) {
          player.onScreenDisplay.setActionBar(
            {translate:"action.hint.pb_dino:pyro_fill_can"}
          );
          world.playSound("mob.cow.milk", block.center());
          // Swap to "pb_dino:fuel_can_full"
          const fullFuelCan = new ItemStack("pb_dino:fuel_can_full", 1);
          equipment.setEquipment("Mainhand", fullFuelCan);

          // Set the block's oilQty to 0
          block.setPermutation(
            block.permutation.withState("pb_dino:oil_quantity", 0)
          );

          // Also update the adjacent block's oilQty to 0
          const facingDirection = block.permutation.getState(
            "minecraft:cardinal_direction"
          );
          const adjacentPosition = connected === "left" ? "right" : "left";
          const adjacentBlock = getAdjacentBlock(
            block,
            facingDirection,
            adjacentPosition
          );
          if (block.typeId == "pb_dino:pyrolyzer") {
            player.dimension.runCommand(
              `particle minecraft:basic_smoke_particle ${adjacentBlock.x} ${
                adjacentBlock.y + 1.8
              } ${adjacentBlock.z}`
            );
          }
          if (block.typeId == "pb_dino:pyrolyzer_tank") {
            player.dimension.runCommand(
              `particle minecraft:basic_smoke_particle ${block.x} ${
                block.y + 1.8
              } ${block.z}`
            );
          }
          if (adjacentBlock) {
            adjacentBlock.setPermutation(
              adjacentBlock.permutation.withState("pb_dino:oil_quantity", 0)
            );
          }
        }

        ////////// UNSUCCESSFUL INTERACTIONS /////////////////////////////////////////////////
        // Empty hand and no oil - no rubber
        if (connected !== "single" && !selectedItem && oilQty === 0) {
          player.onScreenDisplay.setActionBar(
            {translate:"action.hint.pb_dino:pyro_no_rubber"}
          );
          player.dimension.runCommand(
            `particle minecraft:bleach ${block.x} ${block.y + 1.8} ${block.z}`
          );
        }
        // Has wrong item and not full
        if (
          connected !== "single" &&
          selectedItem &&
          !validItems.includes(selectedItem?.typeId) &&
          oilQty < 6
        ) {
          player.onScreenDisplay.setActionBar(
            {translate:"action.hint.pb_dino:pyro_invalid_material"}
          );
          player.dimension.runCommand(
            `particle minecraft:bleach ${block.x} ${block.y + 1.8} ${block.z}`
          );
        }
        // Wrong item and oil less than full - empty hand hint
        if (
          connected !== "single" &&
          selectedItem &&
          !validItems.includes(selectedItem?.typeId) &&
          oilQty > 0 &&
          oilQty < 6
        ) {
          player.runCommandAsync(
            `titleraw @s actionbar {"rawtext":[{"translate":"action.hint.pb_dino:pyro_invalid_material"},{"text":"\n"},{"translate":"action.hint.pb_dino:pyro_empty_hand"}]}`
          );
          player.dimension.runCommand(
            `particle minecraft:bleach ${block.x} ${block.y + 1.8} ${block.z}`
          );
        }
        // Dino Material and oil is full - empty hand or can hint and full hint
        if (
          connected !== "single" &&
          selectedItem?.typeId != "pb_dino:fuel_can_empty" &&
          selectedItem &&
          validItems.includes(selectedItem?.typeId) &&
          oilQty === 6
        ) {
          player.runCommandAsync(
            `titleraw @s actionbar {"rawtext":[{"translate":"action.hint.pb_dino:pyro_full"},{"text":"\n"},{"translate":"action.hint.pb_dino:pyro_full_hint"}]}`
          );
          player.dimension.runCommand(
            `particle minecraft:bleach ${block.x} ${block.y + 1.8} ${block.z}`
          );
        }
        // Wrong item and oil is full - empty hand or can hint
        if (
          connected !== "single" &&
          selectedItem?.typeId != "pb_dino:fuel_can_empty" &&
          selectedItem &&
          !validItems.includes(selectedItem?.typeId) &&
          oilQty === 6
        ) {
          player.runCommandAsync(
            `titleraw @s actionbar {"rawtext":[{"translate":"action.hint.pb_dino:pyro_empty_hand_can"}]}`
          );
          player.dimension.runCommand(
            `particle minecraft:bleach ${block.x} ${block.y + 1.8} ${block.z}`
          );
        }
        // Check if player has "pb_dino:fuel_can_empty" equipped and oilQty is less than 4
        if (
          connected !== "single" &&
          selectedItem?.typeId === "pb_dino:fuel_can_empty" &&
          oilQty < 6
        ) {
          player.runCommandAsync(
            `titleraw @s actionbar {"rawtext":[{"translate":"action.hint.pb_dino:pyro_no_fuel"}]}`
          );
          player.dimension.runCommand(
            `particle minecraft:bleach ${block.x} ${block.y + 1.8} ${block.z}`
          );
        }
        // If the block is not part of a multiblock - warn player
        // Missing tank
        if (connected === "single" && block.typeId == "pb_dino:pyrolyzer") {
          player.runCommandAsync(
            `titleraw @s actionbar {"rawtext":[{"translate":"action.hint.pb_dino:pyro_missing_block"},{"text":"\n"},{"translate":"action.hint.pb_dino:pyro_missing_tank"}]}`
          );
          player.dimension.runCommand(
            `particle minecraft:bleach ${block.x} ${block.y + 1.8} ${block.z}`
          );
        }
        // Missing pyrolyzer
        if (
          connected === "single" &&
          block.typeId == "pb_dino:pyrolyzer_tank"
        ) {
          player.runCommandAsync(
            `titleraw @s actionbar {"rawtext":[{"translate":"action.hint.pb_dino:pyro_missing_block"},{"text":"\n"},{"translate":"action.hint.pb_dino:pyro_missing_pyrolyzer"}]}`
          );
          player.dimension.runCommand(
            `particle minecraft:bleach ${block.x} ${block.y + 1.8} ${block.z}`
          );
        }
      },
    }
  );
});
