//tqm
import {world, system} from '@minecraft/server';
import {list, spawnEnt, lc, dispararP, timer, qkaj, v1} from './main.js';
//-1335551913535129127

/*
system.runInterval(()=>{
  for (const e of world.getDimension('overworld').getEntities()) {
    if (e.typeId === 'minecraft:player') {
      const t = e.getComponent('inventory').container.getItem(e.selectedSlotIndex);
      e.onScreenDisplay.setActionBar(`${t?.typeId}`)
      if (t?.typeId === 'minecraft:redstone') e.applyKnockback(0, 0, 0.5, 2)
    }
  }
});

world.afterEvents.itemUse.subscribe(test=>{
  const a = test.itemStack;
  const i = test.source;
  if (a.typeId === 'minecraft:stick') {
    const l = i.getHeadLocation();
    const v = i.getViewDirection();
    function sosoo(pp, area) {
      const entidad = i.dimension.getEntities({
        location: {x: l.x+v.x*pp, y: l.y+v.y*pp, z: l.z+v.z*pp},
        volume: {x: area, y: area, z: area},
        excludeTypes: ["minecraft:player"]
      });
      entidad.forEach(o=>{
        o.applyDamage(10);
        o.applyImpulse({x: v.x*0.3, y: 0.3+v.y*0.3, z: v.z*0.3})
      });
    }
    sosoo(1, 1);
    sosoo(3, 2);
    sosoo(5, 3);
  }
});
*/

