import { world, system, BlockPermutation, ItemStack, BlockTypes } from "@minecraft/server";
import { applyDurabilityDamage, sapSet, logMap, fruitSet, leafDropMap, saplingBlocks, isSlab } from "./new_wood_handler";
import { generateStructureName, getBlockStatesAndDirection } from "./fence";
import { checkStair } from "../new_wood/roof";

const roofItems = ["hb_hr:cursed_roof", "hb_hr:grim_stone_bricks_roof", "hb_hr:blight_roof", "hb_hr:black_roof"];

function applyBonemealEffect(block, dimension, player, inventory, selectedItem) {
  try {
    dimension.spawnParticle("minecraft:crop_growth_emitter", block.center());
  } catch (error) {
    // Handle or ignore the error
  }
  dimension.playSound("item.bone_meal.use", block.center());

  // Reduce bone meal item
  if (player.getGameMode() !== "creative") {
    if (selectedItem.amount === 1) {
      inventory.setEquipment("Mainhand", undefined);
    } else {
      selectedItem.amount -= 1;
      inventory.setEquipment("Mainhand", selectedItem);
    }
  }
}

function applyBonemeal(block, dimension, player, equipment, selectedItem, newStage) {
  applyBonemealEffect(block, dimension, player, equipment, selectedItem);

  // Set the new growth stage
  block.setPermutation(block.permutation.withState("hb_hr:growth_stage", newStage));
}

function isAreaClear(dimension, x, y, z, radius, height) {
  let heightAdjust = 3; //adjust this based on how high up your leaves start

  // Check the first two blocks above the sapling
  for (let i = 1; i <= heightAdjust; i++) {
    let blockAbove = dimension.getBlock({ x, y: y + i, z });
    if (blockAbove.type.id !== "minecraft:air" && blockAbove.type.id !== "minecraft:grass" && blockAbove.type.id !== "minecraft:tall_grass" && !blockAbove.type.id.includes("leaves") && !blockAbove.type.id.includes("sapling") && !blockAbove.type.id.includes("snow")) {
      return false;
    }
  }

  // Check the 5x5 area on the third block above
  for (let dx = -radius; dx <= radius; dx++) {
    for (let dz = -radius; dz <= radius; dz++) {
      for (let dy = heightAdjust; dy < height; dy++) {
        let blockAbove = dimension.getBlock({ x: x + dx, y: y + dy, z: z + dz });
        if (blockAbove.type.id !== "minecraft:air" && blockAbove.type.id !== "minecraft:grass" && blockAbove.type.id !== "minecraft:tall_grass" && !blockAbove.type.id.includes("leaves") && !blockAbove.type.id.includes("sapling") && !blockAbove.type.id.includes("snow")) {
          return false;
        }
      }
    }
  }

  return true;
}

function stripLog(player, block, selectedItem, inventory, selectedSlotIndex) {
  const stippedLogType = logMap.get(block.typeId);
  if (!stippedLogType) return;

  const currentPermutation = block.permutation;
  const blockStates = currentPermutation.getAllStates();
  const customBlockFace = blockStates["minecraft:block_face"];
  const strippedLogPermutation = BlockPermutation.resolve(stippedLogType).withState("minecraft:block_face", customBlockFace);

  block.setPermutation(strippedLogPermutation);
  player.playSound("item.axe.strip");
  // Apply durability damage for log stripping
  applyDurabilityDamage(player, selectedItem, inventory, selectedSlotIndex);
}

function harvestTree(block) {
  const fruit = leafDropMap.get(block.typeId);
  system.runTimeout(() => {
    block.dimension.spawnItem(new ItemStack(fruit, 3), block.location);
    block.setPermutation(block.permutation.withState("hb_hr:growth_stage", 0));
  }, 1);
}

export function CustomWoodMechanic() {
  world.beforeEvents.playerInteractWithBlock.subscribe((eventData) => {
    system.run(() => {
      const { block, player, itemStack } = eventData;
      const inventory = player.getComponent("inventory");
      const equipment = player.getComponent("equippable");
      const selectedItem = equipment.getEquipment("Mainhand");
      if (itemStack == undefined) return;
      if (selectedItem == undefined) return;
      // world.sendMessage(selectedItem.typeId);
      if (selectedItem.typeId === "minecraft:bone_meal") {
        if (!block || !sapSet.has(block.typeId)) return;
        // Get the current growth stage
        const currentStage = getGrowthStage(block);
        // 45% chance to advance the stage
        if (Math.random() < 0.45) {
          // Increment the stage, but don't exceed maxStage (2 in this case)
          const newStage = Math.min(currentStage + 1, 2);
          // Apply bonemeal effect
          applyBonemeal(block, player.dimension, player, equipment, selectedItem, newStage);
          // Check if the sapling should grow into a tree
          if (newStage === 2) {
            growTree(block, player.dimension);
          }
        } else {
          // Bonemeal was used but didn't advance the stage
          applyBonemealEffect(block, player.dimension, player, equipment, selectedItem);
        }
        return;
      }
      const data = saplingBlocks.find((f) => f.blockID === block.typeId);
      if (fruitSet.has(block.typeId) && getGrowthStage(block) === data.maxStage) {
        harvestTree(block);
        return;
      }
      if (!logMap.has(block.typeId)) return;
      if (logMap.has(block.typeId) && (selectedItem.hasTag("minecraft:is_axe") || selectedItem.typeId.includes("axe")) && !selectedItem.typeId.includes("pickaxe")) {
        eventData.cancel = true;

        system.runTimeout(() => {
          try {
            stripLog(player, block, selectedItem, inventory, player.selectedSlotIndex);
          } catch (error) {
            // console.warn(`Error in stripLog: ${error.message}`);
          }
        }, 1);
      }
    });
  });
}

