package ru.dbotthepony.mc.otm.data.condition

import com.mojang.serialization.Codec
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.storage.loot.LootContext
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
import ru.dbotthepony.mc.otm.capability.items
import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.data.get
import ru.dbotthepony.mc.otm.registry.data.MLootItemConditions

data class ItemInInventoryCondition(
	val item: ItemStack,
	val matchComponents: Boolean = false,
	val matchCosmetics: Boolean = true,
) : LootItemCondition, LootItemCondition.Builder {
	override fun test(t: LootContext): Boolean {
		val matches = t[LootContextParams.LAST_DAMAGE_PLAYER]?.items(matchCosmetics)?.filter {
			!it.isEmpty && it.item == item.item && (!matchComponents || it.components == item.components)
		} ?: return false

		var count = 0

		for (match in matches) {
			count += match.count

			if (count >= item.count) {
				return true
			}
		}

		return false
	}

	override fun getType(): LootItemConditionType {
		return MLootItemConditions.ITEM_IN_INVENTORY
	}

	override fun build(): LootItemCondition {
		return this
	}

	companion object {
		val CODEC: MapCodec<ItemInInventoryCondition> by lazy {
			RecordCodecBuilder.mapCodec {
				it.group(
					ItemStack.CODEC.fieldOf("item").forGetter(ItemInInventoryCondition::item),
					Codec.BOOL.optionalFieldOf("matchComponents", false).forGetter(ItemInInventoryCondition::matchComponents),
					Codec.BOOL.optionalFieldOf("matchCosmetics", false).forGetter(ItemInInventoryCondition::matchCosmetics),
				).apply(it, ::ItemInInventoryCondition)
			}
		}
	}
}