world.afterEvents.entityHurt.subscribe(data=>{
  const fuente = data.damageSource.damagingEntity;
  const qm = data.hurtEntity;
  //const salud = qm.getComponent('health');
  //qm.nameTag = `${Math.floor(salud.currentValue)} / ${salud.defaultValue}`
  if (fuente?.typeId.startsWith("parasitesap:")) {
    try {
      const entity = fuente.dimension.getEntities({location:{ x: fuente.location.x, y: fuente.location.y, z: fuente.location.z},  maxDistance: 5});
      for (const ent of entity) {
        if (ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:item' && ent !== undefined && !ent.typeId.includes('parasitesap:')) ent.addTag('parasite')
      }
    } catch(error){}finally{}
  }
  if (fuente?.typeId === "parasitesap:devourer") {
    fuente.clearVelocity();
  }
});

system.afterEvents.scriptEventReceive.subscribe(emd=>{
  const ev = emd.id;
  const em = emd.message;
  const ent = emd.sourceEntity;
  if (ev === 'parasitesap:wolf') {
    const mss = em.split(" ");
    const ieid = ent.dimension.spawnEntity(`${mss[0]}`, { x: ent.location.x, y: ent.location.y, z: ent.location.z});
    qkaj(ent, ieid);
    system.runTimeout(()=>{
      ent.remove();
    }, 5);
  }
  if (ev === 'parasitesap:minecraft_climate_variant') {
    const mss = em.split(" ");
    const ieid = ent.dimension.spawnEntity(`${mss[0]}`, { x: ent.location.x, y: ent.location.y, z: ent.location.z});
    v1(ent, ieid);
    system.runTimeout(()=>{
      ent.remove();
    }, 5);
  }
  if (ev === 'parasitesap:remains') {
    const entity = ent.location;
    const e = ent.dimension.getEntities({location:entity, type: "parasitesap:remains",  maxDistance: 2});
    for(const nop of e) {
      const victima = nop.location;
      const Vx = victima.x - entity.x
      const Vy = victima.y - entity.y
      const Vz = victima.z - entity.z
      const V = Math.sqrt(Math.pow(Vx, 2) + Math.pow(Vy, 2) + Math.pow(Vz, 2));
      nop.applyImpulse({x: Vx/V*0.8, y: Vy/V*0.7, z: Vz/V*0.8})
    }
  }
  if (ev === 'parasitesap:wardenb') {
    const tL = ent.target?.getHeadLocation();
    ent.lookAt({x: tL.x, y: tL.y, z: tL.z});
    const v = ent.getViewDirection();
    ent.applyImpulse({x: v.x*0.4, y: v.y*0.4, z: v.z*0.4});
  }
  if (ev === 'parasitesap:wardenc') {
    const tL = ent.target?.getHeadLocation();
    ent.lookAt({x: tL.x, y: tL.y+7, z: tL.z});
    const v = ent.getViewDirection();
    ent.applyImpulse({x: v.x*0.4, y: v.y*0.4, z: v.z*0.4});
  }
  if (ev === 'parasitesap:c') {
    system.run(()=>{
      if (ent.hasTag('parasitesap_lanzar')) {
        const t = ent.target
        const v = ent.getViewDirection();
        ent.removeTag('parasitesap_lanzar');
        if (t.typeId === 'minecraft:player') return t.applyKnockback ({x: v.x*3, z: v.z*3}, 2);
        t.applyImpulse({x: v.x*3, y: 2, z: v.z*3});
      }
      if (ent.hasTag('parasitesap_salto')) {
        const eL = ent.location;
        const tL = ent.target?.location ?? null;
        if (tL === null) return ent.applyImpulse({x: 0, y: 2, z: 0})
        const bx = tL.x - eL.x;
        const by = tL.y - eL.y;
        const bz = tL.z - eL.z;
        const r = Math.sqrt(Math.pow(bx, 2) + Math.pow(by, 2) + Math.pow(bz, 2))
        ent.applyImpulse({
          x: bx/r*r*0.25,
          y: by/r*r*0.13,
          z: bz/r*r*0.25
        });
        ent.removeTag('parasitesap_salto');
      }
      if (ent.hasTag('parasitesap_aplicar')) {
        ent.clearVelocity();
        const t = ent.target
        ent.lookAt({x: t.location.x, y: t.location.y, z: t.location.z})
        const v = ent.getViewDirection();
        ent.removeTag('parasitesap_aplicar');
        t.applyDamage(15, {cause: "entityAttack", damagingEntity: ent});
        if (t.typeId === 'minecraft:player') return t.applyKnockback({x: v.x*3, z: v.z*3}, -2);
        t.applyImpulse({x: v.x*3, y: -2, z: v.z*3});
      }
    });
  }
  if (ev === 'parasitesap:salto') {
    const hola = 'auausjs'
    const eL = ent.location;
    const tL = ent.target?.location ?? hola;
    if (ent.typeId ==='parasitesap:mutated_meat_tracker') {
      if (tL === hola) return ent.applyImpulse({x: 0, y: 0.6, z: 0});
      ent.lookAt({x: tL.x, y: tL.y, z: tL.z});
      const getV = ent.getViewDirection();
      ent.applyImpulse({
        x: getV.x*5,
        y: 0.6,
        z: getV.z*5
      });
      /*const empX = tL.x - eL.x
      const empZ = tL.z - eL.z
      const b = 5
      ent.applyImpulse({
        x: empX/b,
        y: 0.6,
        z: empZ/b
      });*/
    }
    if (ent.typeId.includes('parasitesap:mut_inf')) ent.applyKnockback({x: tL.x - eL.x*6, z: tL.z - eL.z*6}, 0.9);
  }
  if (ev === 'parasitesap:infectar') {
    const bloque = ent.dimension.getBlock({x: ent.location.x, y: ent.location.y - 1, z: ent.location.z});
    if (bloque.hasTag('dirt') || bloque.hasTag('grass') || bloque.hasTag('sand')) {
      ent.dimension.runCommand(`setblock ${ent.location.x} ${ent.location.y -1} ${ent.location.z} parasitesap:infected_dirt`);
    }
    else if (bloque.typeId.includes('stone') && bloque.typeId.includes('minecraft:') || bloque.hasTag('stone') || bloque.typeId.includes('deepslate') || bloque.typeId.includes('netherrack')) {
      ent.dimension.runCommand(`setblock ${ent.location.x} ${ent.location.y -1} ${ent.location.z} parasitesap:infested_stone`);
    }
    else if (bloque.hasTag('log') || bloque.typeId.includes('log')) {
      ent.dimension.runCommand(`setblock ${ent.location.x} ${ent.location.y -1} ${ent.location.z} parasitesap:infected_trunk`);
    }
    else if (bloque.hasTag('wood') || bloque.typeId.includes('planks') && !bloque.hasTag('log') && !bloque.typeId.includes('log')) {
      ent.dimension.runCommand(`setblock ${ent.location.x} ${ent.location.y -1} ${ent.location.z} parasitesap:infected_planks`);
    }
  }
  if (ev === 'parasitesap:fase') {
    const dim = world.getDimension(ent.dimension.id).id;
    if (ent.typeId === 'parasitesap:kdjfje') world.scoreboard.getObjective("parasitephasegs").addScore(`parasitesaphase_${dim}`, 3);
    if (ent.typeId.includes('parasitesap:infected')) world.scoreboard.getObjective("parasitephasegs").addScore(`parasitesaphase_${dim}`, 10);
    if (ent.typeId === 'parasitesap:growing_flesh') world.scoreboard.getObjective("parasitephasegs").addScore(`parasitesaphase_${dim}`, 20);
    if (ent.typeId.startsWith('parasitesap:nu_')) world.scoreboard.getObjective("parasitephasegs").addScore(`parasitesaphase_${dim}`, 50);
  }
  if (ev === 'parasitesap:s') {
    const objetivo = ent.target
    salto(ent, objetivo);
  }
  if (ev == 'parasitesap:dmg') {
    const mss = em.split(" ");
    let fl = parseFloat(mss[0]);
    let fm = parseFloat(mss[1]);
    ent.dimension.spawnParticle('parasitesap:explosion_de_sangre3', { x: ent.location.x, y: ent.location.y, z: ent.location.z})
    const entity = ent.dimension.getEntities({location:{ x: ent.location.x, y: ent.location.y, z: ent.location.z},  maxDistance: 4});
    for (const ent of entity) {
      if (ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:item' && ent !== undefined && !ent.typeId.startsWith('parasitesap:')) {
        ent.applyDamage(fl);
        ent.addEffect('poison', timer.s*fm);
      }
    }
    ent.remove();
  }
});

world.afterEvents.entityDie.subscribe(muerte=>{
  const idTransformation = [
    "parasitesap:unknown_worm",
    "parasitesap:parasite",
    "_remains"
  ];
  const muert = muerte.deadEntity;
  const cause = muerte.damageSource?.damagingEntity;
  function muerte1(m1) {
    m1.dimension.spawnEntity(`parasitesap:infected_zombie`, {x: m1.location.x, y: m1.location.y, z: m1.location.z});
    m1.dimension.spawnParticle('parasitesap:parasite', {x: m1.location.x, y: m1.location.y, z: m1.location.z});
    m1.remove();
  }
  function muerte2(m1) {}
  if (cause?.typeId.startsWith('parasitesap:') || muert.typeId.startsWith('parasitesap:')) {
    try{
      if (cause?.typeId.startsWith("parasitesap:")) {
        const entity = cause?.dimension?.getEntities();
        for (const entidad of entity) {
          if (entidad !== undefined && entidad.typeId.includes('parasitesap:nu_')) entidad.triggerEvent("parasitesap:nu_s");
          if (entidad !== undefined && entidad.typeId == 'parasitesap:growing_flesh') entidad.triggerEvent('parasitesap:ccgf')
        }
        const puntos = world.scoreboard.getObjective('parasitephasegs');
        const dim = world.getDimension(cause?.dimension.id).id;
        let p;
        const salud = cause?.getComponent('health').effectiveMax
        const tileEntity = world
        .getDimension(cause.dimension.id)
        .getEntities({ type: "parasitesap:booster" })[0];
        if (idTransformation.includes(cause.typeId)) spawnEnt(muert, tileEntity);
        if (tileEntity === undefined) p = 1;
        if (tileEntity !== undefined) p = 4;
        if (tileEntity !== undefined) {
          lc(muert);
          if (!idTransformation.includes(cause.typeId) && list.includes(muert.typeId)) {
            const rot = muert.getRotation();
            muert.dimension.spawnEntity("parasitesap:lc", {
              x: muert.location.x,
              y: muert.location.y,
              z: muert.location.z
            }).setRotation({ x: rot.x, y: rot.y });
            muert.dimension.spawnParticle("parasitesap:parasite", {
              x: muert.location.x,
              y: muert.location.y,
              z: muert.location.z
            });
            system.run(()=>{
              muert.remove();
            });
          }
        }
        if (cause?.typeId === 'parasitesap:unknown_worm') puntos.addScore(`parasitesaphase_${dim}`, 5 * p);
        if (cause?.typeId === 'parasitesap:parasite') puntos.addScore(`parasitesaphase_${dim}`, 2 * p);
        if (cause?.typeId.includes('parasitesap:infected') && !cause?.typeId.includes('remains')) puntos.addScore(`parasitesaphase_${dim}`, 3 * p);
        if (cause?.typeId.includes('parasitesap:mut_inf')) {
          puntos.addScore(`parasitesaphase_${dim}`, 5 * p);
          if (!cause?.typeId.includes('bat')) {
            const limite = cause?.getProperty('parasitesap:limit');
            if (limite < 3 && cause.hasTag('parasitephase2')) {
              cause.dimension.spawnParticle('add_points', {x: cause.location.x, y: cause.location.y + 1, z: cause.location.z});
              const propiedad = cause?.getProperty('parasitesap:puntos');
              cause.triggerEvent('parasitesap:puntos');
              //cause.setProperty('parasitesap:puntos', +1)
              if (propiedad > 14) {
                cause.dimension.spawnEntity('parasitesap:growing_flesh', {x: cause.location.x, y: cause.location.y, z: cause.location.z});
                cause.triggerEvent('parasitesap:limit');
                //cause.setProperty('parasitesap:limit', +1)
                cause.setProperty('parasitesap:puntos', 0);
              }
            }
          }
        }
        if (cause?.typeId.includes('parasitesap:mutated_')) puntos.addScore(`parasitesaphase_${dim}`, 8 * p);
        if (cause?.typeId === ('parasitesap:hhc')) puntos.addScore(`parasitesaphase_${dim}`, 10 * p);
        if (cause?.typeId === ('parasitesap:devourer')) puntos.addScore(`parasitesaphase_${dim}`, 10 * p);
        if (cause?.typeId === ('parasitesap:pgt')) puntos.addScore(`parasitesaphase_${dim}`, 10 * p);
        if (cause?.typeId === ('parasitesap:warden')) puntos.addScore(`parasitesaphase_${dim}`, 10 * p);
        else puntos.addScore(`parasitesaphase_${dim}`, 1 * p);
      } 
      if (muert.typeId.startsWith('parasitesap:')) {
        if (muert.typeId.includes('parasitesap:oth_b')) return;
        const dim = world.getDimension(muert?.dimension?.id)?.id;
        const puntos = world.scoreboard.getObjective('parasitephasegs');
        if (muert?.typeId === 'parasitesap:parasite') puntos.addScore(`parasitesaphase_${dim}`, 1);
        if (muert?.typeId === 'parasitesap:unknown_worm') puntos.addScore(`parasitesaphase_${dim}`, 1);
        if (muert?.typeId.includes('parasitesap:infected')) puntos.addScore(`parasitesaphase_${dim}`, - 1);
        if (muert?.typeId.includes('parasitesap:mut_inf')) puntos.addScore(`parasitesaphase_${dim}`, - 2);
        if (muert?.typeId.includes('parasitesap:mutated_')) puntos.addScore(`parasitesaphase_${dim}`, - 4);
        if (muert?.startsWith('parasitesap:nu_')) {
          puntos.addScore(`parasitesaphase_${dim}`, - 1);
        }
        else puntos.addScore(`parasitesaphase_${dim}`, - 1);
      }
    } catch(error){}finally{}
  }
  //EXPERIMENTAL
  else if (muert.typeId.includes('zombie') && (muert.hasTag('parasite') || cause?.typeId.startsWith('parasitesap:'))) {
    const sns = [muerte1, muerte2, muerte2, muerte2];
    const snsbb = Math.floor(Math.random() * sns.length);
    sns[snsbb](muert);
  }
  else if (muert.typeId.includes('human') || muert.nameTag.toLowerCase().includes("human") && (muert.hasTag('parasite') || cause?.typeId.startsWith('parasitesap:'))) {
    muert.dimension.spawnEntity(`parasitesap:infected_human`, { x: muert.location.x, y: muert.location.y, z: muert.location.z });
    muert.dimension.spawnParticle('parasitesap:parasite', { x: muert.location.x, y: muert.location.y, z: muert.location.z });
    muert.remove();
  }
  return;
});

world.afterEvents.projectileHitEntity.subscribe(proyectil=>{
  const proj = proyectil.source;
  const pr = proyectil.projectile;
  const victima = proyectil.getEntityHit().entity;
  /*if (proj.typeId == 'parasitesap:mutated_arachnid') {
  }*/
  /*if (pr.typeId == 'parasitesap:flecha') {
    const perforacion = pr.nameTag;
    const score = world.scoreboard.getObjective('flecha_parasitesap');
    score.addScore(pr, 1);
    const s = world.scoreboard.getObjective("flecha_parasitesap").getScore(pr);
    if (s == perforacion) pr.remove();
  }*/
  if (pr.typeId === 'parasitesap:pa') {
    const {location, dimension} = proyectil;
    const tileEntity = world
    .getDimension(pr.dimension.id)
    .getEntities({ type: "parasitesap:booster" })[0];
    const entity = proyectil.dimension.getEntities({location:{ x: proyectil.location.x, y: proyectil.location.y, z: proyectil.location.z},  maxDistance: 4});
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y, z:location.z});
    for (const ent of entity) {
      if (ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:player' && ent.typeId !== 'minecraft:item' && ent !== undefined && !ent.typeId.includes('parasitesap:')) {
        spawnEnt(ent, tileEntity);
        lc(ent);
      }
    }
    pr.remove();
  }
  if (pr.typeId === 'parasitesap:potion_a') {
    const {location, dimension} = proyectil;
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y, z:location.z});
  }
  if (pr.typeId === 'parasitesap:potion_c') {
    const {location, dimension} = proyectil;
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y, z:location.z});
  }
  return;
});

