package ru.dbotthepony.mc.otm.mixin;

import com.mojang.authlib.GameProfile;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
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.IMatteryPlayer;
import ru.dbotthepony.mc.otm.capability.MatteryPlayer;

import java.util.Objects;

@Mixin(Player.class)
public class MixinPlayer implements IMatteryPlayer {
	private Player otmSelf() {
		return (Player) (Object) this;
	}

	@Inject(
		method = "getProjectile(Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;",
		remap = false,
		at = @At(
			value = "INVOKE",
			target = "Lnet/neoforged/neoforge/common/CommonHooks;getProjectile(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;",
			ordinal = 2,
			shift = At.Shift.BEFORE,
			remap = false
		),
		cancellable = true)
	private void exosuitGetProjectileHook(ItemStack weaponItem, CallbackInfoReturnable<ItemStack> hook) {
		ItemStack result = MatteryPlayer.getProjectileHook(otmSelf(), weaponItem);

		if (result != null) {
			hook.setReturnValue(result);
		}
	}

	@Inject(
		method = "destroyVanishingCursedItems()V",
		remap = false,
		at = @At("TAIL")
	)
	private void destroyVanishingCursedItems(CallbackInfo ci) {
		MatteryPlayer.playerDestroyVanishingCursedItems(otmSelf());
	}

	private MatteryPlayer otmPlayer;

	@Inject(
		method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;FLcom/mojang/authlib/GameProfile;)V",
		remap = false,
		at = @At("TAIL")
	)
	private void constructOtmPlayer(Level p_250508_, BlockPos p_250289_, float p_251702_, GameProfile p_252153_, CallbackInfo ci) {
		otmPlayer = new MatteryPlayer(otmSelf());
	}

	@NotNull
	@Override
	public MatteryPlayer getOtmPlayer() {
		return Objects.requireNonNull(otmPlayer, "Something went horribly wrong, otmPlayer is null");
	}

	@Inject(
		method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V",
		remap = false,
		at = @At("TAIL")
	)
	private void addAdditionalSaveData(CompoundTag data, CallbackInfo ci) {
		data.put("overdrive_that_matters_player", otmPlayer.serializeNBT(otmSelf().registryAccess()));
	}

	@Inject(
		method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V",
		remap = false,
		at = @At("TAIL")
	)
	private void readAdditionalSaveData(CompoundTag data, CallbackInfo ci) {
		otmPlayer.deserializeNBT(data.getCompound("overdrive_that_matters_player"), otmSelf().registryAccess());
	}
}
