
import { world, system, ItemStack, EntityComponentTypes, EquipmentSlot } from '@minecraft/server';
import { ActionFormData } from '@minecraft/server-ui';

var moveToolUsers = []
var tools = ["variant_tool", "move_tool", "rotate_tool", "freeze_tool",  "destroy_tool", "toolbox"]

world.afterEvents.playerSpawn.subscribe(event => {
  const { player } = event;
  if (player.getTags().includes('loth_mf_intro')) return;
  player.dimension.spawnItem(new ItemStack('loth_mf:guidebook_spawn_egg'), player.location)
  player.addTag('loth_mf_intro')
})

world.afterEvents.itemUse.subscribe(event => {
  if (event.itemStack.typeId.includes('loth_mf:') && event.itemStack.typeId.includes('_spawn_egg') && event.itemStack.typeId != 'loth_mf:guidebook_spawn_egg') {
    const player = event.source; // Player that used the item
    const playerDimension = player.dimension;
    const targetBlock = player.getBlockFromViewDirection({ includeLiquidBlocks: false, includePassableBlocks: false, maxDistance: 7 });
    if (!targetBlock) return;
    const block = targetBlock.block.center();
    var newBlockRotY = player.getRotation().y;
    if (newBlockRotY > -45 && newBlockRotY <= 45) newBlockRotY = 180
    else if (newBlockRotY > 45 && newBlockRotY <= 135) newBlockRotY = 270
    else if (newBlockRotY > 135 || newBlockRotY <= -135) newBlockRotY = 0
    else if (newBlockRotY <= -45 && newBlockRotY > -135) newBlockRotY = 90
    switch (targetBlock.face) {
      case 'Up':
        block.y += 0.5;
        break;
      case 'Down':
        block.y -= 1.5;
        break;
      case 'North':
        block.z -= 1;
        block.y -= 0.5;
        break;
      case 'South':
        block.z += 1;
        block.y -= 0.5;
        break;
      case 'East':
        block.x += 1;
        block.y -= 0.5;
        break;
      case 'West':
        block.x -= 1;
        block.y -= 0.5;
        break;
      default:
        break;
    }
    const entitiesAtblock =playerDimension.getEntitiesAtBlockLocation(block);
    for (const e of entitiesAtblock){
      if (e.typeId == event.itemStack.type.id.replace('_spawn_egg', '')) return;
    }
    // playerDimension.runCommand(`setblock ${block.x.toFixed(2)} ${block.y + 1} ${block.z.toFixed(2)} barrier []`);
    playerDimension.runCommand(`summon ${event.itemStack.type.id.replace('_spawn_egg', '')} ${block.x} ${block.y} ${block.z} ${newBlockRotY} 0`);
    player.playSound('random.pop', {volume: 0.2, pitch: 0.7});
    player.runCommand(`clear @s ${event.itemStack.type.id} 0 1`);
    return;
  }
})

world.afterEvents.itemStartUse.subscribe(event => {
  if (!event.itemStack) return;
  switch (event.itemStack.type.id) {
    case 'loth_mf:move_tool': {
      const player = event.source; // Player that used the item
      const targtet_entity = player.getEntitiesFromViewDirection({ maxDistance: 5 });
      if (targtet_entity.length && targtet_entity[0].entity.matches({ families: ["furniture"] })) {
        //@ts-ignore
        player.picked_entity = targtet_entity[0].entity;
        const rideableComp = targtet_entity[0].entity.getComponent(EntityComponentTypes.Rideable);
        if (rideableComp && rideableComp.getRiders().length) return;
        if(targtet_entity[0].entity.getComponent(EntityComponentTypes.TypeFamily).hasTypeFamily('light_source')){
          targtet_entity[0].entity.triggerEvent('loth_mf:turn_off');
        }
        player.runCommand(`setblock ${player.picked_entity.location.x} ${player.picked_entity.location.y} ${player.picked_entity.location.z} minecraft:air [] replace`);
        
        moveToolUsers.push(event.source);
      }

      break;
    }
    case 'loth_mf:toolbox': {
      const player = event.source; // Player that used the item
      toolboxDialog(player)
      break;
    }
    default:
      break;
  }
})
world.afterEvents.itemStopUse.subscribe(event => {
  if (!event.itemStack) return;
  switch (event.itemStack.type.id) {
    case 'loth_mf:move_tool': {
      const player = event.source; // Player that used the item
      //@ts-ignore
      if (player.picked_entity) {
        //@ts-ignore
        var picked_entity = player.picked_entity;
        var entityCentered = picked_entity.location;
        entityCentered.x = +(entityCentered.x.toString().split('.')[0] + '.50');
        if (entityCentered.y < 0) entityCentered.y = Math.round(entityCentered.y);
        else entityCentered.y = Math.trunc(entityCentered.y);
        entityCentered.z = +(entityCentered.z.toString().split('.')[0] + '.50');
        picked_entity.teleport(entityCentered);
        // player.runCommand(`setblock ${entityCentered.x} ${entityCentered.y} ${entityCentered.z} minecraft:barrier`);
      }
      //@ts-ignore
      player.picked_entity = undefined;
      moveToolUsers = moveToolUsers.filter(player => player.id != event.source.id);
      break;
    }
    default:
      break;
  }
  return;
})


