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


import "./gri_magna"
import "./gri_noelle"
import "./gri_luck"
import "./gri_yuno"
import "./gri_asta"
import "./gri_licht"

const grimorios = [
  //Magna
  {
    grimorio: "yokai:gri_magna",
    event: "gri_magna",
    slotsG: [ 1, 6, 7, 8 ],
    skils: [{ rank: "d", nome: "yokai:magna_skin", mana: "5", duration: "60" }, { rank: "e", nome: "yokai:ball_magna_item", mana: "1" }, { rank: "d", nome: "yokai:grand_slam", mana: "3" }, { rank: "c", nome: "yokai:ball_scatter_magna", mana: "5" }]
  },
  //Noelle
  {
    grimorio: "yokai:gri_noelle",
    event: "gri_noelle",
    slotsG: [ 1, 6, 7, 8 ],
    skils: [{ rank: "d", nome: "yokai:noelle_skin", mana: "5", duration: "60" }, { rank: "e", nome: "yokai:water_ball_item", mana: "2" }, { rank: "d", nome: "yokai:dragon_nest_item", mana: "5" }, { rank: "b", nome: "yokai:dragon_roar_item", mana: "7" }]
  },
  //Luck
  {
    grimorio: "yokai:gri_luck",
    event: "gri_luck",
    slotsG: [ 1, 6, 7, 8 ],
    skils: [{ rank: "d", nome: "yokai:luck_skin", mana: "5", duration: "60" }, { rank: "e", nome: "yokai:ball_luck_item", mana: "1" }, { rank: "d", nome: "yokai:boots_luck", mana: "2" }, { rank: "b", nome: "yokai:gloves_luck", mana: "7" }]
  },
  //Yuno
  {
    grimorio: "yokai:gri_yuno",
    event: "gri_yuno",
    slotsG: [ 1, 6, 7, 8 ],
    skils: [{ rank: "d", nome: "yokai:yuno_skin", mana: "4", duration: "90" }, { rank: "e", nome: "yokai:ball_yuno_item", mana: "1" }, { rank: "d", nome: "yokai:moon_yuno_item", mana: "3" }, { rank: "b", nome: "yokai:tornado_yuno", mana: "7" }]
  },
  //Asta
  {
    grimorio: "yokai:gri_asta",
    event: "gri_asta",
    slotsG: [ 6, 7, 8 ],
    skils: [{ rank: "e", nome: "yokai:slayer_asta" }, { rank: "c", nome: "yokai:dweller_asta", mana: "3" }, { rank: "b", nome: "yokai:destroyer_asta", mana: "9" }]
  },
  //Licht
  {
    grimorio: "yokai:gri_licht",
    event: "gri_licht",
    slotsG: [ 1, 6, 7, 8 ],
    skils: [{ rank: "d", nome: "yokai:licht_skin", mana: "4", duration: "90" }, { rank: "e", nome: "yokai:slayer_licht" }, { rank: "c", nome: "yokai:dweller_licht", mana: "4" }, { rank: "b", nome: "yokai:destroyer_licht", mana: "9" }]
  }
]

