package nl.sbdeveloper.themeparkplus;

import club.minnced.discord.webhook.WebhookClient;
import club.minnced.discord.webhook.WebhookClientBuilder;
import net.milkbowl.vault.economy.Economy;
import nl.sbdeveloper.themeparkplus.commands.TPPCMD;
import nl.sbdeveloper.themeparkplus.listeners.*;
import nl.sbdeveloper.themeparkplus.managers.DBManager;
import nl.sbdeveloper.themeparkplus.sbutils.UpdateManager;
import nl.sbdeveloper.themeparkplus.sbutils.Verify;
import nl.sbdeveloper.themeparkplus.sbutils.YamlFile;
import nl.sbdeveloper.themeparkplus.util.Inventory;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;

import java.sql.SQLException;

public final class ThemeParkPlus extends JavaPlugin {
    private static ThemeParkPlus instance;
    private static YamlFile config;
    private static DBManager data;
    private static YamlFile messages;

    private static Economy econ = null;
    private static WebhookClient webhookClient;

    private static boolean hasParkHook = false;

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

        getLogger().info("-------------------------------");
        getLogger().info("ThemeParkPlus v" + this.getDescription().getVersion());
        getLogger().info("Made by SBDeveloper");

        getLogger().info(" ");

        getLogger().info("Loading Files...");

        config = new YamlFile("config");
        config.loadDefaults();

        data = new DBManager("data");

        messages = new YamlFile("messages");
        messages.loadDefaults();

        getLogger().info("This copy is bought by %%__USERNAME__%% (%%__USER__%%).");
        getLogger().info("Validating your purchase...");
        Verify v = new Verify(this);
        if (v.isValidated()) {
            getLogger().info("Your purchase is valid. Thanks for your purchase!");
        }

        if (Bukkit.getPluginManager().getPlugin("WorldEdit") == null) {
            getLogger().severe("Missing WorldEdit! Please install it first.");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }

        if (Bukkit.getPluginManager().getPlugin("WorldGuard") == null) {
            getLogger().severe("Missing WorldGuard! Please install it first.");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }

        if (!setupEconomy()) {
            getLogger().severe("Missing Vault! Please install it first.");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }

        getLogger().info("Loading commands...");
        getCommand("themeparkplus").setExecutor(new TPPCMD());

        getLogger().info("Loading listeners...");
        Bukkit.getPluginManager().registerEvents(new DirectionalGateListener(), this);
        Bukkit.getPluginManager().registerEvents(new SignListeners(), this);
        Bukkit.getPluginManager().registerEvents(new WaitingTimeListener(), this);
        if (getSConfig().getFile().getBoolean("AntiFreerun.Enabled")) {
            Bukkit.getPluginManager().registerEvents(new AntiFreerunListener(), this);
        }

        if (Bukkit.getPluginManager().getPlugin("ThemePark") == null && Bukkit.getPluginManager().getPlugin("ParkPlusMC") == null) {
            getLogger().severe("ThemePark or ParkPlusMC not found! Some functions will not work without it!");
        } else if (Bukkit.getPluginManager().getPlugin("ThemePark") != null) {
            getLogger().info("Enabling ThemePark hook...");
            hasParkHook = true;
        } else if (Bukkit.getPluginManager().getPlugin("ParkPlusMC") != null) {
            getLogger().info("Enabling ParkPlusMC hook...");
            hasParkHook = true;
        }

        if (hasParkHook) {
            Bukkit.getPluginManager().registerEvents(new FastpassListeners(), this);
            Bukkit.getPluginManager().registerEvents(new MalfunctionListener(), this);

            if (getSConfig().getFile().getBoolean("DiscordWebhook.Enabled")) {
                String URL = getSConfig().getFile().getString("DiscordWebhook.WebhookURL");
                if (URL != null) {
                    Bukkit.getPluginManager().registerEvents(new StatusChangeListener(), this);

                    getLogger().info("Loading Discord webhook...");
                    WebhookClientBuilder builder = new WebhookClientBuilder(URL);
                    builder.setThreadFactory(job -> {
                        Thread thread = new Thread(job);
                        thread.setName("ThemeParkPlus");
                        thread.setDaemon(true);
                        return thread;
                    });
                    builder.setWait(true);
                    webhookClient = builder.build();
                } else {
                    getLogger().severe("Couldn't load the webhook builder! The URL is null.");
                }
            }
        }

        getLogger().info("Loading GUI helper...");
        Inventory.init(this);

        getLogger().info("Loading data...");
        try {
            data.load();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        getLogger().info("Loading metrics (can be disabled in the config of bStats)...");
        new Metrics(this, 5023);

        if (getSConfig().getFile().getBoolean("UpdateChecker")) {
            UpdateManager updateManager = new UpdateManager(this, UpdateManager.CheckType.POLYMART_PAID);

            updateManager.handleResponse((versionResponse, version) -> {
                switch (versionResponse) {
                    case FOUND_NEW:
                        getLogger().warning("There is a new version available! Current: " + this.getDescription().getVersion() + " New: " + version.get());
                        break;
                    case LATEST:
                        getLogger().info("You are running the latest version [" + this.getDescription().getVersion() + "]!");
                        break;
                    case THIS_NEWER:
                        getLogger().info("You are running a newer version [" + this.getDescription().getVersion() + "]! This is probably fine.");
                        break;
                    case UNAVAILABLE:
                        getLogger().severe("Unable to perform an update check.");
                        break;
                }
            }).check();
        }

        getLogger().info("Plugin enabled!");
        getLogger().info("-------------------------------");
    }

    @Override
    public void onDisable() {
        getLogger().info("Saving data...");
        data.save();
        data.closeConnection();

        getLogger().info("Plugin disabled!");
        instance = null;
    }

    public static ThemeParkPlus getInstance() {
        return instance;
    }

    public static YamlFile getSConfig() {
        return config;
    }

    public static DBManager getData() {
        return data;
    }

    public static YamlFile getMessages() {
        return messages;
    }

    public static Economy getEconomy() {
        return econ;
    }

    public static WebhookClient getWebhookClient() {
        return webhookClient;
    }

    public static boolean hasParkHook() {
        return hasParkHook;
    }

    private boolean setupEconomy() {
        if (getServer().getPluginManager().getPlugin("Vault") == null) {
            return false;
        }
        RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
        if (rsp == null) {
            return false;
        }
        econ = rsp.getProvider();
        return econ != null;
    }
}
