package fr.luc.gamingcore;

import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import fr.luc.gamingcore.database.DatabaseManager;
import fr.luc.gamingcore.database.GuildRepository;
import fr.luc.gamingcore.economy.EconomyManager;
import fr.luc.gamingcore.listener.TerritoryProtectionListener;
import fr.luc.gamingcore.manager.GuildManager;
import fr.luc.gamingcore.util.TextUtil;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;

/**
 * Classe principale et point d'entrée du plugin GamingCore (Système de Guilde).
 */
public final class Main extends JavaPlugin {

    private static Main instance;

    private Economy economy;
    private RegionContainer regionContainer;

    private DatabaseManager databaseManager;
    private GuildRepository guildRepository;
    private EconomyManager economyManager;
    private GuildManager guildManager;

    /**
     * Méthode appelée lors de l'activation du plugin par le serveur Minecraft.
     */
    @Override
    public void onEnable() {
        instance = this;
        saveDefaultConfig();

        // 1. Initialiser le préfixe de texte MiniMessage
        TextUtil.setPrefix(getConfig().getString("prefix", "<gradient:#00C9FF:#92FE9D>[Guilde]</gradient> <dark_gray>»</dark_gray> <gray>"));

        // 2. Initialiser les hooks externes
        setupWorldGuard();
        setupEconomy();

        // 3. Initialiser la couche de données SQLite
        this.databaseManager = new DatabaseManager(this);
        this.databaseManager.initialize();
        this.guildRepository = new GuildRepository(this, databaseManager);

        // 4. Initialiser la couche économique
        this.economyManager = new EconomyManager(this);

        // 5. Initialiser le service métier GuildManager et charger les données
        this.guildManager = new GuildManager(this, guildRepository, economyManager);
        this.guildManager.loadData();

        // 6. Enregistrer les écouteurs d'événements
        PluginManager pm = getServer().getPluginManager();
        pm.registerEvents(new TerritoryProtectionListener(guildManager), this);

        getLogger().info("GamingCore (Système de Guilde - Cœur Métier) a ete active avec succes !");
    }

    /**
     * Méthode appelée lors de la désactivation du plugin.
     */
    @Override
    public void onDisable() {
        if (guildManager != null) {
            guildManager.shutdown();
        }
        if (databaseManager != null) {
            databaseManager.close();
        }

        getLogger().info("GamingCore a ete desactive !");
    }

    /**
     * Initialise la connexion vers l'API WorldGuard 7 si disponible.
     */
    private void setupWorldGuard() {
        try {
            this.regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer();
            getLogger().info("Connexion avec WorldGuard 7 etablie avec succes !");
        } catch (Throwable t) {
            getLogger().warning("WorldGuard non disponible ou erreur d'initialisation : " + t.getMessage());
        }
    }

    /**
     * Enregistre le fournisseur d'économie Vault.
     */
    private void setupEconomy() {
        if (getServer().getPluginManager().getPlugin("Vault") == null) {
            getLogger().warning("Vault n'a pas ete detecte ! Les fonctionnalites payantes seront desactivees.");
            return;
        }

        RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
        if (rsp == null) {
            getLogger().warning("Aucun provider d'economie trouve via Vault (ex: EssentialsX, TheNewEconomy) !");
            return;
        }

        this.economy = rsp.getProvider();
        getLogger().info("Connexion avec l'economie Vault (" + economy.getName() + ") etablie avec succes !");
    }

    /**
     * Obtient l'instance Singleton de la classe principale.
     *
     * @return L'instance unique de Main.
     */
    public static Main getInstance() {
        return instance;
    }

    /**
     * Obtient le fournisseur d'économie Vault.
     *
     * @return L'instance Economy.
     */
    public Economy getEconomy() {
        return economy;
    }

    /**
     * Indique si un service d'économie est actif.
     *
     * @return true si economy != null.
     */
    public boolean hasEconomy() {
        return economy != null;
    }

    /**
     * Obtient le conteneur de régions WorldGuard.
     *
     * @return L'instance RegionContainer.
     */
    public RegionContainer getRegionContainer() {
        return regionContainer;
    }

    /**
     * Obtient le gestionnaire de base de données.
     *
     * @return L'instance DatabaseManager.
     */
    public DatabaseManager getDatabaseManager() {
        return databaseManager;
    }

    /**
     * Obtient le référentiel de persistance des guildes.
     *
     * @return L'instance GuildRepository.
     */
    public GuildRepository getGuildRepository() {
        return guildRepository;
    }

    /**
     * Obtient le gestionnaire d'économie interne.
     *
     * @return L'instance EconomyManager.
     */
    public EconomyManager getEconomyManager() {
        return economyManager;
    }

    /**
     * Obtient le service métier central de gestion des guildes.
     *
     * @return L'instance GuildManager.
     */
    public GuildManager getGuildManager() {
        return guildManager;
    }
}