// export const treeInteractComponent = {
//   onPlayerInteract(eventData) {
//     const { player, block, dimension, face } = eventData;
//     const inventory = player.getComponent("inventory");
//     const equipment = player.getComponent("equippable");
//     const selectedItem = equipment.getEquipment("Mainhand");
//     if (!selectedItem) return;
//     if (logMap.has(block.typeId) && (selectedItem.hasTag("minecraft:is_axe") || selectedItem.typeId.includes("axe")) && !selectedItem.typeId.includes("pickaxe")) {
//       world.sendMessage("cancel");
//       eventData.cancel = true;
//       system.runTimeout(() => {
//         try {
//           stripLog(player, block, selectedItem, inventory, player.selectedSlotIndex);
//         } catch (error) {
//           // console.warn(`Error in stripLog: ${error.message}`);
//         }
//       }, 1);
//     }
//     const data = saplingBlocks.find((f) => f.blockID === block.typeId);
//     if (fruitSet.has(block.typeId) && getGrowthStage(block) === data.maxStage) {
//       harvestTree(block);
//       return;
//     }
//     if (selectedItem.typeId === "minecraft:bone_meal") {
//       if (!block || !sapSet.has(block.typeId)) return;
//       // Get the current growth stage
//       const currentStage = getGrowthStage(block);
//       // 45% chance to advance the stage
//       if (Math.random() < 0.45) {
//         // Increment the stage, but don't exceed maxStage (2 in this case)
//         const newStage = Math.min(currentStage + 1, 2);
//         // Apply bonemeal effect
//         applyBonemeal(block, dimension, player, equipment, selectedItem, newStage);
//         // Check if the sapling should grow into a tree
//         if (newStage === 2) {
//           growTree(block, dimension);
//         }
//       } else {
//         // Bonemeal was used but didn't advance the stage
//         applyBonemealEffect(block, dimension, player, equipment, selectedItem);
//       }
//       return;
//     } else {
//       //   // If it's not a block, it will be undefined.
//       //   if (BlockTypes.get(selectedItem.typeId) == undefined) return;
//       //   // Get block states and player direction
//       //   const { stateName, stateValue } = getBlockStatesAndDirection(player, selectedItem, face);
//       //   // Determine the adjacent block position based on the face
//       //   let adjacentBlockPos;
//       //   switch (face) {
//       //     case "North":
//       //       adjacentBlockPos = { x: block.x, y: block.y, z: block.z - 1 };
//       //       break;
//       //     case "South":
//       //       adjacentBlockPos = { x: block.x, y: block.y, z: block.z + 1 };
//       //       break;
//       //     case "East":
//       //       adjacentBlockPos = { x: block.x + 1, y: block.y, z: block.z };
//       //       break;
//       //     case "West":
//       //       adjacentBlockPos = { x: block.x - 1, y: block.y, z: block.z };
//       //       break;
//       //     case "Up":
//       //       adjacentBlockPos = { x: block.x, y: block.y + 1, z: block.z };
//       //       break;
//       //     case "Down":
//       //       adjacentBlockPos = { x: block.x, y: block.y - 1, z: block.z };
//       //       break;
//       //   }
//       //   const adjacentBlock = eventData.dimension.getBlock(adjacentBlockPos);
//       //   // if (roofItems.includes(selectedItem.typeId)) {
//       //   //   world.sendMessage(block.typeId);
//       //   //   world.sendMessage("statename: "+stateName);
//       //   //   const northBlock = adjacentBlock.north();
//       //   //   const southBlock = adjacentBlock.south();
//       //   //   const eastBlock = adjacentBlock.east();
//       //   //   const westBlock = adjacentBlock.west();
//       //   //   const vertical_half = block.permutation.getState("minecraft:vertical_half");
//       //   //   const shape = block.permutation.getState("hb_hr:shape") ?? "straight";
//       //   //   const cardinal_direction = "north";
//       //   //   checkStair(block, northBlock, southBlock, eastBlock, westBlock, vertical_half, shape, cardinal_direction);
//       //   //   const commandBlock = "/setblock " + adjacentBlockPos.x + " " + adjacentBlockPos.y + " " + adjacentBlockPos.z + " hb_hr:blight_roof [\"hb_hr:placed_bit\"=false,\"hb_hr:shape\"=\"inner_left\",\"minecraft:cardinal_direction\"="+cardinal_direction+",\"minecraft:vertical_half\"=\"bottom\"]";
//       //   //   // const commandBlock = `setblock ${adjacentBlockPos.x} ${adjacentBlockPos.y} ${adjacentBlockPos.z} ${selectedItem.typeId} ["${stateName}"="${stateValue}"]`;
//       //   //   player.runCommand(commandBlock);
//       //   //   return;
//       //   // }
//       //   if (face) {
//       //     if (adjacentBlock.typeId === "minecraft:air" || adjacentBlock.typeId.includes("_inventory")) {
//       //       // Handle block placement with state against a log
//       //       const commandBlock = stateName ? `setblock ${adjacentBlockPos.x} ${adjacentBlockPos.y} ${adjacentBlockPos.z} ${selectedItem.typeId} ["${stateName}"="${stateValue}"]` : `setblock ${adjacentBlockPos.x} ${adjacentBlockPos.y} ${adjacentBlockPos.z} ${selectedItem.typeId}`;
//       //       world.sendMessage(commandBlock);
//       //       system.runTimeout(() => {
//       //         try {
//       //           player.runCommand(commandBlock);
//       //           if (player.getGameMode() !== "creative") {
//       //             if (selectedItem.amount === 1) {
//       //               equipment.setEquipment("Mainhand", undefined);
//       //             } else {
//       //               selectedItem.amount -= 1;
//       //               equipment.setEquipment("Mainhand", selectedItem);
//       //             }
//       //           }
//       //         } catch (error) {
//       //           // console.warn(`Error: ${error.message}`);
//       //         }
//       //       }, 1);
//       //     }
//       //   }
//     }
//   },
// };

