import { world, system, ItemStack } from "@minecraft/server";
import { growTree, getGrowthStage } from "./tree";
import { saplingBlocks, logSet, leafSet, leafDropMap, sapSet, fruitSet } from "./new_wood_handler";

// Define an array of block types to exclude from connections
export const excludeBlocksArray = [
  "minecraft:light_block_0",
  "minecraft:light_block_1",
  "minecraft:light_block_2",
  "minecraft:light_block_3",
  "minecraft:light_block_4",
  "minecraft:light_block_5",
  "minecraft:light_block_6",
  "minecraft:light_block_7",
  "minecraft:light_block_8",
  "minecraft:light_block_9",
  "minecraft:light_block_10",
  "minecraft:light_block_11",
  "minecraft:light_block_12",
  "minecraft:light_block_13",
  "minecraft:light_block_14",
  "minecraft:light_block_15",

  "minecraft:copper_chain",
  "minecraft:exposed_copper_chain",
  "minecraft:iron_chain",
  "minecraft:oxidized_copper_chain",
  "minecraft:waxed_copper_chain",
  "minecraft:waxed_exposed_copper_chain",
  "minecraft:waxed_oxidized_copper_chain",
  "minecraft:waxed_weathered_copper_chain",
  "minecraft:weathered_copper_chain",

  "minecraft:wall_banner",
  "minecraft:standing_banner",
  "minecraft:lantern",
  "minecraft:soul_lantern",
  "minecraft:pointed_dripstone",
  "minecraft:campfire",
  "minecraft:soul_campfire",
  "minecraft:torchflower",
  "minecraft:pitcher_crop",
  "minecraft:wheat",
  "minecraft:carrots",
  "minecraft:potatoes",
  "minecraft:beetroot",
  "minecraft:nether_wart",
  "minecraft:sweet_berry_bush",
  "minecraft:cocoa",
  "minecraft:pumpkin_stem",
  "minecraft:melon_stem",
  "minecraft:bamboo",
  "minecraft:bamboo_sapling",
  "minecraft:cactus",
  "minecraft:reeds",
  "minecraft:command_block",
  "minecraft:repeat_command_block",
  "minecraft:chain_command_block",
  "minecraft:oak_leaves",
  "minecraft:acacia_leaves",
  "minecraft:azalea_leaves",
  "minecraft:azalea_leaves_flowered",
  "minecraft:birch_leaves",
  "minecraft:cherry_leaves",
  "minecraft:dark_oak_leaves",
  "minecraft:jungle_leaves",
  "minecraft:mangrove_leaves",
  "minecraft:dark_oak_leaves",
  "minecraft:pale_oak_leaves",
  "minecraft:spruce_leaves",
  "minecraft:structure_void",
  "minecraft:barrier",
  "minecraft:air",
  "minecraft:wooden_door",
  "minecraft:iron_door",
  "minecraft:acacia_door",
  "minecraft:birch_door",
  "minecraft:crimson_door",
  "minecraft:dark_oak_door",
  "minecraft:jungle_door",
  "minecraft:oak_door",
  "minecraft:spruce_door",
  "minecraft:warped_door",
  "minecraft:mangrove_door",
  "minecraft:cherry_door",
  "minecraft:bamboo_door",
  "minecraft:iron_trapdoor",
  "minecraft:acacia_trapdoor",
  "minecraft:birch_trapdoor",
  "minecraft:crimson_trapdoor",
  "minecraft:dark_oak_trapdoor",
  "minecraft:jungle_trapdoor",
  "minecraft:oak_trapdoor",
  "minecraft:spruce_trapdoor",
  "minecraft:warped_trapdoor",
  "minecraft:mangrove_trapdoor",
  "minecraft:cherry_trapdoor",
  "minecraft:bamboo_trapdoor",
  "minecraft:trapdoor",
  "minecraft:glass_pane",
  "minecraft:stained_glass",
  "minecraft:stained_glass_pane",
  // "minecraft:blue_ice",
  // "minecraft:ice",
  // "minecraft:packed_ice",
  "minecraft:dry_grass",
  "minecraft:tall_dry_grass",
  "minecraft:conduit",
  "minecraft:water",
  "minecraft:lava",
  "minecraft:flowing_lava",
  "minecraft:flowing_water",
  "minecraft:stationary_water",
  "minecraft:stationary_lava",
  "minecraft:oak_slab",
  "minecraft:stone_slab",
  "minecraft:spruce_slab",
  "minecraft:stone_slab2",
  "minecraft:brick_slab",
  "minecraft:stone_brick_slab",
  "minecraft:nether_brick_slab",
  "minecraft:sandstone_slab",
  "minecraft:smooth_sandstone_slab",
  "minecraft:quartz_slab",
  "minecraft:acacia_slab",
  "minecraft:birch_slab",
  "minecraft:jungle_slab",
  "minecraft:dark_oak_slab",
  "minecraft:warped_slab",
  "minecraft:crimson_slab",
  "minecraft:mangrove_slab",
  "minecraft:cherry_slab",
  "minecraft:bamboo_slab",
  "minecraft:stone_stairs",
  "minecraft:oak_stairs",
  "minecraft:spruce_stairs",
  "minecraft:stone_brick_stairs",
  "minecraft:brick_stairs",
  "minecraft:nether_brick_stairs",
  "minecraft:quartz_stairs",
  "minecraft:acacia_stairs",
  "minecraft:birch_stairs",
  "minecraft:jungle_stairs",
  "minecraft:dark_oak_stairs",
  "minecraft:warped_stairs",
  "minecraft:crimson_stairs",
  "minecraft:mangrove_stairs",
  "minecraft:cherry_stairs",
  "minecraft:bamboo_stairs",
  "minecraft:fire",
  "minecraft:carpet",
  "minecraft:ladder",
  "minecraft:vine",
  "minecraft:waterlily",
  "minecraft:ladder",
  "minecraft:chest",
  "minecraft:trapdoor",
  "minecraft:leaves",
  "minecraft:snow_layer",
  "minecraft:bed",
  "minecraft:cactus",
  "minecraft:flower_pot",
  "minecraft:banner",
  "minecraft:painting",
  "minecraft:armor_stand",
  "minecraft:flower_pot",
  "minecraft:torch",
  "minecraft:lantern",
  "minecraft:chest",
  "minecraft:trapped_chest",
  "minecraft:hopper",
  "minecraft:composter",
  "minecraft:shulker_box",
  "minecraft:enchanting_table",
  "minecraft:anvil",
  "minecraft:beacon",
  "minecraft:stonecutter",
  "minecraft:sapling", // Planta
  "minecraft:melon_stem", // Planta
  "minecraft:pumpkin_stem", // Planta
  "minecraft:wheat", // Planta
  "minecraft:beetroots", // Planta
  "minecraft:carrots", // Planta
  "minecraft:potatoes", // Planta
  "minecraft:sweet_berries", // Planta
  "minecraft:nether_wart", // Planta
  "minecraft:waterlily", // Planta
  "minecraft:fern", // Planta
  "minecraft:tall_grass", // Grama alta
  "minecraft:short_grass", // Grama baixa
  "minecraft:dandelion", // Flor
  "minecraft:poppy", // Flor
  "minecraft:blue_orchid", // Flor
  "minecraft:allium", // Flor
  "minecraft:azure_bluet", // Flor
  "minecraft:red_tulip", // Flor
  "minecraft:orange_tulip", // Flor
  "minecraft:white_tulip", // Flor
  "minecraft:pink_tulip", // Flor
  "minecraft:oxeye_daisy", // Flor
  "minecraft:sunflower", // Flor
  "minecraft:lilac", // Flor
  "minecraft:rose_bush", // Flor
  "minecraft:peony", // Flor
  "minecraft:cornflower", // Flor
  "minecraft:lily_of_the_valley", // Flor
  "minecraft:wither_rose", // Flor
  "minecraft:large_fern", // Fern grande
  "minecraft:large_tulip", // Tulipa grande
  "minecraft:large_sunflower", // Girassol grande
  "minecraft:large_lilac", // Lilás grande
  "minecraft:large_rose_bush", // Rosa grande
  "minecraft:large_peony", // Peônia grande
  "minecraft:eyeblossom", // Eyeblossom
  "minecraft:banner",
  "minecraft:painting",
  "minecraft:item_frame",
  "minecraft:glow_item_frame",
  "minecraft:end_portal_frame",
  "minecraft:end_gateway",
  "minecraft:moss_carpet", // Tapete de musgo
  "minecraft:stone_wall", // Muro de pedra
  "minecraft:undyed_shulker_box", // Shulker Box sem cor
  "minecraft:white_shulker_box", // Shulker Box Branco
  "minecraft:orange_shulker_box", // Shulker Box Laranja
  "minecraft:magenta_shulker_box", // Shulker Box Magenta
  "minecraft:light_blue_shulker_box", // Shulker Box Azul Claro
  "minecraft:yellow_shulker_box", // Shulker Box Amarelo
  "minecraft:lime_shulker_box", // Shulker Box Lima
  "minecraft:pink_shulker_box", // Shulker Box Rosa
  "minecraft:gray_shulker_box", // Shulker Box Cinza
  "minecraft:silver_shulker_box", // Shulker Box Prata
  "minecraft:blue_shulker_box", // Shulker Box Azul
  "minecraft:purple_shulker_box", // Shulker Box Roxo
  "minecraft:cyan_shulker_box", // Shulker Box Ciano
  "minecraft:green_shulker_box", // Shulker Box Verde
  "minecraft:red_shulker_box", // Shulker Box Vermelho
  "minecraft:black_shulker_box", // Shulker Box Preto
  "minecraft:stone_pressure_plate", // Placa de pedra
  "minecraft:wooden_pressure_plate", // Placa de madeira
  "minecraft:light_weighted_pressure_plate", // Placa de pressão leve
  "minecraft:heavy_weighted_pressure_plate", // Placa de pressão pesada
  "minecraft:pale_oak_stairs", // Escada de Pale Oak
  "minecraft:pale_oak_slab", // Laje de Pale Oak
  "minecraft:pale_oak_trapdoor", // Trapdoor de Pale Oak
  "minecraft:cobblestone_wall",
  "minecraft:nether_brick_fence",
  "hb_hr:white_oak_fence_inventory",
  "hb_hr:blight_fence_inventory",
  "hb_hr:black_fence_inventory",
  "mc:leshy_door",
  "mc:grassy_leshy_door",
  "mc:leshy_trapdoor",
  "mc:grassy_leshy_trapdoor",
  "hb_hr:cursed_vine",
  "hb_hr:blight_sapling",
  "hb_hr:dead_bush",
  "hb_hr:cursed_bush",
  "hb_hr:dead_grass",
  "hb_hr:cursed_tall_grass",
  "hb_hr:cursed_grass",
  "hb_hr:black_leaves",
  "hb_hr:black_sapling",
  "hb_hr:cursed_sapling",
  "hb_hr:dead_root_carpet",
  "hb_hr:hive_carpet",
  "hb_hr:large_hive_egg",
  "hb_hr:small_hive_egg",
  "hb_hr:hive_vine",
  "hb_hr:cursed_roof",
  "hb_hr:grim_stone_bricks_roof",
  "hb_hr:blight_roof",
  "hb_hr:dead_roof",
  "hb_hr:black_grass",
  "hb_hr:black_tall_grass",
  "hb_hr:black_rose",
  "hb_hr:black_moss_carpet",
  "hb_hr:black_vine_carpet",
  "hb_hr:black_hanging_moss",
  "hb_hr:black_vine",

  // "hb_hr:ash_block",
  // "hb_hr:banned_wither_skull_b1_block",
  // "hb_hr:banned_wither_skull_b2_block",
  // "hb_hr:banned_wither_skull_b3_block",
  // "hb_hr:blight_door",
  // "hb_hr:blight_log",
  // "hb_hr:blight_planks",
  // "hb_hr:blight_slab",
  // "hb_hr:blight_trapdoor",
  // "hb_hr:blight_wood",
  // "hb_hr:stripped_blight_log",
  // "hb_hr:stripped_blight_wood",
  // "hb_hr:cursed_core",
  // "hb_hr:cursed_door",
  // "hb_hr:cursed_grass_block",
  // "hb_hr:cursed_leaves",
  // "hb_hr:cursed_log",
  // "hb_hr:cursed_planks",
  // "hb_hr:cursed_ripped_log",
  // "hb_hr:cursed_slab",
  // "hb_hr:cursed_trapdoor",
  // "hb_hr:cursed_wood",
  // "hb_hr:stripped_cursed_log",
  // "hb_hr:chiseled_grim_stone_bricks",
  // "hb_hr:cracked_grim_stone_bricks",
  // "hb_hr:stripped_cursed_wood",
  // "hb_hr:dead_roots",
  // "hb_hr:dirty_dead_roots",
  // "hb_hr:dried_cursed_grass_block",
  // "hb_hr:dried_dirt",
  // "hb_hr:gravestone",
  // "hb_hr:grim_stone",
  // "hb_hr:grim_stone_bricks",
  // "hb_hr:grim_stone_bricks_slab",
  // "hb_hr:grim_stone_bricks_wall",
  // "hb_hr:grim_stone_chunks",
  // "hb_hr:hive",
  // "hb_hr:hive_carpet_block",
  // "hb_hr:infested_grim_stone_bricks",
  // "hb_hr:polished_grim_stone",
  // "hb_hr:rotten_soil",
  // "hb_hr:soul_ore",
];

