package eu.mhsl.craftattack.teamLobby;

import eu.mhsl.craftattack.teamLobby.util.ConnectInfo;
import eu.mhsl.craftattack.teamLobby.util.DisconnectInfo;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.timer.TaskSchedule;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

public class Main {
    private static ConfigurationNode config;
    private static LobbyManager lobbyManager;
    public static void main(String[] args) throws ConfigurateException {
        String filename = "config.yml";
        File configFile = new File(filename);

        if (!configFile.exists()) {
            System.out.println("Konfigurationsdatei nicht gefunden. Defaultkonfiguration wird verwendet.");

            try (InputStream in = Main.class.getResourceAsStream("/config.yml")) {
                if (in == null) {
                    throw new FileNotFoundException("Beispielkonfiguration 'config.yml' nicht im Ressourcenpfad gefunden.");
                }

                Files.copy(in, configFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException e) {
                throw new RuntimeException("Fehler beim Kopieren der Beispielkonfiguration: ", e);
            }
        }

        config = YamlConfigurationLoader.builder()
            .path(configFile.toPath())
            .build()
            .load();

        ConfigurationNode serverCfg = config.node("server");

        MinecraftServer server = MinecraftServer.init();
        MinecraftServer.setBrandName("mhsl.eu - TeamLobby");
        MinecraftServer.setCompressionThreshold(serverCfg.node("compressionThreshold").getInt(128));
        System.setProperty("minestom.chunk-view-distance", String.valueOf(serverCfg.node("viewDistance").getInt(12)));

        ConfigurationNode authCfg = config.node("authentication");
        Authentication.Values auth = new Authentication.Values(
            authCfg.node("method").getString(Authentication.Method.NONE.name()),
            authCfg.node("secret").getString()
        );
        Authentication.init(auth);

        MinecraftServer.getGlobalEventHandler().addListener(
            AsyncPlayerConfigurationEvent.class,
            event -> {
                try {
                    Player p = event.getPlayer();
                    System.out.printf("Player %s joined: %s%n", p.getUsername(), p.getUuid());
                    InstanceContainer container = lobbyManager.getPlayerInstance(p);
                    event.setSpawningInstance(container);
                    if(container instanceof Lobby lobby) {
                        p.setRespawnPoint(lobby.spawnPoint);
                        MinecraftServer.getSchedulerManager().scheduleTask(
                            () -> {
                                ConnectInfo.cords(p);
                                ConnectInfo.tickets(lobby.team.name(), p);
                            },
                            TaskSchedule.seconds(1),
                            TaskSchedule.stop()
                        );
                    }
                } catch(Exception e) {
                    new DisconnectInfo(
                        "Login abgelehnt",
                        e.getMessage(),
                        "Wenn das ein Fehler ist, melde dich bitte bei einem Admin!",
                        event.getPlayer().getUuid()
                    ).applyKick(event.getPlayer());
                }
            }
        );

        int port = config.node("server", "port").getInt(25565);
        server.start(new InetSocketAddress("0.0.0.0", port));

        lobbyManager = new LobbyManager();
        System.out.println("Server is running!");
    }

    public static ConfigurationNode getConfig() {
        return config;
    }
}