package de.simolzimol.mclogger.velocity;

import com.google.inject.Inject;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
import de.simolzimol.mclogger.velocity.database.VelocityDatabaseManager;
import de.simolzimol.mclogger.velocity.listeners.VelocityEventListener;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import org.slf4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

/**
 * MCLogger – Velocity Proxy Plugin entry point
 *
 * @author SimolZimol
 * @version 1.0.0
 */
@Plugin(
    id = "mclogger-velocity",
    name = "MCLogger-Velocity",
    version = "1.0.0",
    description = "Comprehensive proxy event logger with MariaDB storage",
    authors = {"SimolZimol"},
    url = "https://github.com/SimolZimol/MCLogger"
)
public class VelocityLoggerPlugin {

    private final ProxyServer server;
    private final Logger logger;
    private final Path dataDirectory;

    private VelocityDatabaseManager db;

    @Inject
    public VelocityLoggerPlugin(ProxyServer server, Logger logger,
                                 @DataDirectory Path dataDirectory) {
        this.server = server;
        this.logger = logger;
        this.dataDirectory = dataDirectory;
    }

    @Subscribe
    public void onInitialize(ProxyInitializeEvent event) {
        // Load configuration
        ConfigurationNode cfg = loadConfig();
        if (cfg == null) {
            logger.error("[MCLogger] Failed to load configuration!");
            return;
        }

        // Database connection
        db = new VelocityDatabaseManager(this);
        if (!db.connect(cfg)) {
            logger.error("[MCLogger] No database connection – plugin inactive.");
            return;
        }

        // Register plugin messaging channel incoming from Paper backends
        server.getChannelRegistrar().register(MinecraftChannelIdentifier.from("mclogger:logged"));

        // Register listeners
        server.getEventManager().register(this, new VelocityEventListener(this));

        // Log proxy start
        Map<String, Object> details = new HashMap<>();
        details.put("velocity_version", server.getVersion().getVersion());
        details.put("max_players", server.getConfiguration().getShowMaxPlayers());
        db.insertProxyEvent("proxy_start", null, null, null, null, null, details);

        logger.info("[MCLogger] Velocity plugin started! Proxy: " + db.getProxyName());
    }

    @Subscribe
    public void onShutdown(ProxyShutdownEvent event) {
        if (db != null && db.isConnected()) {
            Map<String, Object> details = new HashMap<>();
            details.put("online_players", server.getPlayerCount());
            db.insertProxyEvent("proxy_stop", null, null, null, null, null, details);
            try { Thread.sleep(300); } catch (InterruptedException ignored) {}
            db.disconnect();
        }
        logger.info("[MCLogger] Velocity plugin shut down.");
    }

    private ConfigurationNode loadConfig() {
        try {
            if (!Files.exists(dataDirectory)) {
                Files.createDirectories(dataDirectory);
            }
            Path configFile = dataDirectory.resolve("config.yml");
            if (!Files.exists(configFile)) {
                try (InputStream in = getClass().getResourceAsStream("/velocity-config.yml")) {
                    if (in != null) Files.copy(in, configFile);
                }
            }
            YamlConfigurationLoader loader = YamlConfigurationLoader.builder()
                    .path(configFile)
                    .build();
            return loader.load();
        } catch (IOException e) {
            logger.error("[MCLogger] Error loading configuration: " + e.getMessage());
            return null;
        }
    }

    public ProxyServer getServer() { return server; }
    public Logger getLogger() { return logger; }
    public VelocityDatabaseManager getDb() { return db; }
}