// Initialize a Map to store the state of each block for tracking changes
const blockStates = new Map();
export const OnTickComponent = {
  onTick(e) {
    if (e.block.typeId.includes("hb_hr:") && e.block.typeId.includes("fence") && e.block.typeId.includes("_inventory")) {
      /*  remove the fake fence collision block if the block below is:
          - any other marketplace-product fence block
          - any vanilla fence block
          - is another fake fence collision block
          - doesnt have fence at all in the block identifier
      */
      if ((!e.block.below().typeId.includes("hb_hr:") && !e.block.below().typeId.includes("minecraft:") && e.block.below().typeId.includes("fence")) || (e.block.below().typeId.includes("minecraft:") && e.block.below().typeId.includes("fence")) || (!e.block.below().typeId.includes("hb_hr:") && !e.block.below().typeId.includes("fence")) || !e.block.below().typeId.includes("fence") || (e.block.below().typeId.includes("hb_hr") && e.block.below().typeId.includes("fence") && e.block.below().typeId.includes("inventory"))) {
        e.block.setType("minecraft:air");
      }
      return;
    }
    // Destructure event data for easier access
    const { block } = e;
    // Get adjacent blocks
    const north = block.north();
    const east = block.east();
    const south = block.south();
    const west = block.west();

    // Check if the adjacent block is not in the excludeBlocksArray
    const northConnects = north ? !excludeBlocksArray.includes(north?.typeId) : false;
    const eastConnects = east ? !excludeBlocksArray.includes(east?.typeId) : false;
    const southConnects = south ? !excludeBlocksArray.includes(south?.typeId) : false;
    const westConnects = west ? !excludeBlocksArray.includes(west?.typeId) : false;

    // Update block states based on the presence of adjacent blocks
    block.setPermutation(block.permutation.withState("hb_hr:north_picket", northConnects ? 1 : 0));
    block.setPermutation(block.permutation.withState("hb_hr:south_picket", southConnects ? 1 : 0));
    block.setPermutation(block.permutation.withState("hb_hr:east_picket", eastConnects ? 1 : 0));
    block.setPermutation(block.permutation.withState("hb_hr:west_picket", westConnects ? 1 : 0));
  },
};

