package de.simolzimol.mclogger.paper;

import de.simolzimol.mclogger.paper.commands.MCLoggerCommand;
import de.simolzimol.mclogger.paper.database.DatabaseManager;
import de.simolzimol.mclogger.paper.listeners.*;
import net.luckperms.api.LuckPerms;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

/**
 * MCLogger – Paper Plugin entry point
 *
 * @author SimolZimol
 * @version 1.0.0
 */
public class PaperLoggerPlugin extends JavaPlugin {

    private static PaperLoggerPlugin instance;
    private DatabaseManager db;

    @Override
    public void onEnable() {
        instance = this;

        saveDefaultConfig();

        // Establish database connection
        db = new DatabaseManager(this);
        if (!db.connect()) {
            getLogger().severe("[MCLogger] Could not connect to database – disabling plugin.");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }

        // Register plugin messaging channel towards the Velocity proxy
        getServer().getMessenger().registerOutgoingPluginChannel(this, "mclogger:logged");

        // Register all listeners
        registerListeners();

        // LuckPerms listener (soft-depend)
        registerLuckPermsListener();

        // Register /mclogger command
        MCLoggerCommand cmdHandler = new MCLoggerCommand(this);
        PluginCommand cmd = getCommand("mclogger");
        if (cmd != null) {
            cmd.setExecutor(cmdHandler);
            cmd.setTabCompleter(cmdHandler);
        }

        // Server-Start Event loggen
        Map<String, Object> details = new HashMap<>();
        details.put("version", getServer().getVersion());
        details.put("bukkit_version", getServer().getBukkitVersion());
        details.put("online_mode", getServer().getOnlineMode());
        details.put("max_players", getServer().getMaxPlayers());
        db.insertServerEvent("server_start", "Server started", details);

        getLogger().info("[MCLogger] started successfully! Server: " + db.getServerName());
    }

    @Override
    public void onDisable() {
        if (db != null) {
            Map<String, Object> details = new HashMap<>();
            details.put("online_players", getServer().getOnlinePlayers().size());
            db.insertServerEvent("server_stop", "Server stopping", details);
            // Short delay to let async tasks finish
            try { Thread.sleep(500); } catch (InterruptedException ignored) {}
            db.disconnect();
        }
        getLogger().info("[MCLogger] disabled.");
    }

    private void registerListeners() {
        PluginManager pm = getServer().getPluginManager();
        pm.registerEvents(new PlayerSessionListener(this), this);
        pm.registerEvents(new PlayerChatCommandListener(this), this);
        pm.registerEvents(new PlayerDeathListener(this), this);
        pm.registerEvents(new PlayerMiscListener(this), this);
        pm.registerEvents(new BlockListener(this), this);
        pm.registerEvents(new EntityListener(this), this);
        pm.registerEvents(new InventoryListener(this), this);
        pm.registerEvents(new WorldListener(this), this);
        getLogger().info("[MCLogger] All listeners registered.");
    }

    /**
     * Registers the LuckPerms listener only if LuckPerms is actually loaded (softdepend).
     */
    private void registerLuckPermsListener() {
        if (getServer().getPluginManager().getPlugin("LuckPerms") == null) {
            getLogger().info("[MCLogger] LuckPerms not found – permission logging disabled.");
            return;
        }
        try {
            RegisteredServiceProvider<LuckPerms> provider =
                    getServer().getServicesManager().getRegistration(LuckPerms.class);
            if (provider != null) {
                new LuckPermsListener(this, provider.getProvider());
            } else {
                getLogger().warning("[MCLogger] LuckPerms service not available.");
            }
        } catch (Exception e) {
            getLogger().log(Level.WARNING, "[MCLogger] Error registering LuckPerms listener.", e);
        }
    }

    public static PaperLoggerPlugin getInstance() { return instance; }
    public DatabaseManager getDb() { return db; }
}