export const leafDefaultComponent = {
  beforeOnPlayerPlace(e) {
    const { permutationToPlace } = e;
    const baseStates = {
      "hb_hr:should_decay": false,
    };

    const newPerm = BlockPermutation.resolve(permutationToPlace.type.id, baseStates);

    e.permutationToPlace = newPerm;
    // const { permutationToPlace, block } = e;
    // permutationToPlace = permutationToPlace.withState("hb_hr:should_decay", false);
  },
};

export function growTree(block, dimension) {
  const { x, y, z } = block;
  const randomNumber = Math.floor(Math.random() * 8) + 1;
  const baseTreeType = generateStructureName(block.typeId);
  const treeType = `${baseTreeType}_${randomNumber}`;
  let treeStructurePath = "hb_hr/" + treeType;
  // world.sendMessage(treeType.toString());

  // Define the area to check based on your tree size
  let checkRadius; // Adjust based on your tree's maximum width
  let checkHeight; // Adjust based on your tree's maximum height
  if (treeStructurePath.includes("blight")) {
    // Define the area to check based on your tree size
    checkRadius = 3; // Adjust based on your tree's maximum width
    checkHeight = 33; // Adjust based on your tree's maximum height
  }
  if (treeStructurePath.includes("cursed")) {
    treeStructurePath = "hb_hr/b2_sap_tree_" + randomNumber.toString();
    // world.sendMessage(treeStructurePath.toString());
    // Define the area to check based on your tree size
    checkRadius = 5; // Adjust based on your tree's maximum width
    checkHeight = 13; // Adjust based on your tree's maximum height
  }
  if (treeStructurePath.includes("black")) {
    treeStructurePath = "hb_hr/b3_tree_" + randomNumber.toString();
    // Define the area to check based on your tree size
    checkRadius = 6; // Adjust based on your tree's maximum width
    checkHeight = 15; // Adjust based on your tree's maximum height
  }

  // Check if the area is clear (air, grass, saplings or leaves can be replaced) - will not replace the air blocks in structure if set up correct fyi
  if (isAreaClear(dimension, x, y, z, checkRadius, checkHeight)) {
    // world.sendMessage(treeStructurePath.toString());
    world.structureManager.place(treeStructurePath, dimension, { x: x - checkRadius, y, z: z - checkRadius });

    if (treeStructurePath.includes("b3")) {
      block.setType("hb_hr:black_log");
    } else {
      block.setType("minecraft:air");
    }
  } else {
    // console.warn("Unable to grow tree: area is not clear");
    return;
  }
}

export function getGrowthStage(block) {
  // Assuming the growth state ID is "hb_hr:growth_stage"
  return block.permutation.getState("hb_hr:growth_stage") || 0;
}