export const randomTickComponent = {
  onRandomTick(e) {
    const { block, dimension } = e;

    if (sapSet.has(block.typeId)) {
      handleSaplingGrowth(block, dimension);
    } else if (fruitSet.has(block.typeId)) {
      if (isAir(block, dimension)) {
        handleFruitGrowth(block);
        handleLeafDecay(block, dimension);
      }
    } else if (leafSet.has(block.typeId)) {
      handleLeafDecay(block, dimension);
    }
  },
};

export function leafDrop(block, broken) {
  const leafType = block.type.id;
  const dropLocation = block.location;
  const saplingType = leafDropMap.get(leafType);
  const randomValue = Math.random();

  if (fruitSet.has(leafType) && getGrowthStage(block) === 2) {
    system.runTimeout(() => {
      block.dimension.spawnItem(new ItemStack(saplingType, 3), dropLocation);
    }, 1);
  }

  if (randomValue < 0.05) {
    // 5% chance to drop a sapling
    if (saplingType) {
      system.runTimeout(() => {
        block.dimension.spawnItem(new ItemStack(saplingType, 1), dropLocation);
      }, 1);
    }
  } else if (randomValue > 0.95) {
    // 5% chance to drop sticks
    system.runTimeout(() => {
      block.dimension.spawnItem(new ItemStack("minecraft:stick", 1), dropLocation);
    }, 1);
  }
  // 90% chance to drop nothing

  if (!broken) {
    // Remove the leaf block if it decayed natually, skip if player broken.
    block.setType("minecraft:air");
  }
}