world.afterEvents.projectileHitBlock.subscribe(proyectil=>{
  const proj = proyectil.source;
  const pr = proyectil.projectile;
  /*if (proj.typeId == 'parasitesap:mutated_arachnid') {
    
  }*/
  if (pr.typeId === 'parasitesap:flecha') {
    try {
      if (pr.hasTag('parasitesap:remover')) {
        system.runTimeout(()=>{
          pr.remove();
        }, 4);
      }
    } catch(error){} finally{}
  }
  if (pr.typeId === 'parasitesap:pa') {
    const {location, dimension} = proyectil;
    const tileEntity = world
    .getDimension(pr.dimension.id)
    .getEntities({ type: "parasitesap:booster" })[0];
    const entity = proyectil.dimension.getEntities({location:{ x: proyectil.location.x, y: proyectil.location.y, z: proyectil.location.z},  maxDistance: 4});
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y + 0.2, z:location.z});
    for (const ent of entity) {
      if (ent.typeId !== 'minecraft:xp_orb' && ent.typeId !== 'minecraft:player' && ent.typeId !== 'minecraft:item' && ent !== undefined && !ent.typeId.includes('parasitesap:')) {
        spawnEnt(ent, tileEntity);
        lc(ent);
      }
    }
    pr.remove();
  }
  if (pr.typeId === 'parasitesap:potion_a') {
    const {location, dimension} = proyectil;
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y + 0.2, z:location.z});
    return;
  }
  if (pr.typeId === 'parasitesap:potion_c') {
    const {location, dimension} = proyectil;
    dimension.spawnParticle('minecraft:splash_spell_emitter', {x: location.x, y: location.y + 0.2, z:location.z});
    return;
  }
  return;
});

