import * as mc from "@minecraft/server";
import * as vector from "./utils/vector";
import { stegoSword } from "./constants";
import * as entityUtils from "./utils/entityUtils";
import * as selectors from "./utils/selectors";

export function startUse(event) {
  if (event.itemStack.typeId === stegoSword) {
    if (!event.source.isSneaking) stegoSwordSwing(event);
    if (event.source.isSneaking) stegoSwordSlam(event);
  }
}

function stegoSwordSwing(event) {
  event.source.runCommand("/playsound hf_da:stego_sword_swing_attack_swoosh @a[r=8] ~~~");
  event.source.playAnimation("animation.hf_da.stego_sword.tp_swing", {
    stopExpression: "v.is_first_person || !q.is_item_name_any('slot.weapon.mainhand', 'hf_da:stego_sword')",
  });
  mc.system.runTimeout(() => {
    const item = event.source.getComponent("equippable").getEquipment("Mainhand");
    if (item.typeId !== stegoSword) return;
    const arc = selectors.getEntitiesArc(event.source, ["!inanimate"], 5, 180);
    const r = event.source.getViewDirection();
    let playedSound = false;
    for (var i = 0; i < arc.length; i++) {
      if (arc[i] === undefined || entityUtils.breakShield(arc[i])) continue;
      if (!playedSound) {
        playedSound = true;
        event.source.runCommand("/playsound hf_da:stego_sword_swing_attack_impact @a[r=8] ~~~");
      }
      arc[i].applyKnockback(r.x, r.z, 2.5, 0.1);
      arc[i].applyDamage(12, {
        cause: "entityAttack",
        damagingEntity: event.source,
      });
    }
  }, 12);
}

function stegoSwordSlam(event) {
  event.source.runCommand("/playsound hf_da:stego_sword_slam_attack_swoosh @a[r=8] ~~~");
  event.source.playAnimation("animation.hf_da.stego_sword.tp_slam", {
    stopExpression: "v.is_first_person || !q.is_item_name_any('slot.weapon.mainhand', 'hf_da:stego_sword')",
  });

  mc.system.runTimeout(() => {
    const item = event.source.getComponent("equippable").getEquipment("Mainhand");
    if (item.typeId !== stegoSword) return;
    event.source.runCommand("/playsound hf_da:stego_sword_slam_attack_impact @a[r=8] ~~~");
    event.source.runCommand("/camerashake add @a[r=8] 0.3 0.5 positional");
    for (let i = 0; i < 10; i++) {
      const block = event.source.dimension.getBlockFromRay(
        vector.add(vector.add(event.source.location, vector.multiply(vector.flatten(event.source.getViewDirection(), "y"), i)), vector.up),
        vector.down,
        {
          maxDistance: 2,
          includePassableBlocks: false,
          includeLiquidBlocks: false,
        }
      );
      if (block === undefined) continue;

      let map = new mc.MolangVariableMap();
      map.setFloat("variable.radius", i / 5);
      event.source.dimension.spawnParticle("hf_da:stego_sword_attack_slam_player", vector.add(vector.up, block.block.location), map);
    }

    const arc = selectors.getEntitiesArc(event.source, ["!inanimate"], 10, 40);

    for (var i = 0; i < arc.length; i++) {
      if (arc[i] === undefined || entityUtils.breakShield(arc[i])) continue;
      const r = vector.flatten(vector.subtract(arc[i].location, event.source.location), "y");
      arc[i].applyKnockback(-r.x, -r.z, 5, 1.1);
      arc[i].applyDamage(15, {
        cause: "entityAttack",
        damagingEntity: event.source,
      });
    }
  }, 14);
}
