package pw.hamzantal.vagueenchants.commands

import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.command.CommandSender
import pw.hamzantal.vagueenchants.*
import pw.hamzantal.vagueenchants.enchantments.CustomEnchant
import pw.hamzantal.vagueenchants.enchantments.OmniTool
import kotlin.math.min

class Upgrade : Cmd {

	override val firstArg = "upgrade"
	override val usage = "/ve upgrade [player] [enchantment] <level>"
	override val minArgs = 3
	override val description = "&7Upgrade the player's level for an enchantment."

	override val requirePermission = true
	override val permission = "ve.admin"
	override val requirePlayer = false

	override fun execute(sender: CommandSender, args: Array<String>) {
		val (_, targetName, enchName) = args

		val target = Bukkit.getPlayer(targetName) ?: run {
			sender.err("target_not_found", "player" to targetName)
			return
		}
		val ench = enchName.ench(sender) ?: return

		val level = if (args.size == 4) args.component4().toIntOrNull() ?: run {
			sender.err("The value ${args.component4()} was not parsed as a number. Using 1 instead.")
			1
		} else 1
		if (level < 0) {
			target.err("level_below_zero")
			return
		}

		val item = target.inventory.itemInMainHand
		if (item == null || item.type == Material.AIR) {
			target.err("no_item_held")
			return
		}

		val current = item.enchantments[ench] ?: 0
		val config = ench.conf() ?: run {
			target.err("upgrade_illegal_enchantment")
			return
		}
		if (current >= config.max) {
			target.err("upgrade_max_level")
			return
		}

		val newLevel = min(config.max, current + level)

		val cost = ((current + 1)..(newLevel)).toList()
			.map { config.cost.x(it) }
			.sumBy { it.toInt() }

		val tokens = getTokens(target.uuid)
		if (tokens < cost) {
			target.err("upgrade_not_enough", "token" to "$cost")
			return
		}

		setTokens(target.uuid, tokens - cost)

		val success = if (ench is CustomEnchant) ench.customEnchant(item, newLevel)
		else item.addUnsafeEnchantment(ench, newLevel) == Unit

		if (ench is OmniTool) target.inventory.itemInMainHand = item.unbreakable(true)

		if (success) {
			target.success("upgrade_receiver", "level" to "${newLevel - current}", "token" to "$cost")
		} else sender.err("general_error")
	}
}