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.SerializationContext
import net.minecraft.advancements.critereon.SimpleCriterionTrigger
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.fromJsonStrict
import ru.dbotthepony.mc.otm.core.toJsonStrict

val ExopackObtainedTrigger = SingletonTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_obtained"))
val ExopackGainedCraftingTrigger = SingletonTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_gained_crafting"))
val ExopackGainedSmeltingTrigger = SingletonTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_gained_smelting"))

val ExopackBatterySlotTrigger = ItemTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_battery_slot"))

object ExopackSlotsExpandedTrigger : SimpleCriterionTrigger<ExopackSlotsExpandedTrigger.Instance>() {
	val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_expanded")

	override fun getId(): ResourceLocation {
		return ID
	}

	val codec: Codec<Instance> = RecordCodecBuilder.create {
		it.group(
			Codec.intRange(0, Int.MAX_VALUE).optionalFieldOf("minGained", 0).forGetter(Instance::minGained),
			Codec.intRange(0, Int.MAX_VALUE).optionalFieldOf("minTotal", 0).forGetter(Instance::minTotal),
		).apply(it, ::Instance)
	}

	fun trigger(player: ServerPlayer, gained: Int, total: Int) {
		trigger(player) { it.minGained <= gained && it.minTotal <= total }
	}

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

	data class Instance(val minGained: Int = 0, val minTotal: Int = 0) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {
		init {
			require(minGained >= 0) { "Invalid minGained $minGained" }
			require(minTotal >= 0) { "Invalid minTotal $minTotal" }
		}

		override fun serializeToJson(p_16979_: SerializationContext): JsonObject {
			return codec.toJsonStrict(this) as JsonObject
		}
	}
}