//Save And Load Inventory
world.afterEvents.itemUse.subscribe(function (use) {
  const player = use.source
  const grimorio = grimorios.findIndex(obj => obj.grimorio == use.itemStack.typeId)
  if (grimorio != -1) {
    player.triggerEvent(`${grimorios[grimorio].event}`)
    player.addTag("gri_ativado")
    
    const inventory = player.getComponent("inventory").container
    const slots = []
    
    grimorios[grimorio].slotsG.forEach((data, index) => {
    //Reset Slots
      player.setDynamicProperty(`slot${data}_name`, undefined)
      player.setDynamicProperty(`slot${data}_amount`, undefined)
      player.setDynamicProperty(`slot${data}_lore`, undefined)
      player.setDynamicProperty(`slot${data}_nameTag`, undefined)
      player.setDynamicProperty(`slot${data}_dura`, undefined)
      player.setDynamicProperty(`slot${data}_enca_types`, undefined)
      player.setDynamicProperty(`slot${data}_enca_levels`, undefined)
      
      //save Slots
      slots.push(inventory.getItem(data))
      
      const slot = grimorios[grimorio].slotsG[index]
      if (slots[index]) {
        player.setDynamicProperty(`slot${slot}_name`, slots[index].typeId)
        player.setDynamicProperty(`slot${slot}_amount`, slots[index].amount)
        player.setDynamicProperty(`slot${slot}_lore`, slots[index].getLore().join('-'))
        player.setDynamicProperty(`slot${slot}_nameTag`, slots[index].nameTag)
        if (slots[index].hasComponent("minecraft:durability")) {
          player.setDynamicProperty(`slot${slot}_dura`, slots[index].getComponent("minecraft:durability").damage)
        }
        if (slots[index].hasComponent("minecraft:enchantable")) {
          const encatamentos = slots[index].getComponent("minecraft:enchantable").getEnchantments()
          const types = []
          const levels = []
          encatamentos.forEach(obj => {
            types.push(obj.type.id)
            levels.push(obj.level)
          })
          if (encatamentos) {
            player.setDynamicProperty(`slot${slot}_enca_types`, types.join("-"))
            player.setDynamicProperty(`slot${slot}_enca_levels`, levels.join("-"))
          }
        }
      }
    })
    

//Teste de Rank maior
    function rankMaior(playerRank, requiredRank) {
    const rankOrder = ["e", "d", "c", "b", "a", "s", "rei" ]
    return rankOrder.indexOf(playerRank) >= rankOrder.indexOf(requiredRank);
}

    //replace items
    grimorios[grimorio].slotsG.forEach((slot, i) => {
      const rank = player.getDynamicProperty("rank")
      const skil = grimorios[grimorio].skils[i]
        if (rankMaior(rank, skil.rank)) {
          const skilI = new ItemStack(skil.nome, 1)
          skilI.keepOnDeath = true
          skilI.lockMode = "slot"
          if (skil.duration && skil.mana) {
            skilI.setLore([
              { text: `mana: -${skil.mana}` },
              { rawtext: [ { translate: "item.info.duration" } , { text: `: ${skil.duration}` } ] }
            ])
          } else if (skil.mana) {
            skilI.setLore([ `mana: -${skil.mana}` ])
          }
          inventory.setItem(slot, skilI)
        } else {
          const lock = new ItemStack("yokai:lock", 1)
          lock.setLore([
            { rawtext: [{ text: `rank ${skil.rank} ` }, { translate: "item.info.required" } ] }
          ])
          lock.keepOnDeath = true
          lock.lockMode = "slot"
          inventory.setItem(slot, lock)
        }
    })
    
    const item = new ItemStack(`${grimorios[grimorio].grimorio}_open`, 1)
    item.keepOnDeath = true
    item.lockMode = "slot"
    inventory.setItem(0, item)

  } else {
    const grimorio = grimorios.findIndex(obj => `${obj.grimorio}_open` == use.itemStack.typeId)
    if (grimorio != -1) {
    player.triggerEvent(`${grimorios[grimorio].event}_close`)
    player.removeTag("gri_ativado")
    
    const inventory = player.getComponent("inventory").container
    const item = new ItemStack(grimorios[grimorio].grimorio, 1)
    item.keepOnDeath = true
    item.lockMode = "slot"
    inventory.setItem(0, item)
    
    //Load Slots
    grimorios[grimorio].slotsG.forEach(slotsI => {
      inventory.setItem(slotsI, undefined)
      const slots = [ player.getDynamicProperty(`slot${slotsI}_name`), player.getDynamicProperty(`slot${slotsI}_amount`), player.getDynamicProperty(`slot${slotsI}_lore`), player.getDynamicProperty(`slot${slotsI}_nameTag`), player.getDynamicProperty(`slot${slotsI}_dura`), player.getDynamicProperty(`slot${slotsI}_enca_types`), player.getDynamicProperty(`slot${slotsI}_enca_levels`) ]
      if (slots[0]) {
        const slot = new ItemStack(slots[0], slots[1])
        if (slots[2]) {
          slot.setLore(slots[2].split('-'))
        }
        if (slots[3]) {
          slot.nameTag = slots[3]
        }
        if (slots[4]) {
          slot.getComponent("minecraft:durability").damage = slots[4]
        }
        if (slots[5]) {
          const slotSplit = slots[5].split("-")
          slotSplit.forEach((data, index) => {
            const typeNew = new EnchantmentType(data)
            slot.getComponent("minecraft:enchantable").addEnchantment({
              level: parseInt(slots[6].split("-")[index]),
              type: typeNew
            })
          })
        }
        inventory.setItem(slotsI, slot)
      }
    })
  }
  }

})



