package net.knarcraft.blacksmith;

import net.citizensnpcs.api.CitizensAPI;
import net.knarcraft.blacksmith.command.BlackSmithConfigCommand;
import net.knarcraft.blacksmith.command.BlackSmithConfigTabCompleter;
import net.knarcraft.blacksmith.command.BlackSmithEditCommand;
import net.knarcraft.blacksmith.command.BlackSmithEditTabCompleter;
import net.knarcraft.blacksmith.config.GlobalSettings;
import net.knarcraft.blacksmith.listener.NPCClickListener;
import net.knarcraft.blacksmith.listener.PlayerListener;
import net.knarcraft.blacksmith.manager.EconomyManager;
import net.knarcraft.blacksmith.trait.BlacksmithTrait;
import org.bukkit.command.PluginCommand;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.logging.Level;

/**
 * Blacksmith's main class
 */
public class BlacksmithPlugin extends JavaPlugin {

    private static BlacksmithPlugin instance;
    private GlobalSettings config;

    /**
     * Gets an instance of the Blacksmith plugin
     *
     * @return <p>An instance of the blacksmith plugin</p>
     */
    public static BlacksmithPlugin getInstance() {
        return instance;
    }

    /**
     * Gets settings for the blacksmith plugin
     *
     * @return <p>Settings for the blacksmith plugin</p>
     */
    public GlobalSettings getSettings() {
        return config;
    }

    /**
     * Reloads the configuration file from disk
     */
    public void reload() {
        config.load();
    }

    @Override
    public void onDisable() {
        getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " disabled.");
    }

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

        //Copy default config to disk
        FileConfiguration fileConfiguration = this.getConfig();
        this.saveDefaultConfig();
        fileConfiguration.options().copyDefaults(true);

        //Load settings
        config = new GlobalSettings(this);
        config.load();

        //Set up Vault integration
        if (!setUpVault()) {
            return;
        }

        //Register the blacksmith trait with Citizens
        CitizensAPI.getTraitFactory().registerTrait(
                net.citizensnpcs.api.trait.TraitInfo.create(BlacksmithTrait.class).withName("blacksmith"));

        //Register all commands
        registerCommands();
        //Register all listeners
        registerListeners();

        getLogger().log(Level.INFO, " v" + getDescription().getVersion() + " enabled.");
    }

    /**
     * Tries to set up Vault
     *
     * @return <p>True if Vault setup/integration succeeded</p>
     */
    private boolean setUpVault() {
        getLogger().log(Level.INFO, "Setting Up Vault now....");
        boolean canLoad = EconomyManager.setUp(getServer().getServicesManager(), getLogger());
        if (!canLoad) {
            getLogger().log(Level.SEVERE, "Vault Integration Failed....");
            getServer().getPluginManager().disablePlugin(this);
            return false;
        }
        return true;
    }

    /**
     * Registers all listeners used by this plugin
     */
    private void registerListeners() {
        PluginManager pluginManager = getServer().getPluginManager();
        pluginManager.registerEvents(new PlayerListener(), this);
        pluginManager.registerEvents(new NPCClickListener(), this);
    }

    /**
     * Registers all commands used by this plugin
     */
    private void registerCommands() {
        //Register the blacksmith NPC edit main-command
        PluginCommand blacksmithCommand = this.getCommand("blacksmith");
        if (blacksmithCommand != null) {
            blacksmithCommand.setExecutor(new BlackSmithEditCommand());
            blacksmithCommand.setTabCompleter(new BlackSmithEditTabCompleter());
        }

        //Register the global config edit command
        PluginCommand blacksmithConfigCommand = this.getCommand("blacksmithConfig");
        if (blacksmithConfigCommand != null) {
            blacksmithConfigCommand.setExecutor(new BlackSmithConfigCommand());
            blacksmithConfigCommand.setTabCompleter(new BlackSmithConfigTabCompleter());
        }
    }

}