export function treeTicks() {}

function handleFruitGrowth(block) {
  const data = saplingBlocks.find((f) => f.blockID === block.typeId);
  if (!data) return;

  const stage = getGrowthStage(block);
  if (stage >= data.maxStage) return;

  const num = randomNum(0, data.growChance.denominator);
  if (num > data.growChance.numerator) return;

  const newStage = stage + 1;
  block.setPermutation(block.permutation.withState("hb_hr:growth_stage", newStage));
}

// this function looks if there is an air block to the sides before advancing growth of the fruit
function isAir(block, dim) {
  const directions = ["North", "South", "East", "West"];
  for (const direction of directions) {
    let adjacentBlockPos;
    switch (direction) {
      case "North":
        adjacentBlockPos = {
          x: block.location.x,
          y: block.location.y,
          z: block.location.z - 1,
        };
        break;
      case "South":
        adjacentBlockPos = {
          x: block.location.x,
          y: block.location.y,
          z: block.location.z + 1,
        };
        break;
      case "East":
        adjacentBlockPos = {
          x: block.location.x + 1,
          y: block.location.y,
          z: block.location.z,
        };
        break;
      case "West":
        adjacentBlockPos = {
          x: block.location.x - 1,
          y: block.location.y,
          z: block.location.z,
        };
        break;
    }

    try {
      const adjacentBlock = dim.getBlock(adjacentBlockPos);
      if (adjacentBlock.typeId === "minecraft:air") {
        return true;
      } else {
        return false;
      }
    } catch (error) {
      // console.warn(`Error: ${error}`);
    }
  }
}

