package ru.dbotthepony.mc.otm.triggers

import com.google.gson.JsonObject
import net.minecraft.advancements.critereon.*
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.entity.LivingEntity
import ru.dbotthepony.mc.otm.core.set

abstract class HurtTrigger : SimpleCriterionTrigger<HurtTrigger.Instance>() {
	abstract val ID: ResourceLocation

	override fun getId(): ResourceLocation {
		return ID
	}

	override fun createInstance(
		p_66248_: JsonObject,
		p_286603_: ContextAwarePredicate,
		p_66250_: DeserializationContext
	): Instance {
		return Instance(
			EntityPredicate.fromJson(p_66248_, "entity_predicate", p_66250_),
			(p_66248_["damage"] as? JsonObject)?.let(DamagePredicate::fromJson) ?: DamagePredicate.ANY
		)
	}

	fun trigger(player: ServerPlayer, entity: LivingEntity, damage: Float, damageSource: DamageSource) {
		val context = EntityPredicate.createContext(player, entity)

		trigger(player) {
			it.predicate.matches(context) && it.damagePredicate.matches(player, damageSource, damage, damage, false)
		}
	}

	inner class Instance(
		val predicate: ContextAwarePredicate = ContextAwarePredicate.ANY,
		val damagePredicate: DamagePredicate = DamagePredicate(
			MinMaxBounds.Doubles.atLeast(1.0),
			MinMaxBounds.Doubles.atLeast(1.0),
			EntityPredicate.ANY,
			null,
			DamageSourcePredicate.ANY
		)
	) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {
		override fun serializeToJson(pConditions: SerializationContext): JsonObject {
			return super.serializeToJson(pConditions).also {
				it["entity_predicate"] = predicate.toJson(pConditions)
				it["damage"] = damagePredicate.serializeToJson()
			}
		}
	}
}
