package dev.micle.loginprotection.proxy;

import dev.micle.loginprotection.LoginProtection;
import dev.micle.loginprotection.data.ProtectedPlayer;
import dev.micle.loginprotection.data.ProtectedPlayerManager;
import dev.micle.loginprotection.events.client.OnClientInputEventHandler;
import dev.micle.loginprotection.events.common.OnLivingSetAttackTargetEventHandler;
import dev.micle.loginprotection.events.common.OnPlayerDamageEventHandler;
import dev.micle.loginprotection.events.common.OnPlayerJoinEventHandler;
import dev.micle.loginprotection.events.common.OnPlayerLeaveEventHandler;
import dev.micle.loginprotection.network.NetworkManager;
import dev.micle.loginprotection.setup.Config;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.AddReloadListenerEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.event.lifecycle.*;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

public class Proxy implements IProxy {
    // Initialize variables
    private static MinecraftServer server = null;

    // Common setup
    public Proxy() {
        // Initialize setup
        Config.init();
        NetworkManager.init();

        // Register mod event bus listeners
        IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
        modEventBus.addListener(Proxy::setup);
        modEventBus.addListener(Proxy::imcEnqueue);
        modEventBus.addListener(Proxy::imcProcess);

        // Register event but listeners
        MinecraftForge.EVENT_BUS.addListener(Proxy::onAddReloadListeners);
        MinecraftForge.EVENT_BUS.addListener(Proxy::serverStarted);
        MinecraftForge.EVENT_BUS.addListener(Proxy::serverStopping);

        // Register event handlers
        MinecraftForge.EVENT_BUS.register(new OnLivingSetAttackTargetEventHandler());
        MinecraftForge.EVENT_BUS.register(new OnPlayerDamageEventHandler());
        MinecraftForge.EVENT_BUS.register(new OnPlayerJoinEventHandler());
        MinecraftForge.EVENT_BUS.register(new OnPlayerLeaveEventHandler());
    }

    private static void setup(FMLCommonSetupEvent event) {}

    private static void imcEnqueue(InterModEnqueueEvent event) {}

    private static void imcProcess(InterModProcessEvent event) {}

    private static void onAddReloadListeners(AddReloadListenerEvent event) {}

    private static void serverStarted(ServerStartedEvent event) {
        ProtectedPlayerManager.init();
        server = event.getServer();
    }

    private static void serverStopping(ServerStoppingEvent event) {
        server = null;
    }

    @Override
    public MinecraftServer getServer() {
        return server;
    }

    @Override
    public Player getClientPlayer() {
        return null;
    }

    @Override
    public Level getClientWorld() {
        return null;
    }

    // Client setup
    public static class Client extends Proxy {
        private static ProtectedPlayer.State playerState;
        private static int lastInputTick;

        public Client() {
            // Register mod event bus listeners
            IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
            modEventBus.addListener(Client::setup);
            modEventBus.addListener(Client::postSetup);

            // Register event handlers
            MinecraftForge.EVENT_BUS.register(new OnClientInputEventHandler());
        }

        private static void setup(FMLClientSetupEvent event) {}

        private static void postSetup(FMLLoadCompleteEvent event) {}

        public static ProtectedPlayer.State getPlayerState() {
            return playerState;
        }

        public static void setPlayerState(ProtectedPlayer.State newPlayerState) {
            playerState = newPlayerState;
        }

        public static int getLastInputTick() {
            return lastInputTick;
        }

        public static void updateLastInputTick() {
            lastInputTick = LoginProtection.getProxy().getClientPlayer().tickCount;
        }

        @Override
        @OnlyIn(Dist.CLIENT)
        public Player getClientPlayer() {
            return Minecraft.getInstance().player;
        }

        @Override
        @OnlyIn(Dist.CLIENT)
        public Level getClientWorld() {
            return Minecraft.getInstance().level;
        }
    }

    // Server setup
    public static class Server extends Proxy {
        public Server() {
            // Register mod event bus listeners
            IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
            modEventBus.addListener(Server::setup);
        }

        private static void setup(FMLDedicatedServerSetupEvent event) {}
    }
}
