import {world,MolangVariableMap,ItemStack,system} from "@minecraft/server"
import {socksSpeedEffect} from "./socks.js"
import {soulboundRing} from "./soulbound_ring.js"
import { minecraftFood } from "../armors/deceitweb.js"
import { getScore } from "../../utils/score.js"




export const artifactsList = [
    "poisonous_mucus",
    "corrupted_star",
    "blaze_heart",
    "blue_eye",
    "crystal_of_youth",
    "crystal_of_bravery",
    "crystal_of_rage",
    "crystal_of_fear",
    "dragon_heart",
    "battle_cry",
    'ancient_shield',
    'double_quiver',
    'bloody_totem',
    'explosive_blaze_rod',
    'soul_bottle',
    'blood_vial',
    'sculk_quiver',
    'magic_axe',
    'enchanted_socks',
    'magnetic_firework',
    'magnet',
    'ring_of_atlantis',
    'golden_ring',
    'heavy_quiver',
    'magma_socks',
    'noinsomnia',
    'heart_bottle',
    'gheart_bottle',
    'undying_flower',
    'bloody_ruby',
    'hussars_spear',
    "chaining_scroll",
    "charged_hit_scroll",
    "crushing_scroll",
    "uppercut_scroll",
    'sharper_spear',
    'speed_spear',
    'shield_spear',
    'wither_spear',
    'cloud_socks',
    'heavy_socks',
    'molten_ingot',
    'bloody_bramble',
    'sculk_portal',
    'supersonic_arrow',
    'void_socks',
    'chorus_socks',
    'purpur_socks',
    'void_cloak',
    'xp_orb',
    'soul_mirror',
    'soulbound_ring',
    'doppelpalm',
    'bile_heart',
    'pulse_ear'
]

export function artifacts(player)
{
    let inv = player.getComponent("inventory").container
    var item1=inv?.getItem(9)?.getTags()
    var item2=inv?.getItem(18)?.getTags()
    var item3=inv?.getItem(27)?.getTags()
    if(item1==undefined) item1=[]
    var goldenSlots = item1?.concat(item2,item3)
    if(goldenSlots.length>0)
      for(let j = 0; j < artifactsList.length; j++)
        {
          let hasArtifact = goldenSlots.includes(artifactsList[j]) 
          let hasTag = player.hasTag(artifactsList[j])
          if((hasTag && !hasArtifact ))
            player.removeTag(artifactsList[j])
          else if(!hasTag && hasArtifact)
            player.addTag(artifactsList[j])
        }
    
}

export function artifactsWork20T(player)
{
  magmaSocks(player)
  poisonousMucus(player)
  fireAmulet(player)
  socksSpeedEffect(player)
  ringOfAtlantis(player)
  Magnet(player)
  FleshTotem(player)
  FleshTotemParticle(player)
  MagicAxe(player)
}
export function artifactsWork40T(player)
{
  undyingFlower(player)
  soulboundRing(player)
  BlueEye(player)
  xpOrb(player)
  DragonHeart(player)
  Crystals(player)
  HeartInBottle(player)
  GoldenHeartInBottle(player)
  DreamlikePendant(player)
  PulseEar(player)
}


export function ancientShieldParry(attacker,player,damage){
  if(player.hasTag('ancient_shield'))
  {
    const time = world.scoreboard.getObjective("Sneak_time");
    const timeValue = time.getScore(player);
    if(timeValue >=5 && player.isSneaking)
    {
      player.dimension.playSound('item.shield.block',player.location,{pitch:Math.random()+0.5});
      if(player.hasTag('void_cloak') && world.scoreboard.getObjective("Void_cloak").getScore(player)==0)
      {
        VoidCloakBoom(player,true)
      }
      else
      {
        attacker.applyDamage(Math.max(10, damage*8/10),{cause: "entityAttack",damagingEntity: player})
        const vmap = new MolangVariableMap();
        vmap.setVector3('variable.direction', player.getViewDirection());
        player.dimension.spawnParticle('edx:ancient_shield_parry',{x:player.getHeadLocation().x+player.getViewDirection().x/4,y:player.getHeadLocation().y+player.getViewDirection().y/4,z:player.getHeadLocation().z+player.getViewDirection().z/4},vmap);
      }
    }
  }
  else if(player.hasTag('void_cloak'))
  {
    VoidCloakBoom(player,false)
  }
  
}

export function ancientShieldTime(player){
  const time = world.scoreboard.getObjective("Sneak_time");
  if(time.getScore(player)==0 || time.getScore(player)==undefined)
  {
    time.setScore(player, 8);
  }
    
}

