import { world, EntityInventoryComponent, ItemStack, system, EquipmentSlot, GameMode, ItemCooldownComponent, Player, EntityEquippableComponent, EntityComponentTypes } from '@minecraft/server'
import { available_items, itemsHandEffect } from '../UTILS/globalVars';
import { dwInjections } from './weaponsEffects';
function damageItemIfNeeded(player) {
    if (!(player instanceof Player)) return;

    const equippable = player.getComponent("minecraft:equippable");
    if (!equippable) return;

    const mainhand = equippable.getEquipmentSlot(EquipmentSlot.Mainhand);
    if (!mainhand.hasItem()) return;

    if (player.getGameMode() === GameMode.creative) return;

    const itemStack = mainhand.getItem();
    const durability = itemStack.getComponent("minecraft:durability");
    if (!durability) return;

    const enchantable = itemStack.getComponent("minecraft:enchantable");
    const unbreakingLevel = enchantable?.getEnchantment("unbreaking")?.level ?? 0;
    const damageChance = durability.getDamageChance(unbreakingLevel) / 100;

    if (Math.random() > damageChance) return;

    // Aplicar daño
    if (durability.damage + 1 >= durability.maxDurability) {
        mainhand.setItem(undefined);
        player.playSound("random.break");
    } else {
        durability.damage++;
        mainhand.setItem(itemStack);
    }
}
world.beforeEvents.worldInitialize.subscribe(e => {
    e.itemComponentRegistry.registerCustomComponent("dive_hw:on_use", {
        async onUse(event) {
        const player = event.source;
        const itemUsed = event.itemStack;
        if (!available_items.has(itemUsed.typeId)) return;
        const { x, y, z } = player.location;
        switch (itemUsed.typeId) {
            case 'dive_hw:hacker_sword':
                player.playAnimation(`animation.dive_hw.hacker_sword.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
                world.playSound(`mob.panda.bite`, { x: x, y: y, z: z });
                damageItemIfNeeded(player);
                break;
            case 'dive_hw:hacker_axe':
                    player.playAnimation(`animation.dive_hw.hacker_axe.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
                    system.runTimeout(() => {
                        world.playSound(`mob.panda.bite`, { x: x, y: y, z: z }, { pitch: 0.5 });
                        system.runTimeout(() => {
                        player.removeTag("dive_hw.stop_animations");
                        }, 8);
                    }, 4)
                    damageItemIfNeeded(player);
                break;
            case 'dive_hw:hacker_blade':
                player.playAnimation(`animation.dive_hw.hacker_blade.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
                player.addTag("dive_hw.stop_animations");
                world.playSound(`mob.evocation_illager.cast_spell`, { x: x, y: y, z: z });
                if (player.hasTag("dive_hw.stop_animations")) {
                    system.runTimeout(() => {
                    player.removeTag("dive_hw.stop_animations");
                }, 19);
                };
                damageItemIfNeeded(player);
            break;
            case 'dive_hw:hacker_hammer':
              player.playAnimation(`animation.dive_hw.hacker_hammer.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
              player.addTag("dive_hw.stop_animations");
              if (player.hasTag("dive_hw.stop_animations")) {
                system.runTimeout(() => {
                  world.playSound(`random.anvil_land`, { x: x, y: y, z: z }, { pitch: 0.5 });
                  player.removeTag("dive_hw.stop_animations");
                }, 22
                );
              };
              damageItemIfNeeded(player);
            break;
            case 'dive_hw:hacker_blaster':
            player.playAnimation(`animation.dive_hw.hacker_blaster.tpp_attack`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
            player.addTag("dive_hw.stop_animations");
            if (player.hasTag("dive_hw.stop_animations")) {
              system.runTimeout(() => {
                world.playSound(`mob.blaze.shoot`, { x: x, y: y, z: z }, { pitch: 0.5 });
                system.runTimeout(() => {
                  player.removeTag("dive_hw.stop_animations");
                }, 18
                );
              }, 4);
            };
            damageItemIfNeeded(player);
          break;
            case 'dive_hw:hacker_laser':
              player.playAnimation(`animation.dive_hw.hacker_laser.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
              player.addTag("dive_hw.stop_animations");
              if (player.hasTag("dive_hw.stop_animations")) {
                system.runTimeout(() => {
                  world.playSound(`mob.blaze.shoot`, { x: x, y: y, z: z }, { pitch: 2 });
                  system.runTimeout(() => {
                    world.playSound(`mob.blaze.shoot`, { x: x, y: y, z: z }, { pitch: 2 });
                    system.runTimeout(() => {
                      world.playSound(`mob.blaze.shoot`, { x: x, y: y, z: z }, { pitch: 2 });
                      system.runTimeout(() => {
                        player.removeTag("dive_hw.stop_animations");
                      }, 10
                      );
                    }, 4);
                  }, 4);
                }, 4)
              };
              damageItemIfNeeded(player);
            break;
            case 'dive_hw:hacker_chopper':
            player.playAnimation(`animation.dive_hw.hacker_chopper.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
            player.addTag("dive_hw.stop_animations");
            if (player.hasTag("dive_hw.stop_animations")) {
              system.runTimeout(() => {
                world.playSound(`mob.panda.bite`, { x: x, y: y, z: z });
                system.runTimeout(() => {
                  player.removeTag("dive_hw.stop_animations");
                }, 22
                );
              }, 7)
            };
            damageItemIfNeeded(player);
          break;
            case 'dive_hw:hacker_pickaxe':
            player.playAnimation(`animation.dive_hw.hacker_pickaxe.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
            player.addTag("dive_hw.stop_animations");
            if (player.hasTag("dive_hw.stop_animations")) {
              system.runTimeout(() => {
                world.playSound(`mob.blaze.shoot`, { x: x, y: y, z: z }, { pitch: 0.2 });
                system.runTimeout(() => {
                  player.removeTag("dive_hw.stop_animations");
                }, 22
                );
              }, 5)
            };
            damageItemIfNeeded(player);
            break;
            case 'dive_hw:hacker_drill':
            player.playAnimation(`animation.dive_hw.hacker_drill.tpp_attack`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
            player.addTag("dive_hw.stop_animations");
            world.playSound(`minecart.inside`, { x: x, y: y, z: z }, { pitch: 3.25 });
            if (player.hasTag("dive_hw.stop_animations")) {
              system.runTimeout(() => {
                player.removeTag("dive_hw.stop_animations");
              }, 22
              );
            };
            damageItemIfNeeded(player);
            break;
            case 'dive_hw:hacker_hoe':
            player.playAnimation(`animation.dive_hw.hacker_hoe.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
            system.runTimeout(() => {
              world.playSound(`block.composter.fill`, { x: x, y: y, z: z }, { pitch: 1 });
            }, 10
            );
            damageItemIfNeeded(player);
            break;
            case 'dive_hw:hacker_wand':
            player.playAnimation(`animation.dive_hw.hacker_wand.tpp_use`, { controller: `ItemUseFirstPerson`, stopExpression: `q.all_animations_finished` });
            player.addTag("dive_hw.stop_animations");
            if (player.hasTag("dive_hw.stop_animations")) {
              system.runTimeout(() => {
                player.removeTag("dive_hw.stop_animations");
                world.playSound(`mob.evocation_illager.prepare_summon`, { x: x, y: y, z: z });
              }, 22
              );
            };
            damageItemIfNeeded(player);
            break;
            case 'dive_hw:hacker_shield':
              player.playAnimation("animation.dive_hw.hacker_shield.tpp_use")
              player.dimension.spawnParticle("dive_hw:shield_hexagon", player.location);
              damageItemIfNeeded(player);
            break;
          }
        }
    });
})

world.afterEvents.entityHitEntity.subscribe(({ damagingEntity, hitEntity }) => {
    const is = damagingEntity instanceof Player;
    const vl = hitEntity && is;
    if (!vl) return;

    const itemStack = damagingEntity.itemInHand;
    if (!itemStack) return;
    if (!dwInjections.has(itemStack.typeId)) return;
    const inject = dwInjections.get(itemStack.typeId);

    const validAttacks = inject.attacks.filter(({ injectorType }) => injectorType == "onHit");
    if (!validAttacks || validAttacks?.length == 0) return;

    for (const attack of validAttacks) {
        if (inject.hasCooldown && attack.testCooldown) {
        const cooldown = itemStack.getComponent(ItemCooldownComponent.componentId);
        const remaining = cooldown?.getCooldownTicksRemaining(damagingEntity);
        if (remaining !== (cooldown.cooldownTicks - 1)) continue;
        }
        
        attack.toInject(damagingEntity, hitEntity, itemStack);
    }
});
world.afterEvents.itemUse.subscribe(({ source, itemStack }) => {
    if (!dwInjections.has(itemStack.typeId)) return;
    const inject = dwInjections.get(itemStack.typeId);

    const validAttacks = inject.attacks.filter(({ injectorType }) => injectorType == "onUse");
    if (!validAttacks || validAttacks?.length == 0) return;

    for (const attack of validAttacks) {
        if (inject.hasCooldown && attack.testCooldown) {
        const cooldown = itemStack.getComponent(ItemCooldownComponent.componentId);
        const remaining = cooldown?.getCooldownTicksRemaining(source);
        if (remaining !== (cooldown.cooldownTicks - 1)) {
            continue;
        }
        }

        attack.toInject(source, itemStack);
        if (attack?.cancelNext) return;
    }
});

world.afterEvents.projectileHitEntity.subscribe(projectileHitEntity => {
  const { projectile, source } = projectileHitEntity;
  const hitEntity = projectileHitEntity.getEntityHit().entity;

  if (!hitEntity) return;
  if (!dwInjections.has(projectile.typeId)) return;

  const inject = dwInjections.get(projectile.typeId);

  const validAttacks = inject.attacks.filter(({ injectorType }) => injectorType == "onHitByProjectile");
  if (!validAttacks || validAttacks?.length == 0) return;

  for (const attack of validAttacks) {
    attack.toInject(projectile, hitEntity, source);
  }
});
world.afterEvents.projectileHitBlock.subscribe(projectileHitBlock => {
  const { projectile, source } = projectileHitBlock;
  const hitBlock = projectileHitBlock.getBlockHit().block;
  
  
  if (!hitBlock) return;
  if (!dwInjections.has(projectile.typeId)) return;

  const inject = dwInjections.get(projectile.typeId);

  const validAttacks = inject.attacks.filter(({ injectorType }) => injectorType == "onHitByProjectileAtBlock");
  if (!validAttacks || validAttacks?.length == 0) return;

  for (const attack of validAttacks) {
    attack.toInject(projectile, hitBlock, source);
  }
});
world.beforeEvents.playerBreakBlock.subscribe(({ player, block, itemStack }) => {
  if (!itemStack) return;
  if (!dwInjections.has(itemStack.typeId)) return;

  const inject = dwInjections.get(itemStack.typeId);

  const validAttacks = inject.attacks.filter(({ injectorType }) => injectorType == "onBreakBlock");
  if (!validAttacks || validAttacks?.length == 0) return;

  for (const attack of validAttacks) {
    attack.toInject(player, block, itemStack);
  }
});
system.runInterval(async () => {
  const players = world.getAllPlayers();
  for (let i = 0; i < players.length; i++) {
    const player = players[i];
    const item = player.itemInChest;

    if (!item) continue;
    if (!dwInjections.has(item.typeId)) continue;

    const inject = dwInjections.get(item.typeId);
    inject.setInterval(player);

    await new Promise(resolve => system.runTimeout(resolve, 1));
    continue;
  }
});

itemsHandEffect.set("dive_hw:hacker_hammer", [
  ["fire_resistance", 20],
  ["speed", 20]
]);
system.runInterval(async () => {
  const players = world.getAllPlayers();
  for (let i = 0; i < players.length; i++) {
    const player = players[i];
    const item = player.itemInHand;
    if (!item) continue;
    if (!itemsHandEffect.has(item.typeId)) continue;

    const effects = itemsHandEffect.get(item.typeId);
    for (const [effect, duration] of effects) {
      player.addEffect(effect, duration);
    }

    await new Promise(resolve => system.runTimeout(resolve, 1));
    continue;
  }
}, 10);