package ru.dbotthepony.mc.otm.mixin;

import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.event.ForgeEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.config.ServerConfig;
import ru.dbotthepony.mc.otm.core.util.ExperienceUtilsKt;
import ru.dbotthepony.mc.otm.registry.MItems;

@SuppressWarnings("ConstantConditions")
@Mixin(LivingEntity.class)
public class MixinLivingEntity {
	@Inject(
		method = "canFreeze()Z",
		at = @At("HEAD"),
		cancellable = true)
	public void canFreeze(CallbackInfoReturnable<Boolean> hook) {
		if (((Object) this) instanceof LivingEntity entity) {
			boolean flag =
				entity.getItemBySlot(EquipmentSlot.HEAD).is(MItems.INSTANCE.getTRITANIUM_HELMET()) &&
				entity.getItemBySlot(EquipmentSlot.CHEST).is(MItems.INSTANCE.getTRITANIUM_CHESTPLATE()) &&
				entity.getItemBySlot(EquipmentSlot.LEGS).is(MItems.INSTANCE.getTRITANIUM_PANTS()) &&
				entity.getItemBySlot(EquipmentSlot.FEET).is(MItems.INSTANCE.getTRITANIUM_BOOTS())
				;

			if (flag)
				hook.setReturnValue(false);
		}
	}

	@Shadow
	protected Player lastHurtByPlayer;

	@Inject(
		method = "dropExperience()V",
		at = @At("HEAD"),
		cancellable = true)
	public void dropExperience(CallbackInfo hook) {
		if (((Object) this) instanceof Player player && ServerConfig.INSTANCE.getDROP_EXPERIENCE_CAPSULES()) {
			player.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresent(it -> {
				hook.cancel();

				long totalExperience = ExperienceUtilsKt.getTotalXpRequiredForLevel(player.experienceLevel);
				totalExperience += (long) (player.experienceProgress * player.getXpNeededForNextLevel());

				double min = ServerConfig.INSTANCE.getMIN_EXPERIENCE_DROPPED();
				double max = ServerConfig.INSTANCE.getMAX_EXPERIENCE_DROPPED();

				if (min == max) {
					totalExperience *= min;
				} else {
					if (min > max) {
						min = 0.4;
						max = 0.8;
					}

					totalExperience *= min + player.getRandom().nextDouble() * (max - min);
				}

				if (totalExperience >= Integer.MAX_VALUE) {
					int hooked = ForgeEventFactory.getExperienceDrop(player, lastHurtByPlayer, Integer.MAX_VALUE);

					if (hooked != Integer.MAX_VALUE) {
						totalExperience = hooked;
					}
				} else {
					totalExperience = ForgeEventFactory.getExperienceDrop(player, lastHurtByPlayer, (int) totalExperience);
				}

				if (totalExperience > 0L) {
					if (it.isAndroid()) {
						player.drop(MItems.INSTANCE.getESSENCE_DRIVE().make(totalExperience), true, false);
					} else {
						player.drop(MItems.INSTANCE.getESSENCE_CAPSULE().make(totalExperience), true, false);
					}
				}
			});
		}
	}
}