export function BattleCry(player){
  if(!player.hasTag('battle_cry')) return;
  const time = world.scoreboard.getObjective("Battle_cry");
  if(time.getScore(player)==0 || time.getScore(player)==undefined)
  {
    
    const entityOptions = {
      location: player.location,
      maxDistance: 8
    }
    const entities = player.dimension.getEntities(entityOptions);
    var shoot=false
    if(entities!=undefined)
      for (let i = 0; i < entities.length ; i++){
          if(entities[i]!=undefined)
          {
            const entity =entities[i]
            const projectile = entity?.getComponent("minecraft:projectile")
            if(projectile!=undefined)
            {
              shoot=true
              projectile.owner = player
              const dir = {x:-player.location.x+entity.location.x,y:-player.location.y-1+entity.location.y,z:-player.location.z+entity.location.z}
              const dist = Math.sqrt(dir.x**2+dir.y**2+dir.z**2)
              projectile.shoot({ x: dir.x/dist*2, y: dir.y/dist*2, z: dir.z/dist*2})
            }
          }
      }
      if(shoot)
      {
        time.setScore(player, 8);
        player.dimension.spawnParticle('minecraft:knockback_roar_particle',{x:player.location.x,y:player.location.y+1,z:player.location.z});
      }
  }
}
function MagicAxe(player)
{
  if (player.hasTag("magic_axe")) 
  {
    if(player.getComponent("health").currentValue>6)return;
    const magic_axe_score = world.scoreboard.getObjective("magic_axe");
    if(magic_axe_score.getScore(player)==0)
    {
        magic_axe_score.setScore(player,120)
        const magic_axe = player.dimension.spawnEntity("edx:magic_axe", player.location);
        magic_axe.getComponent("minecraft:tameable").tame(player)
    }
  }
}
export function bloodVial(player,damage,victim)
{
  let health = player.getComponent("health")
  health.setCurrentValue(health.currentValue + Math.min(0.8, damage*1/10))
  victim.runCommand(`particle edx:blood ~~~`);
}

export function deadlyRuby(player)
{
  if (player.hasTag("bloody_ruby")) {
    player.addEffect("strength", 20 );
  }
}
export function HeavySocks(player)
{
  if (player.hasTag("heavy_socks")) {
    var distance = getScore(player,'Height') - player.location.y
    if(distance>=6)
    {
      const shockawve = player.dimension.spawnEntity("edx:shockwave",player.location);
      shockawve.triggerEvent('shockwave')
    }
  }
}

function PulseEar(player)
{
  if(!player.hasTag('pulse_ear') || !player.isSneaking) return
  
  const entityOptions = {
    location: player.location,
    families: ["mob"],
    excludeFamilies: ["skeleton"],
    maxDistance: 32
  }
  const entities = player.dimension.getEntities(entityOptions);
  if(entities!=undefined)
    for (let i = 0; i < entities.length ; i++){
        if(entities[i]!=undefined && entities[i] != player)
        {
          if(Math.random()<0.8)
          {
            const entity = entities[i]
            const dir = {x:player.location.x-entity.location.x,y:player.location.y-entity.location.y,z:player.location.z-entity.location.z}
            const dist = Math.sqrt(dir.x**2+dir.y**2+dir.z**2)
            const lifetime = dist/10 //5=speed
            const vmap = new MolangVariableMap();
            vmap.setVector3('variable.dir', dir);
            vmap.setFloat('variable.max_lifetime', lifetime);
            player.spawnParticle('edx:pulse_ear_particle',{x:entity.location.x,y:1+entity.location.y,z:entity.location.z},vmap);
          }
          
        }
    }
}

function DreamlikePendant(player)
{
  const score = world.scoreboard.getObjective('Dreamlike_pendant');
  const health = world.scoreboard.getObjective('max_health');
  if(player.hasTag('noinsomnia'))
  {
    if(score.getScore(player)>=601 && !player.hasTag('already_dreamlike_pendant'))
    {
      player.addTag('already_dreamlike_pendant')
      health.addScore(player, 2)
    }
    else if(score.getScore(player)<=600 && player.hasTag('already_dreamlike_pendant'))
    {
      player.removeTag('already_dreamlike_pendant')
      health.addScore(player, -2)
    }
    if(score.getScore(player)>=1 && !player.hasTag('already_dreamlike_pendant2'))
    {
      player.addTag('already_dreamlike_pendant2')
      health.addScore(player, 2)
    }
    else if(score.getScore(player)<=0 && player.hasTag('already_dreamlike_pendant2'))
    {
      player.removeTag('already_dreamlike_pendant2')
      health.addScore(player, -2)
    }
  }
  if (!player.hasTag('noinsomnia') && score.getScore(player)>0)
  {
    score.setScore(player, 0)
  }
  
}

