import { world, system, ItemStack, EquipmentSlot, EntityComponentTypes } from "@minecraft/server";

world.afterEvents.playerSpawn.subscribe(e => {
  const player = e.player
  if (e.initialSpawn) {
    if (player.hasTag('dlb_van_guidebook_given')) return
    player.dimension.spawnItem(new ItemStack('dlb_van:book_start', 1), player.location)
    player.addTag('dlb_van_guidebook_given')
  }
})

world.beforeEvents.worldInitialize.subscribe(e => {
  e.itemComponentRegistry.registerCustomComponent('dlb_van:book', {
    onUse: e => {
      const player = e.source
      const mainHand = player.getComponent(EntityComponentTypes.Equippable).getEquipmentSlot(EquipmentSlot.Mainhand)
      
      player.playSound('item.book.page_turn');
      const pages = ['dlb_van:book_start', ...Array.from({ length: 52 }, (_, i) => `dlb_van:page_${i}`)];
      let index = pages.indexOf(e.itemStack.typeId);
      if (!player.isSneaking) {
          index = (index + 1) % pages.length;
      } else {
          index = (index - 1 + pages.length) % pages.length;
      }
      mainHand.setItem(new ItemStack(pages[index], 1));
    }
  })
})

world.afterEvents.playerInteractWithBlock.subscribe(e => {
  try {
    if (e.itemStack.typeId === 'dlb_van:book_spawn_egg') {
      e.player.playSound('item.book.page_turn');
      e.player.getComponent(EntityComponentTypes.Equippable).getEquipmentSlot(EquipmentSlot.Mainhand).setItem(new ItemStack('dlb_van:page_1', 1))
    }
  } catch  { }
})
system.afterEvents.scriptEventReceive.subscribe((event) => {
  const id = event.id
  const source = event.sourceEntity
  const dimType = source.dimension
  if (id == 'dlb_van:wheel_stack') {
    const entitiesPushing = dimType.getEntities({ excludeTypes: [source.typeId], location: source.location, maxDistance: 2.2 });
    const sourceLoc = source.location;
    sourceLoc.y = 0;
    for (const entityPushing of entitiesPushing) {
      const entityPushingLoc = entityPushing.location;
      entityPushingLoc.y = 0;
      const finalLoc = {
        x: entityPushingLoc.x - sourceLoc.x,
        y: entityPushingLoc.y - sourceLoc.y,
        z: entityPushingLoc.z - sourceLoc.z
      };
      const distance = Math.sqrt(finalLoc.x * finalLoc.x + finalLoc.y * finalLoc.y + finalLoc.z * finalLoc.z);
      if (distance < 2) {
        const magnitude = Math.sqrt(finalLoc.x * finalLoc.x + finalLoc.y * finalLoc.y + finalLoc.z * finalLoc.z);
        const direction = {
          x: finalLoc.x / magnitude,
          y: finalLoc.y / magnitude,
          z: finalLoc.z / magnitude
        };
        try {
          const push = {
            x: direction.x * (2 - distance) * 0.5,
            y: direction.y * (2 - distance) * 0.5,
            z: direction.z * (2 - distance) * 0.5
          };
          event.sourceEntity.clearVelocity()
          const nPush = 2 + Math.random();
          for(let i = 0; i < nPush; i++) {
            entityPushing.applyImpulse(push);
          }
        } catch {
          entityPushing.applyKnockback(finalLoc.x, finalLoc.z, Math.hypot(finalLoc.x, finalLoc.z), finalLoc.y+0.5);
        }
      }
    }
  }
})