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

// MYCELIUM Armour

world.afterEvents.entityDie.subscribe((event) => {
  const deadEntity = event.deadEntity;
  const damageSource = event.damageSource.damagingEntity;
  if (!damageSource) { return; }
  if (damageSource.typeId === "minecraft:player" && damageSource.hasTag('dragons:mycelium_armour') && (deadEntity.matches({ families: ['monster'] }) || deadEntity.matches({ families: ['mob'] }))) {
    damageSource.addEffect("absorption", 1200, { amplifier: 0, showParticles: true });
  }
});

// BAMBOO Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.isSprinting && player.hasTag("dragons:bamboo_armour")) {
      player.addEffect("speed", 5, { amplifier: 1, showParticles: false });
      player.addEffect("jump_boost", 5, { amplifier: 0, showParticles: false });
    }
  }
});

// NIGHT Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.isSneaking && player.hasTag("dragons:night_armour")) {
      player.addEffect("invisibility", 3, { amplifier: 0, showParticles: false });
      player.addEffect("speed", 3, { amplifier: 2, showParticles: false });
      player.playAnimation('animation.night_armour');
    }
  }
});

// DEADLY Armour

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.isValid()) return;
  if (!hurtEntity.hasTag('dragons:deadly_armour')) {
    return;
  }
  if (hurtEntity == damageSource) {
    return;
  }
  if (cause == "thorns") return;

  damageSource.runCommand('particle dragons:deadly_deflect ~~1~');
  if (hurtEntity.typeId === "minecraft:player") {
    hurtEntity.playSound('damage.thorns', {
      pitch: 0.5,
      volume: 0.5
    });
  }
  damageSource.applyDamage(damage * 2, {
    cause: EntityDamageCause.thorns,
    damagingEntity: hurtEntity
  });

});

// ECHO Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:echo_armour")) {
      player.addEffect("night_vision", 300, { amplifier: 0, showParticles: false });
    }
  }
});

// FIRE Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:fire_armour")) {
      player.addEffect("fire_resistance", 10, { amplifier: 0, showParticles: false });
    }
  }
});

// NETHER Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:nether_armour")) {
      player.addEffect("fire_resistance", 10, { amplifier: 0, showParticles: false });
    }
  }
});

// QUAKE Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:quake_armour")) {
      player.addEffect("haste", 10, { amplifier: 1, showParticles: false });
    }
  }
});

// SNOW Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:snow_armour")) {
      player.addEffect("resistance", 10, { amplifier: 0, showParticles: false });
    }
  }
});

// SKY Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:sky_armour")) {
      player.addEffect("speed", 10, { amplifier: 0, showParticles: false });
    }
  }
});

// VOID Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:void_armour")) {
      player.addEffect("strength", 10, { amplifier: 0, showParticles: false });
    }
  }
});

// TIDE Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:tide_armour")) {
      player.addEffect("water_breathing", 10, { amplifier: 0, showParticles: false });
    }
  }
});

// ENCHANTED Armour

const positiveEffects = [
  'speed',
  'haste',
  'strength',
  'jump_boost',
  'regeneration',
  'resistance',
  'health_boost',
  'absorption'
];

world.afterEvents.effectAdd.subscribe((event) => {
  const entity = event.entity;
  if (entity.hasTag('ignoreEnchanted')) {
    entity.removeTag('ignoreEnchanted')
    return;
  }
  if (!event.effect) { return; }
  if (entity.typeId !== 'minecraft:player') return;
  const amplifier = event.effect.amplifier;
  const duration = event.effect.duration;
  const effectId = event.effect.typeId;
  if (amplifier >= 255) return;
  if (!positiveEffects.includes(effectId)) {
    return;
  }
  if (!entity.hasTag('dragons:enchanted_armour')) return;
  entity.addTag('ignoreEnchanted')
  entity.removeEffect(effectId);
  entity.addEffect(effectId, duration, {
    amplifier: amplifier + 1
  });
  system.runTimeout(() => {
    entity.removeTag('ignoreEnchanted')
  }, 3);
});

// FOREST Armour

system.runInterval(() => {
  for (const player of world.getPlayers()) {
    if (player.hasTag("dragons:forest_armour")) {
      let hp = player.getComponent('minecraft:health')
      hp.setCurrentValue(hp.currentValue + 1)
    }
  }
}, 100);

// Lethal Armour

world.afterEvents.entityHurt.subscribe((event) => {
  const hurtEntity = event.hurtEntity;
  const damage = event.damage

  if (!hurtEntity.hasTag('dragons:lethal_armour')) {
    return;
  }

  hurtEntity.dimension.spawnParticle("dragons:lethal_absorption", { x: hurtEntity.location.x, y: hurtEntity.location.y + 1, z: hurtEntity.location.z })
  hurtEntity.playSound('damage.thorns', {
    pitch: 0.25,
    volume: 0.25
  });
  var lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
  if (!lethalAbsorp) {
    world.scoreboard.addObjective("lethalAbsorp");
    lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
  }
  if (damage < 0.2) return;
  if (lethalAbsorp.getScore(hurtEntity) == 19) {
    hurtEntity.dimension.playSound("mob.warden.death", hurtEntity.location, { pitch: 1.5, volume: 2 })
    if (!hurtEntity.hasTag("dragons:deadly_charge_warn")) {
      hurtEntity.sendMessage("§e§oOnce the Lethal Dragon Armour has absorped enough damage, double tap SNEAK to release a large blast!");
      hurtEntity.addTag("dragons:deadly_charge_warn")
    }
  }
  lethalAbsorp.addScore(hurtEntity, Math.ceil(damage))


});