function HeartInBottle(player)
{
  const score = world.scoreboard.getObjective('max_health');
  if(player.hasTag('heart_bottle') && !player.hasTag('already_heart_bottle'))
  {
    player.addTag('already_heart_bottle')
    score.addScore(player, 2)
  }
  else if(!player.hasTag('heart_bottle') && player.hasTag('already_heart_bottle'))
  {
    player.removeTag('already_heart_bottle')
    score.addScore(player, -2)
  }
}
function GoldenHeartInBottle(player)
{
  const score = world.scoreboard.getObjective('max_health');
  if(player.hasTag('gheart_bottle') && !player.hasTag('already_gheart_bottle'))
  {
    player.addTag('already_gheart_bottle')
    score.addScore(player, 2)
  }
  else if(!player.hasTag('gheart_bottle') && player.hasTag('already_gheart_bottle'))
  {
    player.removeTag('already_gheart_bottle')
    score.addScore(player, -2)
  }
}
function FleshTotemParticle(player)
{
  if (player.hasTag("flesh_totem") && player.isSneaking) {
    player.dimension.spawnParticle('edx:flesh_totem_circle',{x:player.location.x,y:player.location.y+1,z:player.location.z});
  }
}

function FleshTotem(player)
{
  FleshTotemArtifact(player)
  system.runTimeout(() => { // to make the artifact works every 10 ticks without having to get all players every 10 ticks (prevent lag this way)
    FleshTotemArtifact(player)
  },10)
}
function FleshTotemArtifact(player)
{
  if (!player.hasTag("flesh_totem")) return;
  const entityOptions1 = {
    location: player.location,
    type:  "minecraft:player" ,
    maxDistance: 6
  }
  const entities1 = player.dimension.getEntities(entityOptions1);
  if(entities1!=undefined)
    for (let i = 0; i < entities1.length ; i++){
        if(entities1[i]!=undefined && entities1[i].name != player.name)
        {
          const entity =entities1[i]
          entity.addEffect("strength", 20 );
          entity.addEffect("speed", 20 );
          if(Math.abs(entity.location.x-player.location.x)<=2 && Math.abs(entity.location.y-player.location.y)<=2 && Math.abs(entity.location.z-player.location.z)<=2)
          {
            entity.addEffect("resistance", 20 );
            entity.addEffect("regeneration", 20 );
          }
        }
    }
}
function magmaSocks(player)
{
  if (player.hasTag("magma_socks")) {
    const block = player.dimension.getBlock(player.location)
    if(block.typeId=="minecraft:powder_snow")
    {
      block.setType("minecraft:air")
      player.dimension.spawnParticle('minecraft:ice_evaporation_emitter',player.location);
    }
    const blockabove = player.dimension.getBlock({x:player.location.x,y:player.location.y+1,z:player.location.z})
    if(blockabove.typeId=="minecraft:powder_snow")
    {
      blockabove.setType("minecraft:air")
      player.dimension.spawnParticle('minecraft:ice_evaporation_emitter',{x:player.location.x,y:player.location.y+1,z:player.location.z});
    }
  }
}

function xpOrb(player)
{
  if (player.hasTag("xp_orb") && (player.isSprinting || player.isSwimming)) {
    player.addExperience(1)
  }
}
function Magnet(player) 
{
  MagnetArtifact(player)
  system.runTimeout(() => { // to make the artifact works every 10 ticks without having to get all players every 10 ticks (prevent lag this way)
    MagnetArtifact(player)
  },10)

}
function MagnetArtifact(player)
{
  if (player.hasTag("magnet")) {
    const entityOptions = {
      location: player.location,
      type:  "minecraft:item" ,
      maxDistance: 4
    }
  const entities = player.dimension.getEntities(entityOptions);
  if(entities!=undefined)
    for (let i = 0; i < entities.length ; i++){
        if(entities[i]!=undefined)
        {
          const entity =entities[i]
          const dir = {x:player.location.x-entity.location.x,y:player.location.y-entity.location.y,z:player.location.z-entity.location.z}
          const dist = Math.sqrt(dir.x**2+dir.y**2+dir.z**2)
          entity.applyImpulse({ x: dir.x/(dist*2), y: dir.y/(dist*2), z: dir.z/(dist*2)})
        }
    }
  }
}

