import {
  ActionFormData,
  MessageFormData,
  ModalFormData,
} from "@minecraft/server-ui";
import { getPlayerExperienceLevel } from 'get_level_tests'
import { world, system, Player, ItemStack, BlockVolumeUtils, ItemTypes } from "@minecraft/server";
import * as Utils from "./treeUitls.js";
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.allowedBlocksWood.find((b) => b.id == blockType.id)?.drops;
    //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.type);
        if (enchantments.includes( "silk_touch" )) {
            dimension.spawnItem(new ItemStack(blockType.id), start);
        } else {
            const level = enchantments.includes( "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);
        };
    };

    locs.locations.push({ x, y, z });
    const blocks = BlockVolumeUtils.getBlockLocationIterator({
        from: { x: x+1, y: y+1, z: z+1 },
        to: { x: x-1, y: y-1, z: z-1 },
    });
    
    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 }) => {
        const inventory = player.getComponent( "minecraft:inventory" ).container;
        const item = inventory.getItem( player.selectedSlot );
        const durability = item.getComponent('durability')
        const veinLore = item.getLore().includes("§r§7Tree Capitator I")
		if (!item) return;
        if (item.getLore().includes("§r§7Tree Capitator I") && (durability.maxDurability - durability.damage) != 0){
          if (!item.hasTag('minecraft:is_axe'))return;
         
          breakBlocks( player, block, dimension, brokenBlockPermutation.type, block.location, Date.now() );
          }
        
    },
);



system.afterEvents.scriptEventReceive.subscribe(
  ({ id, sourceEntity })=>{
      if (!(sourceEntity instanceof Player)) return;
      if (id == "bob:warn") {
        blockWarn(sourceEntity)
      }
  },
  {
      namespaces: [
          "bob",
      ],
  },
);


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()?.block;
  if (
    (item?.hasTag('minecraft:is_axe')) &&
    blockTest?.typeId == "better_on_bedrock:enchant_bench"
  ) {
    console.warn(item.getTags)
    veinMine(player);
  }
});
function blockWarn(player) {
  let form = new ActionFormData();
  form.title("No Tool?");
  form.body(
    "§cYou are unable to enchant your tool. Please hold an Axe or Pickaxe you crafted or found and try again."
  );
    form.button("Ok");
     form.show(player).then((response) => {
    if (response.selection == 0) {

      }
    })
}
function veinMine(player) {
  let level = player.runCommandAsync("xp 0 @s").level;
  let form = new ActionFormData();
  form.title("Enchant axe?");
  form.body(
    "§cTo enchant this axe with Tree Capitator I, you need the following requirements:\n\n§e- 1x Axe\n- 1x Tree Capitator 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(
        'inventory'
      );
      for (let slot = 0; slot < inventory.container.size; slot++) {
        const itemStack = inventory.container.getItem(slot);
        if (itemStack?.typeId === "better_on_bedrock:tree_cap_book") {
          let inv = player.getComponent("inventory").container;
          let item = inv.getItem(player.selectedSlot);
          let newItem = new ItemStack(ItemTypes?.get("better_on_bedrock:stone_axe"));
          if (item?.hasTag('minecraft:is_axe')) {
            item?.setLore(["§r§7Tree Capitator I"]);
            player.runCommandAsync("clear @p better_on_bedrock:tree_cap_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) {

    }
  });
}