function randomNum(min, max) {
  //return a random number
  return Math.random() * (max - min) + min;
}
function handleLeafDecay(block, dimension) {
  const shouldDecay = block.permutation.getState("hb_hr:should_decay");
  if (!shouldDecay) return;

  const currentTier = block.permutation.getState("hb_hr:decay_tier") || 0;

  const newDecayTier = getNewDecayTier(block, dimension, currentTier);

  if (newDecayTier === 0) {
    leafDrop(block);
  } else if (newDecayTier !== currentTier) {
    block.setPermutation(block.permutation.withState("hb_hr:decay_tier", newDecayTier));
  }
}

function handleSaplingGrowth(block, dimension) {
  const data = saplingBlocks.find((f) => f.blockID === block.typeId);
  if (!data) return;

  const stage = getGrowthStage(block);
  if (stage >= data.maxStage) return;

  const num = randomNum(0, data.growChance.denominator);
  if (num > data.growChance.numerator) return;

  const newStage = stage + 1;
  block.setPermutation(block.permutation.withState("hb_hr:growth_stage", newStage));

  if (newStage === data.maxStage) {
    growTree(block, dimension);
  }
}

function getNewDecayTier(block, dimension, currentTier) {
  // Check for nearby logs first
  if (hasNearbyLog(block, dimension, 2)) {
    return currentTier;
  }

  let num = Math.random();
  // Control decay speed with this, only if no logs are nearby
  if (num > 0.4) {
    // 40% chance to decay 1 stage
    return Math.max(0, currentTier - 1);
  } else if (num < 0.6) {
    // 60% chance to decay fully
    leafDrop(block);
  }

  return currentTier;
}

function hasNearbyLog(block, dimension, radius) {
  for (let dx = -radius; dx <= radius; dx++) {
    for (let dy = -radius; dy <= radius; dy++) {
      for (let dz = -radius; dz <= radius; dz++) {
        const checkLocation = {
          x: block.location.x + dx,
          y: block.location.y + dy,
          z: block.location.z + dz,
        };
        const checkBlock = dimension.getBlock(checkLocation);
        if (checkBlock && logSet.has(checkBlock.type.id)) {
          return true;
        }
      }
    }
  }
  return false;
}
