package ru.dbotthepony.mc.otm.triggers

import com.google.gson.JsonObject
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
import net.minecraft.advancements.critereon.ContextAwarePredicate
import net.minecraft.advancements.critereon.DeserializationContext
import net.minecraft.advancements.critereon.ItemPredicate
import net.minecraft.advancements.critereon.SerializationContext
import net.minecraft.advancements.critereon.SimpleCriterionTrigger
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.fromJsonStrict
import ru.dbotthepony.mc.otm.core.toJsonStrict
import ru.dbotthepony.mc.otm.data.ItemPredicateCodec

class ItemTrigger(val ID: ResourceLocation) : SimpleCriterionTrigger<ItemTrigger.Instance>() {
	override fun getId(): ResourceLocation {
		return ID
	}

	fun trigger(player: ServerPlayer, item: ItemStack) {
		trigger(player) { if (it.invert) !it.predicate.matches(item) else it.predicate.matches(item) }
	}

	val codec: Codec<Instance> = RecordCodecBuilder.create {
		it.group(
			ItemPredicateCodec.fieldOf("predicate").forGetter(Instance::predicate),
			Codec.BOOL.optionalFieldOf("invert", false).forGetter(Instance::invert),
		).apply(it, ::Instance)
	}

	override fun createInstance(p_66248_: JsonObject, p_286603_: ContextAwarePredicate, p_66250_: DeserializationContext): Instance {
		return codec.fromJsonStrict(p_66248_)
	}

	inner class Instance(val predicate: ItemPredicate, val invert: Boolean = false) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {
		override fun serializeToJson(p_16979_: SerializationContext): JsonObject {
			return codec.toJsonStrict(this) as JsonObject
		}
	}
}
