package ru.dbotthepony.mc.otm.recipe

import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.NonNullList
import net.minecraft.core.RegistryAccess
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.CraftingBookCategory
import net.minecraft.world.item.crafting.CraftingRecipe
import net.minecraft.world.item.crafting.Ingredient
import net.minecraft.world.item.crafting.RecipeSerializer
import net.minecraft.world.level.Level
import net.minecraftforge.common.Tags
import ru.dbotthepony.mc.otm.container.util.stream
import ru.dbotthepony.mc.otm.core.isActuallyEmpty
import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer
import ru.dbotthepony.mc.otm.item.tool.ExplosiveHammerItem
import ru.dbotthepony.mc.otm.registry.MItems

class ExplosiveHammerPrimingRecipe(val payload: Ingredient, private val id: ResourceLocation) : CraftingRecipe {
	override fun getId(): ResourceLocation {
		return id
	}

	override fun isIncomplete(): Boolean {
		return payload.isActuallyEmpty
	}

	override fun isSpecial(): Boolean {
		return true
	}

	override fun matches(pContainer: CraftingContainer, pLevel: Level): Boolean {
		val result = pContainer.stream().filter { it.isNotEmpty }.toList()
		if (result.size != 3) return false
		return result.any { it.item is ExplosiveHammerItem && !(it.item as ExplosiveHammerItem).isPrimed(it) } &&
				result.any { it.`is`(Tags.Items.GUNPOWDER) } &&
				result.any { payload.test(it) }
	}

	override fun assemble(pContainer: CraftingContainer, registry: RegistryAccess): ItemStack {
		val hammer = pContainer.stream().filter { it.isNotEmpty && it.item is ExplosiveHammerItem }.findAny()
		if (hammer.isEmpty) return ItemStack.EMPTY

		return hammer.orElseThrow().copyWithCount(1).also {
			(it.item as ExplosiveHammerItem).prime(it)
		}
	}

	override fun canCraftInDimensions(pWidth: Int, pHeight: Int): Boolean {
		return pWidth * pHeight >= 3
	}

	override fun getResultItem(registry: RegistryAccess): ItemStack {
		return ItemStack.EMPTY
	}

	override fun getSerializer(): RecipeSerializer<*> {
		return CODEC
	}

	override fun category(): CraftingBookCategory {
		return CraftingBookCategory.EQUIPMENT
	}

	override fun getIngredients(): NonNullList<Ingredient> {
		return NonNullList.of(Ingredient.of(), Ingredient.of(MItems.EXPLOSIVE_HAMMER), Ingredient.of(Tags.Items.GUNPOWDER), payload)
	}

	fun toFinished() = CODEC.toFinished(this)

	companion object {
		val CODEC = Codec2RecipeSerializer<ExplosiveHammerPrimingRecipe> { p ->
			RecordCodecBuilder.create {
				it.group(
					p.ingredients.fieldOf("payload").forGetter(ExplosiveHammerPrimingRecipe::payload)
				).apply(it) { a -> ExplosiveHammerPrimingRecipe(a, p.id) }
			}
		}
	}
}
