import { Entity, ItemDurabilityComponent, ItemStack, system } from "@minecraft/server";
import { Helper } from "../utils/Helper";
import { PlayerUtils } from "../utils/PlayerUtils";
const ITEM_ID = "sf_nba:tooth_dagger";
const ENTITY_ID = "sf_nba:tooth_dagger";
const FUTURE_DAMAGE_PROP = "sf_nba:future_damage";
const ON_TOOTH_DAGGER_HIT_GROUND_EVENT = "sf_nba:on_tooth_dagger_hit_ground_event";
const DAGGER_DAMAGE = 4;
const PROJECTILE_STRENGTH = 1.1;
export class ToothDagger {
  constructor() {
    this.onUse = this.onUse.bind(this);
    system.run(() => {
      this.#onHitGround();
    });
  }
  onUse({ source: player }) {
    const { dimension, location: pos } = player;
    const damageToBeApplied = PlayerUtils.damageMainhandItemStack(player, true, 1, false) ?? 0;
    Helper.decreaseMainhandItemStack(player);
    dimension.playSound("mob.snowgolem.shoot", pos, { pitch: 0.8 });
    const headPos = player.getHeadLocation();
    const rotation = player.getViewDirection();
    const projectile = player.dimension.spawnEntity(ENTITY_ID, {
      x: headPos.x - rotation.z * 0.3 + rotation.x * 0.2,
      y: headPos.y + 0.2,
      z: headPos.z + rotation.x * 0.3 + rotation.z * 0.2,
    });
    projectile.setRotation(player.getRotation());
    this.#listenForHitEntitySensor(projectile);
    projectile.clearVelocity();
    projectile.applyImpulse({
      x: rotation.x * PROJECTILE_STRENGTH + player.getVelocity().x,
      y: rotation.y,
      z: rotation.z * PROJECTILE_STRENGTH + player.getVelocity().z
    });
    projectile.setProperty(FUTURE_DAMAGE_PROP, damageToBeApplied);
  }
  #onHitGround() {
    system.afterEvents.scriptEventReceive.subscribe(({ id, sourceEntity: projectile }) => {
      if (id !== ON_TOOTH_DAGGER_HIT_GROUND_EVENT) return;
      this.#spawnDamagedThrownDagger(projectile);
    });
  }
  #listenForHitEntitySensor(projectile) {
    const _id = system.runInterval(() => {
      try {
        const { dimension } = projectile;
        const hitEntity = dimension.getEntities({
          location: projectile.location,
          excludeFamilies: ["sf_nba:projectile"],
          maxDistance: 1,
          closest: 1
        })[0];
        if (!hitEntity) return;
        hitEntity.applyDamage(DAGGER_DAMAGE);
        this.#spawnDamagedThrownDagger(projectile);
        system.clearRun(_id);
      } catch (error) {
        system.clearRun(_id);
      }
    }, 1);
  }
  #spawnDamagedThrownDagger(projectile, remove = true) {
    const futureDamage = projectile?.getProperty(FUTURE_DAMAGE_PROP);
    if (!projectile) return;
    const { dimension, location } = projectile;
    dimension.playSound("item.trident.hit", location, { pitch: 1.5 });
    const stack = new ItemStack(ITEM_ID);
    const durability = stack.getComponent(ItemDurabilityComponent.componentId);
    if (futureDamage >= durability.maxDurability) {
      dimension.playSound("random.break", location);
      dimension.spawnParticle("sf_nba:tooth_dagger_break", location);
      projectile.remove();
      return;
    }
    durability.damage = futureDamage;
    dimension.spawnItem(stack, location);
    if (remove) projectile.remove();
  }
}