import {
  world,
  system,
  EntityDamageCause 
} from "@minecraft/server";

// Battlestaff

const battlestaffWeapons = [
  'dungeons:battlestaff',
  'dungeons:growing_staff',
  'dungeons:battlestaff_of_terror'
];

world.afterEvents.entityHurt.subscribe((event) => {
  const hurtEntity = event.hurtEntity;
  const damageSource = event.damageSource.damagingEntity;
  const cause = event.damageSource.cause

  if (!damageSource) {
    return;
  }
  if (!damageSource.typeId === "minecraft:player") {
    return;
  }
  if (hurtEntity == damageSource) {
    return;
  }
  if (cause != "entityAttack") {
    return;
  }
  const heldItem = damageSource.getComponent("minecraft:equippable").getEquipment("Mainhand");
  if (!battlestaffWeapons.includes(heldItem.typeId)) {
    return;
  }
  if (damageSource.hasTag('battlestaff_ready')) {
    hurtEntity.runCommandAsync('summon dungeons:battlestaff_sweep ~~~')
  }
  damageSource.runCommandAsync('function battlestaff/cooldown')

});

// Committed

const committedWeapons = [
  'dungeons:growing_staff'
];

world.afterEvents.entityHurt.subscribe((event) => {
  const hurtEntity = event.hurtEntity;
  const damageSource = event.damageSource.damagingEntity;
  const cause = event.damageSource.cause
  const damage = event.damage
  if (!damageSource) {
    return;
  }
  if (!damageSource.typeId === "minecraft:player") {
    return;
  }
  if (hurtEntity == damageSource) {
    return;
  }
  if (cause != "entityAttack") {
    return;
  }
  const heldItem = damageSource.getComponent("minecraft:equippable").getEquipment("Mainhand");
  if (!committedWeapons.includes(heldItem.typeId)) {
    return;
  }

  let hp = hurtEntity.getComponent('minecraft:health')

  if (!hp) {
    console.warn('Entity does not have health component');
    return;
  }

  if ((hp.currentValue + damage) < hp.defaultValue) {

    if ((hp.defaultValue - ((hp.currentValue + damage)) * 0.33) < 30) {
      hurtEntity.applyDamage(((hp.defaultValue - (hp.currentValue + damage)) * 0.2), {cause : cause, damagingEntity: damageSource});
    } else {
      hurtEntity.applyDamage(25, {cause : cause, damagingEntity: damageSource});
    }
  }

});

// Illagers Bane

const illagersBaneWeapons = [
  'dungeons:bone_cudgel'
];

world.afterEvents.entityHurt.subscribe((event) => {
  const hurtEntity = event.hurtEntity;
  const damageSource = event.damageSource.damagingEntity;
  const cause = event.damageSource.cause
  const damage = event.damage
  if (!damageSource) {
    return;
  }
  if (!damageSource.typeId === "minecraft:player") {
    return;
  }
  if (hurtEntity == damageSource) {
    return;
  }
  if (!hurtEntity.matches({
      families: ['illager']
    })) {
    return;
  }
  if (cause != "entityAttack") {
    return;
  }
  const heldItem = damageSource.getComponent("minecraft:equippable").getEquipment("Mainhand");
  if (!illagersBaneWeapons.includes(heldItem.typeId)) {
    return;
  }

  hurtEntity.runCommandAsync('function illagers_bane_vfx')
  hurtEntity.applyDamage((damage * 1.75), {cause : cause, damagingEntity: damageSource});

});

// Smiting

const smitingWeapons = [
  'dungeons:dark_katana'
];

world.afterEvents.entityHurt.subscribe((event) => {
  const hurtEntity = event.hurtEntity;
  const damageSource = event.damageSource.damagingEntity;
  const cause = event.damageSource.cause
  const damage = event.damage
  if (!damageSource) {
    return;
  }
  if (!damageSource.typeId === "minecraft:player") {
    return;
  }
  if (hurtEntity == damageSource) {
    return;
  }
  if (!hurtEntity.matches({
      families: ['undead']
    })) {
    return;
  }
  if (cause != "entityAttack") {
    return;
  }
  const heldItem = damageSource.getComponent("minecraft:equippable").getEquipment("Mainhand");
  if (!smitingWeapons.includes(heldItem.typeId)) {
    return;
  }

  hurtEntity.runCommandAsync('function smiting_vfx')
  hurtEntity.applyDamage((damage * 1.2), {cause : cause, damagingEntity: damageSource});

});

// Unchanting

const unchantingWeapons = [
  'dungeons:truthseeker'
];

world.afterEvents.entityHurt.subscribe((event) => {
  const hurtEntity = event.hurtEntity;
  const damageSource = event.damageSource.damagingEntity;
  const cause = event.damageSource.cause
  const damage = event.damage
  if (!damageSource) {
    return;
  }
  if (!damageSource.typeId === "minecraft:player") {
    return;
  }
  if (hurtEntity == damageSource) {
    return;
  }
  if (!hurtEntity.matches({
      families: ['enchanted']
    })) {
    return;
  }
  if (cause != "entityAttack") {
    return;
  }
  const heldItem = damageSource.getComponent("minecraft:equippable").getEquipment("Mainhand");
  if (!unchantingWeapons.includes(heldItem.typeId)) {
    return;
  }

  hurtEntity.runCommandAsync('function unchanting_vfx')
  hurtEntity.applyDamage((damage * 2.2), {cause : cause, damagingEntity: damageSource});

});

// Exploding

const explodingWeapons = [
  'dungeons:cursed_axe',
  'dungeons:battlestaff_of_terror'
];

world.afterEvents.entityDie.subscribe((event) => {
  const deadEntity = event.deadEntity;
  const damageSource = event.damageSource.damagingEntity;
  const cause = event.damageSource.cause

  if (!damageSource) {
    return;
  }
  if (!damageSource.typeId === "minecraft:player") {
    return;
  }
  if (deadEntity == damageSource) {
    return;
  }
  if (cause != "entityAttack") {
    return;
  }
  const heldItem = damageSource.getComponent("minecraft:equippable").getEquipment("Mainhand");
  if (!explodingWeapons.includes(heldItem.typeId)) {
    return;
  }

  let hp = deadEntity.getComponent('minecraft:health')

  if (!hp) {
    console.warn('Entity does not have health component');
    return;
  }

  const nearbyMobs = deadEntity.dimension.getEntities({
    location: deadEntity.location,
    maxDistance: 3,
    families: ['monster']
  });

  system.runTimeout(() => {

    for (const mob of nearbyMobs) {
      if (!deadEntity) {
        return;
      }
      mob.applyDamage((hp.defaultValue * 0.25), {cause : EntityDamageCause.entityExplosion, damagingEntity: damageSource});
    }
    deadEntity.runCommandAsync('function exploding_vfx')

  }, 18) // waits 0.9 seconds for death to finish

});