const MagicShardManager = {
  MAX: 10,

  SHARDS: {
    "kubejs:mana_crystal": {
      types: ["mana", "arsmana"],
      value: 25,
      attrs: [
        {
          id: "irons_spellbooks:max_mana",
          modId: "kubejs:magic_shard_max_mana",
          type: "mana",
          operation: "addition"
        }
      ],
      color: "§b",
      text: "Mana"
    },

    "kubejs:cooldown_reduction_crystal": {
      types: ["cooldown"],
      value: 0.03,
      attrs: [
        {
          id: "irons_spellbooks:cooldown_reduction",
          modId: "kubejs:magic_shard_cooldown",
          type: "cooldown",
          operation: "addition"
        }
      ],
      color: "§d",
      text: "Cooldown Reduction"
    },

    "kubejs:spell_power_crystal": {
      types: ["spellPower"],
      value: 0.5,
      attrs: [
        {
          id: "irons_spellbooks:spell_power",
          modId: "kubejs:magic_shard_spell_power",
          type: "spellPower",
          operation: "addition"
        }
      ],
      color: "§c",
      text: "Spell Power"
    },

    "kubejs:mana_regeneration_crystal": {
      types: ["regenera"],
      value: 0.1,
      attrs: [
        {
          id: "irons_spellbooks:mana_regen",
          modId: "kubejs:magic_shard_mana_regen",
          type: "regenera",
          operation: "addition"
        }
      ],
      color: "§d",
      text: "Regeneration"
    }
  },

  getData(server, player) {
    if (!server.persistentData.magicShardBonuses)
      server.persistentData.magicShardBonuses = {}

    const uuid = player.uuid.toString()

    if (!server.persistentData.magicShardBonuses[uuid]) {
      server.persistentData.magicShardBonuses[uuid] = {
        mana: 0,
        arsmana: 0,
        cooldown: 0,
        spellPower: 0,
        regenera: 0,

        mana_count: 0,
        cooldown_count: 0,
        spellPower_count: 0,
        regenera_count: 0
      }
    }

    const data = server.persistentData.magicShardBonuses[uuid]

    if (data.mana === undefined) data.mana = 0
    if (data.arsmana === undefined) data.arsmana = 0
    if (data.cooldown === undefined) data.cooldown = 0
    if (data.spellPower === undefined) data.spellPower = 0
    if (data.regenera === undefined) data.regenera = 0

    if (data.mana_count === undefined) data.mana_count = 0
    if (data.cooldown_count === undefined) data.cooldown_count = 0
    if (data.spellPower_count === undefined) data.spellPower_count = 0
    if (data.regenera_count === undefined) data.regenera_count = 0

    return data
  },

  apply(player, server) {
    const data = this.getData(server, player)

    Object.values(this.SHARDS).forEach(shard => {
      shard.attrs.forEach(attr => {
        player.removeAttribute(attr.id, attr.modId)

        const bonus = data[attr.type] || 0
        if (bonus !== 0) {
          player.modifyAttribute(attr.id, attr.modId, bonus, attr.operation)
        }
      })
    })
  },

  consume(player, server, item) {
    const shard = this.SHARDS[item.id]
    if (!shard) return

    const data = this.getData(server, player)

    const mainType = shard.types[0]
    const countKey = mainType + "_count"

    if (data[countKey] >= this.MAX) {
      player.tell("§cYou can never absorb more of this crystal.")
      return
    }

    shard.types.forEach(type => {
      if (data[type] === undefined) data[type] = 0
      data[type] += shard.value
    })

    data[countKey]++
    item.count--

    server.runCommandSilent(
      `effect give ${player.username} minecraft:blindness 2 0 true`
    )

    server.runCommandSilent(
      `playsound goety:apostle_death master ${player.username}`
    )

    server.runCommandSilent(
      `particle minecraft:soul_fire_flame ${player.x} ${player.y + 1} ${player.z} 0.4 0.6 0.4 0.02 40`
    )
    server.runCommandSilent(
      `particle minecraft:enchant ${player.x} ${player.y + 1} ${player.z} 0.5 0.8 0.5 0.1 60`
    )

    this.apply(player, server)

    player.tell(
      `${shard.color}Crystal ${shard.text} absorbed! §7(${data[countKey]}/${this.MAX})`
    )
  },

  restore(event) {
    event.server.scheduleInTicks(2, () => {
      this.apply(event.player, event.server)
    })
  }
}

ItemEvents.rightClicked(event => {
  MagicShardManager.consume(event.player, event.server, event.item)
})

PlayerEvents.loggedIn(event => {
  MagicShardManager.restore(event)
})

PlayerEvents.respawned(event => {
  MagicShardManager.restore(event)
})