package ru.dbotthepony.mc.otm.registry

import net.minecraft.network.chat.Component
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3
import ru.dbotthepony.mc.otm.core.TranslatableComponent

class ImmutableDamageSource(private val parent: DamageSource) : DamageSource(parent.msgId) {
	override fun equals(other: Any?): Boolean {
		return parent == other
	}

	override fun hashCode(): Int {
		return parent.hashCode()
	}

	override fun toString(): String {
		return parent.toString()
	}

	override fun isProjectile(): Boolean {
		return parent.isProjectile
	}

	override fun setProjectile(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun isExplosion(): Boolean {
		return parent.isExplosion
	}

	override fun setExplosion(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun isBypassArmor(): Boolean {
		return parent.isBypassArmor
	}

	override fun isDamageHelmet(): Boolean {
		return parent.isDamageHelmet
	}

	override fun getFoodExhaustion(): Float {
		return parent.foodExhaustion
	}

	override fun isBypassInvul(): Boolean {
		return parent.isBypassInvul
	}

	override fun isBypassMagic(): Boolean {
		return parent.isBypassMagic
	}

	override fun getDirectEntity(): Entity? {
		return parent.directEntity
	}

	override fun getEntity(): Entity? {
		return parent.entity
	}

	override fun bypassArmor(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun damageHelmet(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun bypassInvul(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun bypassMagic(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun setIsFire(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun setNoAggro(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun getLocalizedDeathMessage(p_19343_: LivingEntity): Component {
		return super.getLocalizedDeathMessage(p_19343_)
	}

	override fun isFire(): Boolean {
		return parent.isFire
	}

	override fun isNoAggro(): Boolean {
		return parent.isNoAggro
	}

	override fun getMsgId(): String {
		return parent.getMsgId()
	}

	override fun setScalesWithDifficulty(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun scalesWithDifficulty(): Boolean {
		return parent.scalesWithDifficulty()
	}

	override fun isMagic(): Boolean {
		return parent.isMagic
	}

	override fun setMagic(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun isFall(): Boolean {
		return parent.isFall
	}

	override fun setIsFall(): DamageSource {
		throw UnsupportedOperationException()
	}

	override fun isCreativePlayer(): Boolean {
		return parent.isCreativePlayer
	}

	override fun getSourcePosition(): Vec3? {
		return parent.sourcePosition
	}
}

abstract class MatteryDamageSource(name: String, private val entity: Entity? = null, val inflictor: ItemStack? = null) : DamageSource(name) {
	override fun getLocalizedDeathMessage(victim: LivingEntity): Component {
		val itemStack = inflictor ?: (entity as LivingEntity?)?.mainHandItem ?: ItemStack.EMPTY

		if (!itemStack.isEmpty && itemStack.hasCustomHoverName()) {
			return TranslatableComponent("death.attack.$msgId.player.item", victim.displayName, entity!!.displayName, itemStack.displayName)
		}

		if (entity != null) {
			return TranslatableComponent("death.attack.$msgId.player", victim.displayName, entity.displayName)
		}

		return TranslatableComponent("death.attack.$msgId", victim.displayName)
	}

	final override fun getEntity(): Entity? {
		return entity
	}
}

class EMPDamageSource(entity: Entity? = null, inflictor: ItemStack? = null) : MatteryDamageSource(MRegistry.DAMAGE_EMP_NAME, entity, inflictor) {
	init {
		bypassArmor()
		bypassMagic()
	}

	override fun scalesWithDifficulty(): Boolean {
		return false
	}
}

class ExopackDamageSource(entity: Entity? = null, inflictor: ItemStack? = null) : MatteryDamageSource(MRegistry.DAMAGE_EXOPACK_PROBE_ID, entity, inflictor) {
	init {
		bypassArmor()
		bypassMagic()
		bypassEnchantments()
	}

	override fun scalesWithDifficulty(): Boolean {
		return false
	}
}

class CosmicRaysDamageSource(entity: Entity? = null, inflictor: ItemStack? = null) : MatteryDamageSource(MRegistry.DAMAGE_COSMIC_RAYS_NAME, entity, inflictor) {
	init {
		bypassArmor()
		bypassMagic()
		bypassEnchantments()
	}

	override fun scalesWithDifficulty(): Boolean {
		return false
	}
}

class ExplosiveHammerDamageSource(entity: Entity? = null, inflictor: ItemStack? = null) : MatteryDamageSource(MRegistry.DAMAGE_EXPLOSIVE_HAMMER_NAME, entity, inflictor) {
	override fun scalesWithDifficulty(): Boolean {
		return false
	}
}

class ShockwaveDamageSource(entity: Entity? = null, inflictor: ItemStack? = null) : MatteryDamageSource(MRegistry.DAMAGE_SHOCKWAVE_NAME, entity, inflictor) {
	init {
		bypassArmor()
	}

	override fun scalesWithDifficulty(): Boolean {
		return false
	}
}

class PlasmaDamageSource(entity: Entity? = null, inflictor: ItemStack? = null) : MatteryDamageSource(MRegistry.DAMAGE_PLASMA_NAME, entity, inflictor) {
	override fun scalesWithDifficulty(): Boolean {
		return false
	}
}

class HammerNailDamageSource(entity: Entity? = null, inflictor: ItemStack? = null) : MatteryDamageSource(MRegistry.DAMAGE_HAMMER_NAIL_NAME, entity, inflictor) {
	override fun scalesWithDifficulty(): Boolean {
		return false
	}
}