/*world.afterEvents.playerPlaceBlock.subscribe(infected => {
  const { block, dimension } = infected;
  const { x, y, z } = block.location;
  const directions = {
    a: { x: x, y: y + 1, z: z },
    b: { x: x, y: y - 1, z: z },
    c: { x: x, y: y, z: z + 1 },
    d: { x: x, y: y, z: z - 1 },
    e: { x: x + 1, y: y, z: z },
    f: { x: x - 1, y: y, z: z }
  };
  for (const [a, v] of Object.entries(directions)) {
    const neighborBlock = dimension.getBlock(v);
    if (!neighborBlock.hasTag('parasitesap_bloque_infectado')) continue;
    neighborBlock.setType('minecraft:stone');
    const ob = neighborBlock.permutation.getState('parasitesap:i_b');
    if (ob === false) {
      const state = neighborBlock.withState('parasitesap:i_b', true)
      neighborBlock.setPermutation(state);
    }
  }
});*/

world.afterEvents.itemCompleteUse.subscribe(({itemStack, source}) => {
  if (itemStack.typeId === "parasitesap:potion_b") {
    source.removeTag("parasite");
  }
  return;
});

system.beforeEvents.watchdogTerminate.subscribe(et=>{
  et.cancel = true;
});

world.afterEvents.dataDrivenEntityTrigger.subscribe(s=>{
  const e = s.entity;
  const n = s.eventId;
  if (e.typeId === 'parasitesap:devourer') {
    if (n === 'parasitesap:ap') {
      const entity = e.location;
      const a = e.dimension.getEntities({location:entity, excludeFamilies: ["parasitesap", "inanimate"], excludeTypes: ["minecraft:xp_orb", "minecraft:item"],  maxDistance: 8});
      for(const nop of a) {
        const victima = nop.location;
        const Vx = victima.x - entity.x
        const Vy = victima.y - entity.y
        const Vz = victima.z - entity.z
        const V = Math.sqrt(Math.pow(Vx, 2) + Math.pow(Vy, 2) + Math.pow(Vz, 2));
        if (nop.typeId === 'minecraft:player') {
          if (!nop.matches({gameMode: 'creative'}) && !nop.matches({gameMode: 'spectator'})) {
            nop.applyKnockback({x: -Vx/V*1.4, z: -Vz/V*1.4}, -Vy/V);
          }
        }
        else if (nop.typeId !== 'minecraft:player') {
          nop.applyImpulse({x: -Vx/V*1.2, y: -Vy/V*1.2, z: -Vz/V*1.2});
        }
      }
    }
  }
  if (e.typeId === 'parasitesap:unknown_worm') {
    if (n === 'parasitesap:tr') {
      e.dimension.spawnParticle('parasitesap:parasite', e.location);
    }
  }
  if (e.typeId.startsWith('parasitesap:infected')) {
    if (n === 'parasitesap:infected_transformation') {
      e.dimension.spawnParticle('parasitesap:parasite', e.location);
    }
  }
});

function salto(entidad, objetivo) {
    const posicionEntidad = entidad.location;
    const posicionObjetivo = objetivo.location;
    const dX = posicionObjetivo.x - posicionEntidad.x;
    const dZ = posicionObjetivo.z - posicionEntidad.z;
    const distanciaTotal = Math.sqrt(dX ** 2 + dZ ** 2);
    const fuerzaImpulso = distanciaTotal*0.16;
    entidad.applyImpulse({
      x: dX / distanciaTotal * fuerzaImpulso,
      y: +1.4,
      z: dZ / distanciaTotal * fuerzaImpulso
    });
}