async function toolboxDialog(player) {
  try {
    if (!player) return;
    const usedItemSlot = player.selectedSlotIndex;
    const inventory = player.getComponent(EntityComponentTypes.Inventory);
    const invContainer = inventory.container
    invContainer.setItem(usedItemSlot, new ItemStack(`loth_mf:toolbox_select`, 1));
    player.playSound('armor.equip_gold', {pitch: 0.8})
    const form = new ActionFormData()
      .title({ translate: 'dialog.toolbox.title'})
      // .body({ translate: 'dialog.toolbox.body' })
      .button({ translate: 'dialog.toolbox.btn.variant' }, 'textures/loth/mf/items/tools/variant')
      .button({ translate: 'dialog.toolbox.btn.move' }, 'textures/loth/mf/items/tools/move')
      .button({ translate: 'dialog.toolbox.btn.rotate' }, 'textures/loth/mf/items/tools/rotate')
      .button({ translate: 'dialog.toolbox.btn.gravity' }, 'textures/loth/mf/items/tools/freeze')
      .button({ translate: 'dialog.toolbox.btn.destroy' }, 'textures/loth/mf/items/tools/destroy');

    const formResponse = await form.show(player)
    if (formResponse.canceled) {
      invContainer.setItem(usedItemSlot, new ItemStack(`loth_mf:toolbox`, 1));
      player.playSound('armor.equip_gold', {pitch: 1.1})
      return;
    } else {
      invContainer.setItem(usedItemSlot, new ItemStack(`loth_mf:${tools[formResponse.selection]}`, 1));
      player.playSound('armor.equip_gold', {pitch: 1.1})
    }

  } catch (error) {
    console.warn(error);
  }
}

function tpPickedEntity(player) {
  try {
    if (!player) return;
    if (!player.picked_entity) return;
    var picked_entity = player.picked_entity;
    const targtet_block = player.getBlockFromViewDirection({ maxDistance: 10, includePassableBlocks: true });
    if (targtet_block) {
      const pos = targtet_block.block.center();
      switch (targtet_block.face) {
        case 'Up':
          pos.y += 0.6;
          break;
        case 'Down':
          pos.y -= 1.5;
          break;
        case 'North':
          pos.z -= 1;
          pos.y -= 0.4;
          break;
        case 'South':
          pos.z += 1;
          pos.y -= 0.4;
          break;
        case 'East':
          pos.x += 1;
          pos.y -= 0.4;
          break;
        case 'West':
          pos.x -= 1;
          pos.y -= 0.4;
          break;
        default:
          break;
      }
      picked_entity.teleport({ x: pos.x, y: pos.y, z: pos.z });
      picked_entity.dimension.spawnParticle('loth_mf:tool_move', { x: pos.x, y: pos.y, z: pos.z });
      return
    }
  } catch (error) {
    console.warn(error);
  }
}

function loopMoveToolUsers() {
  for (const player of moveToolUsers) {
    tpPickedEntity(player);
  }
}

function loopPlayers() {
  for (const player of world.getAllPlayers()) {
    if (player.isSneaking) {
      const playerEquipment = player.getComponent(EntityComponentTypes.Equippable);
      if (playerEquipment) {
        const equip = playerEquipment.getEquipment(EquipmentSlot.Mainhand);
        if (equip) {
          if (tools.includes(equip.typeId.replace('loth_mf:', ''))) {
            toolboxDialog(player);
          }
        }
      }
    }
  }
}

system.runInterval(loopMoveToolUsers, 1);
system.runInterval(loopPlayers, 1);