system.runInterval(() => {
  for (const player of world.getPlayers({
    tags: ["dragons:lethal_armour"]
  })) {
    var lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
    if (!lethalAbsorp) {
      world.scoreboard.addObjective("lethalAbsorp");
      lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
    }
    if (lethalAbsorp.getScore(player) >= 20) {
      player.dimension.spawnParticle("dragons:electric_aura", player.location)
    }
    if (lethalAbsorp.getScore(player) >= 50) {
      player.dimension.spawnParticle("dragons:electric_aura2", player.location)
    }
  }
});

system.runInterval(() => {
  for (const player of world.getPlayers({
    tags: ["dragons:lethal_armour"]
  })) {
    var lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
    if (!lethalAbsorp) {
      world.scoreboard.addObjective("lethalAbsorp");
      lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
    }
    if (lethalAbsorp.getScore(player) >= 50) {
      player.applyDamage(1, { cause: EntityDamageCause.lightning })
    }
  }
}, 100);

world.afterEvents.entityDie.subscribe((event) => {
  const entity = event.deadEntity;
  if (!entity) return;
  if (!entity.isValid()) return;
  if (entity.hasTag("dragons:lethal_armour")) {
    var lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
    if (!lethalAbsorp) {
      world.scoreboard.addObjective("lethalAbsorp");
      lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
    }
    lethalAbsorp.setScore(entity, 0)
  }
})

world.afterEvents.playerButtonInput.subscribe((event) => {
  const player = event.player;
  const button = event.button;
  const newState = event.newButtonState;
  let inputInfo = player.inputInfo.lastInputModeUsed;
  if (!player.hasTag('dragons:lethal_armour')) {
    return;
  }
  var lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
  if (!lethalAbsorp) {
    world.scoreboard.addObjective("lethalAbsorp");
    lethalAbsorp = world.scoreboard.getObjective("lethalAbsorp")
  }
  if (lethalAbsorp.getScore(player) < 20) return;
  if (button === "Jump") return;
  if (newState === ButtonState.Released) return;
  if (player.hasTag('dragons:debug')) {
    player.sendMessage(button);
    player.sendMessage(newState);
    player.sendMessage(inputInfo);
  }
  if (player.hasTag('dragons:detect_double_sneak')) {
    player.removeTag('dragons:detect_double_sneak');

    player.dimension.playSound("mob.warden.sonic_boom", player.location, { pitch: 1.5, volume: 2 })
    player.dimension.playSound("item.trident.return", player.location, { pitch: 1, volume: 12 })
    player.dimension.spawnParticle("dragons:electric_burst1", { x: player.location.x, y: player.location.y + 1, z: player.location.z })
    player.dimension.spawnParticle("dragons:electric_burst2", { x: player.location.x, y: player.location.y, z: player.location.z })
    player.dimension.spawnParticle("dragons:electric_burst2", { x: player.location.x + 2, y: player.location.y, z: player.location.z })
    player.dimension.spawnParticle("dragons:electric_burst2", { x: player.location.x - 2, y: player.location.y, z: player.location.z })
    player.dimension.spawnParticle("dragons:electric_burst2", { x: player.location.x, y: player.location.y, z: player.location.z + 2 })
    player.dimension.spawnParticle("dragons:electric_burst2", { x: player.location.x, y: player.location.y, z: player.location.z - 2 })



    let entities = player.dimension.getEntities({
      location: player.location,
      maxDistance: 5
    });
    const newEntiies = [];
    for (const entity of entities) {
      if (entity !== player && (entity.matches({ families: ["player"] }) || entity.matches({ families: ["monster"] }))) {
        newEntiies.push(entity)
      }
    }
    if (newEntiies.length >= 1) {

      var damage = lethalAbsorp.getScore(player) / (1 + newEntiies.length / 4)
      if (damage < 5) damage = 5;
      if (damage > 30) damage = 30;
      for (const entity of newEntiies) {
        entity.applyDamage(damage, { damagingEntity: player, cause: EntityDamageCause.lightning })
        const xDif = entity.location.x - player.location.x;
        const zDif = entity.location.z - player.location.z;

        if (entity.typeId === 'minecraft:player') {
          entity.runCommandAsync('camerashake add @s 0.6 1 positional');
        }
        entity.applyKnockback(xDif, zDif, damage / 10, damage / 20);
        lethalAbsorp.addScore(player, damage * -2)
      }
    }
    lethalAbsorp.addScore(player, (lethalAbsorp.getScore(player) / 4) * -1)
    if (lethalAbsorp.getScore(player) < 0) {
      lethalAbsorp.setScore(player, 0)
    }



    return;
  }
  if (!player.hasTag('dragons:detect_double_sneak')) {
    player.addTag('dragons:detect_double_sneak');
    if (inputInfo === "Touch") {
      system.runTimeout(() => {
        if (player.hasTag('dragons:detect_double_sneak')) player.removeTag('dragons:detect_double_sneak');
      }, 10);
      return;
    }
    else {
      system.runTimeout(() => {
        if (player.hasTag('dragons:detect_double_sneak')) player.removeTag('dragons:detect_double_sneak');
      }, 5);
    }
  }
});