package top.r3944realms.lib39.mixin.init;

import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.platform.WindowEventHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.server.Services;
import net.minecraft.server.WorldStem;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.util.thread.ReentrantBlockableEventLoop;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraftforge.common.MinecraftForge;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import top.r3944realms.lib39.api.event.MinecraftSetUpServiceEvent;

/**
 * The type Mixin minecraft.
 */
@Mixin(Minecraft.class)
public abstract class MixinMinecraft extends ReentrantBlockableEventLoop<Runnable> implements WindowEventHandler, net.minecraftforge.client.extensions.IForgeMinecraft {
    /**
     * Instantiates a new Mixin minecraft.
     *
     * @param name the name
     */
    public MixinMinecraft(String name) {
        super(name);
    }

    /**
     * Set level setup.
     *
     * @param levelClient the level client
     * @param ci          the ci
     * @param services    the services
     */
    @Inject(
            method = "setLevel",
            at = @At(
                    value = "INVOKE",
                    target = "Lnet/minecraft/server/players/GameProfileCache;setUsesAuthentication(Z)V",
                    shift = At.Shift.AFTER
            )
    )
    public void setLevel$setup(ClientLevel levelClient, CallbackInfo ci,
                               @Local(ordinal = 0) Services services) {
        MinecraftForge.EVENT_BUS.post(new MinecraftSetUpServiceEvent(services,this));
    }

    /**
     * Do world load setup.
     *
     * @param levelId        the level id
     * @param level          the level
     * @param packRepository the pack repository
     * @param worldStem      the world stem
     * @param newWorld       the new world
     * @param ci             the ci
     * @param services       the services
     */
    @Inject(
            method = "doWorldLoad",
            at = @At(
                    value = "INVOKE",
                    target = "Lnet/minecraft/server/players/GameProfileCache;setUsesAuthentication(Z)V",
                    shift = At.Shift.AFTER
            )
    )
    public void doWorldLoad$setup(String levelId, LevelStorageSource.LevelStorageAccess level, PackRepository packRepository, WorldStem worldStem, boolean newWorld, CallbackInfo ci,
                                  @Local(ordinal = 0) Services services) {
        MinecraftForge.EVENT_BUS.post(new MinecraftSetUpServiceEvent(services,this));
    }
}

