package net.knarcraft.blacksmith.util;

import org.bukkit.Material;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;

import java.util.ArrayList;
import java.util.List;

/**
 * A helper class for getting information about items
 */
public final class ItemHelper {

    private ItemHelper() {

    }

    /**
     * Gets whether the given item is repairable
     *
     * @param item                      <p>The item to check</p>
     * @param disableMaterialLimitation <p>Whether to disable the EnchantmentTarget.BREAKABLE limitation</p>
     * @return <p>True if the item is repairable</p>
     */
    public static boolean isRepairable(ItemStack item, boolean disableMaterialLimitation) {
        return item.getItemMeta() instanceof Damageable && (disableMaterialLimitation ||
                EnchantmentTarget.BREAKABLE.includes(item));
    }

    /**
     * Gets the max durability of an item
     *
     * @param itemStack <p>The item to get the durability of</p>
     * @return <p>The max durability of the item</p>
     */
    public static short getMaxDurability(ItemStack itemStack) {
        return itemStack.getType().getMaxDurability();
    }

    /**
     * Gets the current durability of the given item
     *
     * @param itemStack <p>The item to get the durability of</p>
     * @return <p>The durability of the item</p>
     */
    public static short getDurability(ItemStack itemStack) {
        Damageable damageable = (Damageable) itemStack.getItemMeta();
        int maxDurability = getMaxDurability(itemStack);
        if (damageable != null) {
            return (short) (maxDurability - damageable.getDamage());
        } else {
            return (short) maxDurability;
        }
    }

    /**
     * Gets the damage done to the given item
     *
     * @param itemStack <p>The damage done to the item</p>
     * @return <p>The damage done to the item</p>
     */
    public static short getDamage(ItemStack itemStack) {
        Damageable damageable = (Damageable) itemStack.getItemMeta();
        if (damageable != null) {
            return (short) damageable.getDamage();
        } else {
            return 0;
        }
    }

    /**
     * Gets a complete list of all reforge-able materials
     *
     * @return <p>A complete list of reforge-able materials</p>
     */
    public static List<Material> getAllReforgeAbleMaterials() {
        List<Material> reforgeAbleMaterials = new ArrayList<>();
        for (Material material : Material.values()) {
            ItemStack item = new ItemStack(material);
            if (item.getItemMeta() instanceof Damageable && EnchantmentTarget.BREAKABLE.includes(item)) {
                reforgeAbleMaterials.add(material);
            }
        }
        return reforgeAbleMaterials;
    }

    /**
     * Checks whether the given material is an anvil
     *
     * @param material       <p>The material to check</p>
     * @param requireDamaged <p>Whether only a damaged anvil should count</p>
     * @return <p>True if the given material is an anvil</p>
     */
    public static boolean isAnvil(Material material, boolean requireDamaged) {
        boolean isDamagedAnvil = material == Material.CHIPPED_ANVIL || material == Material.DAMAGED_ANVIL;
        boolean isAnvil = isDamagedAnvil || material == Material.ANVIL;
        return (requireDamaged && isDamagedAnvil) || (!requireDamaged && isAnvil);
    }

}