package ru.dbotthepony.mc.otm.mixin;

import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.neoforged.neoforge.event.EventHooks;
import org.jetbrains.annotations.Nullable;
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 ru.dbotthepony.mc.otm.capability.IMatteryPlayer;
import ru.dbotthepony.mc.otm.config.ServerConfig;
import ru.dbotthepony.mc.otm.core.util.ExperienceUtilsKt;
import ru.dbotthepony.mc.otm.registry.game.MItems;

@SuppressWarnings("ConstantConditions")
@Mixin(LivingEntity.class)
public class MixinLivingEntity {
	@Shadow(remap = false)
	@Nullable
	protected Player lastHurtByPlayer;

	@Inject(
		method = "dropExperience(Lnet/minecraft/world/entity/Entity;)V",
		remap = false,
		at = @At("HEAD"),
		cancellable = true)
	public void dropExperience(@Nullable Entity killer, CallbackInfo hook) {
		if (((Object) this) instanceof Player player && ServerConfig.INSTANCE.getDROP_EXPERIENCE_CAPSULES()) {
			hook.cancel();

			var android = ((IMatteryPlayer) player).getOtmPlayer();
			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 = EventHooks.getExperienceDrop(player, lastHurtByPlayer, Integer.MAX_VALUE);

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

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