//Pele de Mana
const peles = [
//Magna
  {
    item: "yokai:magna_skin",
    event: "magna_skin",
    mana: 5,
    duration: 1200,
    velocity: 0,
    resistance: 0
  },
//Noelle
  {
    item: "yokai:noelle_skin",
    event: "noelle_skin",
    mana: 5,
    duration: 1200,
    velocity: 0,
    resistance: 0
  },
//luck
  {
    item: "yokai:luck_skin",
    event: "luck_skin",
    mana: 5,
    duration: 1200,
    velocity: 0,
    resistance: 0
  },
//yuno
  {
    item: "yokai:yuno_skin",
    event: "yuno_skin",
    mana: 4,
    duration: 1800,
    velocity: 0,
    resistance: 0
  },
//Licht
  {
    item: "yokai:licht_skin",
    event: "licht_skin",
    mana: 4,
    duration: 1800,
    velocity: 0,
    resistance: 0
  }
  ]
  
  system.beforeEvents.startup.subscribe((event) => {
    event.itemComponentRegistry.registerCustomComponent('yokai:mana_skin', {
      onUse: use => {
        const player = use.source
        player.addTag("pele_mana")
        const rank = player.getDynamicProperty("rank")
        let speed = 0
        if (["c", "b", "a"].includes(rank)) {
          speed++
        } else if (["s", "rei"].includes(rank)) {
          speed += 2
        }
        
        const mana = player.getDynamicProperty("mana")
        const pele = peles.findIndex(obj => obj.item == use.itemStack.typeId)
        if (mana >= peles[pele].mana) {
          player.setDynamicProperty("mana", mana - peles[pele].mana)
          player.triggerEvent(`${peles[pele].event}`)
          
          player.addEffect("speed", peles[pele].duration, { amplifier: peles[pele].velocity + speed, showParticles: false })
          player.addEffect("resistance", peles[pele].duration, { amplifier: peles[pele].resistance, showParticles: false })
          system.runTimeout(() => {
            player.triggerEvent("none_skin")
            player.removeTag("pele_mana")
          }, peles[pele].duration)
        }
      }
    })
  });
  
  //Retirar pele Mana apos A morte
  world.afterEvents.entityDie.subscribe((event) => {
    if (event.deadEntity.typeId == "minecraft:player" && event.deadEntity.hasTag("pele_mana")) event.deadEntity.triggerEvent("none_skin")
  })





// Alternar entre menu e grimorio
system.afterEvents.scriptEventReceive.subscribe((event) => {
  if (event.id == "yokai:sneak" && event.sourceEntity.hasTag("finalExam")) {
    if (event.sourceEntity.selectedSlotIndex == 0) {
      const inventory = event.sourceEntity.getComponent("inventory").container
      const item = inventory.getItem(event.sourceEntity.selectedSlotIndex)
      if (item.typeId == "yokai:menu_m") {
        let itemGri = event.sourceEntity.getDynamicProperty("griShift")
        itemGri = new ItemStack(itemGri)
        itemGri.keepOnDeath = true;
        itemGri.lockMode = "slot";
        inventory.setItem(0, itemGri)
      } else {
        const itemMenu = new ItemStack("yokai:menu_m")
        itemMenu.keepOnDeath = true;
        itemMenu.lockMode = "slot";
        event.sourceEntity.setDynamicProperty("griShift", item.typeId)
        inventory.setItem(0, itemMenu)
      }
    }
  }
})