function poisonousMucus(player)
{
  if (player.hasTag("poisonous_mucus")) {
    player.removeEffect('poison')
    player.removeEffect('fatal_poison')
    player.removeEffect('hunger')
  }
}
function Crystals(player)
{
  if(player.getComponent("health").currentValue>10)return;

  if (player.hasTag("crystal_of_bravery")) {
    player.addEffect("resistance", 100 ,{showParticles: false})
  }
  if (player.hasTag("crystal_of_youth")) {
    player.addEffect("regeneration", 100 ,{showParticles: false})
  }
  if (player.hasTag("crystal_of_rage")) {
    player.addEffect("strength", 100 ,{showParticles: false})
  }
  if (player.hasTag("crystal_of_fear")) {
    player.addEffect("speed", 100 ,{showParticles: false})
  }
}
function fireAmulet(player)
{
  if (player.hasTag("blaze_heart")) {
    if(player?.getDynamicProperty('blazeblade_arena')==undefined && player.dimension.getBlock(player.location).typeId != "minecraft:lava")
      player.addEffect("fire_resistance", 240 ,{showParticles: false})
    else if(player.getEffect("fire_resistance")!=undefined && player?.getDynamicProperty('blazeblade_arena')!=undefined)
    {
      player.removeEffect("fire_resistance")
      player.dimension.playSound('random.break',player.location)
      player.dimension.spawnParticle('edx:fire_amulet_break',player.location);
    }
  }
}
function DragonHeart(player)
{
  if (player.hasTag("dragon_heart")) {
    player.dimension.spawnEntity("edx:dragon_breath",player.location);
  }
}

function undyingFlower(player)
{
  const time=world.getTimeOfDay()
  if (player.hasTag("undying_flower") && time>0 && time<13000) {
    const raycast = player.dimension.getBlockFromRay(player.location,{x:0,y:1,z:0},{ maxDistance: 200,includePassableBlocks:false,includeLiquidBlocks:false})
    if(raycast?.block==undefined)
    {
      let health = player.getComponent("health")
      health.setCurrentValue(health.currentValue+0.66)
    }
  }
}

function ringOfAtlantis(player){
  if(player.hasTag('ring_of_atlantis') && player.isInWater)
  {
    player.addEffect("water_breathing", 60 ,{showParticles: false});
    player.addEffect("weakness", 60,{showParticles: false});
  }
}
function BlueEye(player){
  if(player.hasTag('blue_eye'))
  {
    player.addEffect("night_vision", 400 ,{showParticles: false});
  }
}

export function EatArtifacts(player,item)
{
  if(player.hasTag('bile_heart') || player.hasTag('doppelpalm'))
  {
    var itemNutrition=undefined
    const vanillaFood = minecraftFood.find(({ id }) => id === item.typeId )
    if(item?.getComponent("minecraft:food")!=undefined)
    {
      itemNutrition = item.getComponent("minecraft:food").nutrition
    }
    else if(vanillaFood!=undefined)
    {
      itemNutrition = vanillaFood.nutrition
    }
    if(itemNutrition!=undefined)
    {
      if(player.hasTag('bile_heart'))
      {
        let health = player.getComponent("health")
        try{
        health.setCurrentValue(health.currentValue + itemNutrition/4)
        }
        catch(e){}
      }
      if(player.hasTag('doppelpalm') && Math.random()<0.25)
        {
          let inv = player.getComponent("inventory").container
          inv.addItem(new ItemStack(item.typeId, 1))
          player.dimension.playSound('item.deceitweb_armor.eat',player.location)
        }
    }
  }
}

function VoidCloakBoom(player,shield)
{
  const score = world.scoreboard.getObjective("Void_cloak");
  if(score.getScore(player)!=0)return
  const options = {location: player.location, maxDistance: 4 ,excludeTypes: ["minecraft:item"],excludeFamilies:["projectile"]}
  const entities = player.dimension.getEntities(options);
  var boom = false
  if(entities!=undefined)
    for (let i = 0; i < entities.length ; i++){
        if(entities[i]!=undefined && entities[i].typeId != "minecraft:player")
        {
          boom=true
          const entity =entities[i]
          entity.applyDamage(shield?30:15,{cause: "entityAttack",damagingEntity: player})
          
        }
    }
    if(boom)
    {
      if(player.hasTag('void_armor'))
        score.setScore(player, 20);
      else
        score.setScore(player, 40);
      player.dimension.playSound('respawn_anchor.deplete',player.location,{pitch:Math.random()+0.5});
      player.dimension.spawnParticle('edx:void_cloak_boom',{x:player.location.x,y:player.location.y,z:player.location.z});
      if(shield)
      {
        player.dimension.playSound('respawn_anchor.set_spawn',player.location,{pitch:Math.random()+0.5});
        player.dimension.spawnParticle('edx:void_cloak_circle',{x:player.location.x,y:player.location.y,z:player.location.z});
      }
        
    }
}

export async function BewitchedFirework(dim)
{
  const fireworks = dim.getEntities({type: 'fireworks_rocket'});
  for (const firework of fireworks){
    if(firework?.getComponent('variant')?.value==1)
    {
      let entities = dim.getEntities({location:firework.location,maxDistance:7,excludeTypes: ["minecraft:player","minecraft:fireworks_rocket"],excludeFamilies:["projectile","pet","player","sus_item"]});
      for(const entity of entities)
      {
         entity.teleport(firework.location)
      }
      await system.waitTicks(2)//to keep it attracted
      for(const entity of entities)
      {
         entity.teleport(firework.location)
      }
        
    }
}
}




