import { world, system,  ItemStack, BlockVolume, EntityInventoryComponent, EntityType } from "@minecraft/server";
import * as Utils from "./utils.js";
import { getPlayerExperienceLevel } from "get_level_tests";
import { ActionFormData } from "@minecraft/server-ui";
system.beforeEvents.watchdogTerminate.subscribe(
    (data) => {
        data.cancel = true;
        console.warn(data.terminateReason);
    },
);

/**
 * @type {{ run: number; locations: import("@minecraft/server").Vector3[] }[]}
 */
let locations = [];

/**
 * 
 * @param { import("@minecraft/server").Player } player
 * @param { import("@minecraft/server").Block } block
 * @param { import("@minecraft/server").Dimension } dimension
 * @param { import("@minecraft/server").BlockType } blockType
 * @param { import("@minecraft/server").Vector3 } start
 * @param { number } run
 */
const breakBlocks = ( player, block, dimension, blockType, start, run ) => {
    let locs = locations.find(({ run: r }) => r == run);
    if (locs == undefined) {
        locations.push({ run, locations: [] });
        locs = locations.find(({ run: r }) => r == run);
    };

    const { x, y, z } = block.location;
    const alreadyVisited = locs.locations.find((l) => ( l.x == x && l.y == y && l.z == z )) != undefined;
    const drops = Utils.allowedBlocks.find((b) => b.id == blockType.id)?.drops;
    const dropXp = Utils.allowedBlocks.find((b) => b.id == blockType.id )?.dropXP;
    //const tag = Utils.allowedTags.find((t) => t.id == blockType.id)?.tag;
    if (
        alreadyVisited
        || (
            locs.locations.length != 0
            && ( drops == undefined || block.type.id != blockType.id )
        )
        || locs.locations.length == Utils.maxBlocks
    ) return;
    
    block.setType('air');
    if (locs.locations.length != 0) {
        /*** @type { import("@minecraft/server").Container } */
        const inventory = player.getComponent( "minecraft:inventory" ).container;
        const item = inventory.getItem( player.selectedSlot );
        /*** @type { import("@minecraft/server").EnchantmentList } */
        const enchantments = item.getComponent("minecraft:enchantable").getEnchantments().map((e) => e.id);
      
        if (item.getComponent("enchantable").hasEnchantment('silk_touch')) {
            dimension.spawnItem(new ItemStack(blockType.id), start);
        } else {
            const level = item.getComponent("minecraft:enchantable").getEnchantment( "fortune" )?.level ?? 0;
            const drop = drops.drops[level];
            const amount = Math.random() * (drop.max - drop.min) + drop.min;
            dimension.spawnItem(new ItemStack(drops.id, amount), start);
            //console.warn(dropXp)
            if(dropXp ==true){
              dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              console.warn("test")
              if(drops.id == 'minecraft:lapis_lazuli' || drops.id == 'minecraft:deepslate_lapis_lazuli' || drops.id == 'minecraft:quartz_ore') {
                dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              dimension.spawnEntity('minecraft:xp_orb', start)
              }
          }
        };
    };

    locs.locations.push({ x, y, z });
    const blocks = new BlockVolume({ x: x+1, y: y+1, z: z+1 }, { x: x-1, y: y-1, z: z-1 }).getBlockLocationIterator();
    
    for (const b of blocks) {
        const block = dimension.getBlock(b);
        breakBlocks( player, block, dimension, blockType, start, run );
    };
    const inventory = player.getComponent( "minecraft:inventory" ).container;
    const item = inventory.getItem( player.selectedSlot );
    //console.warn( item.getComponent('durability').damage)

    item.getComponent('durability').damage = item.getComponent('durability').damage += 1
    inventory.setItem(player.selectedSlot, item);
};

world.afterEvents.playerBreakBlock.subscribe(
    ({ player, block, dimension, brokenBlockPermutation, experience }) => {
        const inventory = player.getComponent( "minecraft:inventory" ).container;
        const item = inventory.getItem( player.selectedSlot );
        if (!item) return;
        if (item.getLore().includes("§r§7Vein Miner I")){
        if (!item.hasTag('minecraft:is_pickaxe'))return;
       
        breakBlocks( player, block, dimension, brokenBlockPermutation.type, block.location, Date.now() );
        }
    },
);



world.afterEvents.itemUseOn.subscribe(
  (use) => {
    let player = use.source,
    item = use.itemStack; // this do not work. can't get item no more
  let blockTest = player.getBlockFromViewDirection();
    let block = player.getBlockFromViewDirection()?.block;
    if (
      (item?.hasTag('minecraft:is_pickaxe'))
      && block?.typeId == "better_on_bedrock:enchant_bench"
    ) veinMine(player); 
});

function veinMine(player) {
  let level = player.runCommandAsync("xp 0 @s")
  let form = new ActionFormData();
  form.title("Enchant Pickaxe?");
  form.body(
    "§cTo enchant this pickaxe with Vein Miner I, you need the following requirements:\n\n§e- 1x Pickaxe\n- 1x Vein Miner Book\n- 6x XP levels"
  );
  ///buttons
  form.button("Enchant");
  form.button("Don't Enchant");
  form.show(player).then((response) => {
    if (response.selection == 0 && getPlayerExperienceLevel(player) >= 6) {
      const inventory = player.getComponent(
        EntityInventoryComponent.componentId
      );
      for (let slot = 0; slot < inventory.container.size; slot++) {
        const itemStack = inventory.container.getItem(slot);
        if (itemStack?.typeId === "better_on_bedrock:vein_miner_book") {
          let inv = player.getComponent("inventory").container;
          let item = inv.getItem(player.selectedSlot);
          if (item.hasTag('minecraft:is_pickaxe')) {
     
            item.setLore(['§r§7Vein Miner I'])
            player.runCommandAsync("clear @p better_on_bedrock:vein_miner_book 0 1");
            player.runCommandAsync("xp -6l @p");
            inv.setItem(player.selectedSlot, item);

            player.runCommandAsync("enchant @p efficiency 1");
          }
         
        }
      }
    } else if (response.selection == 0 && getPlayerExperienceLevel(player) < 6) {
      player.sendMessage("§cYou don't have enough levels.")
    }
    if (response.selection == 1) {
    }
  });
}
