package com.shanebeestudios.skbee.elements.recipe.effects;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.parser.ParserInstance;
import ch.njol.util.Kleenean;
import com.shanebeestudios.skbee.api.event.internal.recipe.ShapedRecipeCreateEvent;
import com.shanebeestudios.skbee.api.event.internal.recipe.ShapelessRecipeCreateEvent;
import com.shanebeestudios.skbee.api.recipe.RecipeUtil;
import com.github.shanebeee.skr.Registration;
import org.bukkit.event.Event;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;

public class EffRecipeSetIngredient extends Effect {

    public static void register(Registration reg) {
        reg.newEffect(EffRecipeSetIngredient.class,
                "set ingredient (of|for) %string% to %itemstack/recipechoice/minecrafttag%",
                "add %itemstack/recipechoice/minecrafttag% to ingredients")
            .name("Recipe - Ingredient")
            .description("Set/add to the ingredients of a shaped/shapeless recipe.",
                "This is specifically used in the ingredients section of shaped/shapeless recipe section.",
                "`set ingredient` is used for shaped recipes.",
                "`add ingredient` is used for shapeless recipes.")
            .examples("see shaped/shapeless recipe sections.")
            .since("3.0.0")
            .register();
    }

    private int pattern;
    private Expression<String> key;
    private Expression<?> ingredient;

    @SuppressWarnings("unchecked")
    @Override
    public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
        this.pattern = matchedPattern;

        if (this.pattern == 0 && !ParserInstance.get().isCurrentEvent(ShapedRecipeCreateEvent.class)) {
            Skript.error("`set ingredient` effect can only be used in an `ingredients` section of a shaped recipe section.");
            return false;
        } else if (this.pattern == 1 && !ParserInstance.get().isCurrentEvent(ShapelessRecipeCreateEvent.class)) {
            Skript.error("`add ingredients` effect can only be used in an `ingredients` section of a shapeless recipe section.");
            return false;
        }
        this.key = this.pattern == 0 ? (Expression<String>) exprs[0] : null;
        this.ingredient = exprs[this.pattern == 0 ? 1 : 0];
        return true;
    }

    @Override
    protected void execute(Event event) {
        Object ingredient = this.ingredient.getSingle(event);

        RecipeChoice recipeChoice = RecipeUtil.getRecipeChoice(ingredient);
        if (recipeChoice == null) return;

        if (this.pattern == 0 && event instanceof ShapedRecipeCreateEvent shapedEvent) {
            String key = this.key.getSingle(event);
            if (key == null || key.length() != 1) return;

            ShapedRecipe shapedRecipe = shapedEvent.getRecipe();
            if (Arrays.toString(shapedRecipe.getShape()).contains(key)) {
                char charKey = key.charAt(0);
                shapedRecipe.setIngredient(charKey, recipeChoice);

            }
        } else if (this.pattern == 1 && event instanceof ShapelessRecipeCreateEvent shapelessEvent) {
            ShapelessRecipe shapelessRecipe = shapelessEvent.getRecipe();
            if (shapelessRecipe.getChoiceList().size() < 9) shapelessRecipe.addIngredient(recipeChoice);
        }
    }

    @Override
    public @NotNull String toString(@Nullable Event e, boolean d) {
        if (this.pattern == 0) {
            return "set ingredient of " + this.key.toString(e, d) + " to " + this.ingredient.toString(e, d);
        } else {
            return "add " + this.ingredient.toString(e, d) + " to ingredients";
        }
    }

}
