package com.bitnix.dirtcryptostore;

import com.bitnix.dirtcryptostore.command.CryptoStoreCommand;
import com.bitnix.dirtcryptostore.listener.StoreGuiListener;
import com.bitnix.dirtcryptostore.manager.ConfigManager;
import com.bitnix.dirtcryptostore.manager.InvoiceManager;
import com.bitnix.dirtcryptostore.manager.PaymentWatcher;
import com.bitnix.dirtcryptostore.manager.PricingManager;
import com.bitnix.dirtcryptostore.manager.QrMapManager;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;

public final class DirtCryptoStorePlugin extends JavaPlugin {

    private static DirtCryptoStorePlugin instance;

    private ConfigManager configManager;
    private InvoiceManager invoiceManager;
    private PaymentWatcher paymentWatcher;
    private QrMapManager qrMapManager;
    private PricingManager pricingManager;
    private BukkitTask watcherTask;

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

        saveDefaultConfig();

        this.configManager = new ConfigManager(this);
        this.configManager.load();

        this.pricingManager = new PricingManager(this);

        this.invoiceManager = new InvoiceManager(this);
        this.invoiceManager.init();
        this.invoiceManager.load();

        this.qrMapManager = new QrMapManager(this);

        registerCommands();
        registerListeners();
        startWatcher();

        getLogger().info("DirtCryptoStore enabled.");
    }

    @Override
    public void onDisable() {
        if (watcherTask != null) {
            watcherTask.cancel();
            watcherTask = null;
        }

        if (invoiceManager != null) {
            invoiceManager.save();
            invoiceManager.clearAll();
        }

        if (qrMapManager != null) {
            qrMapManager.clearAll();
        }

        if (pricingManager != null) {
            pricingManager.clearCache();
        }

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

    private void registerCommands() {
        PluginCommand command = getCommand("cryptostore");
        if (command == null) {
            getLogger().severe("Command 'cryptostore' is missing from plugin.yml");
            return;
        }

        CryptoStoreCommand cryptoStoreCommand = new CryptoStoreCommand(this);
        command.setExecutor(cryptoStoreCommand);
        command.setTabCompleter(cryptoStoreCommand);
    }

    private void registerListeners() {
        getServer().getPluginManager().registerEvents(new StoreGuiListener(this), this);
    }

    private void startWatcher() {
        this.paymentWatcher = new PaymentWatcher(this);

        long pollSeconds = getConfig().getLong("settings.payment.poll-seconds", 30L);
        long periodTicks = Math.max(20L, pollSeconds * 20L);

        watcherTask = getServer().getScheduler().runTaskTimerAsynchronously(this, paymentWatcher, periodTicks, periodTicks);
    }

    public void reloadPlugin() {
        reloadConfig();

        if (watcherTask != null) {
            watcherTask.cancel();
            watcherTask = null;
        }

        configManager.load();

        if (pricingManager != null) {
            pricingManager.clearCache();
        }

        invoiceManager.load();

        if (qrMapManager != null) {
            qrMapManager.clearAll();
        }

        startWatcher();
    }

    public static DirtCryptoStorePlugin getInstance() {
        return instance;
    }

    public ConfigManager getConfigManager() {
        return configManager;
    }

    public InvoiceManager getInvoiceManager() {
        return invoiceManager;
    }

    public PaymentWatcher getPaymentWatcher() {
        return paymentWatcher;
    }

    public QrMapManager getQrMapManager() {
        return qrMapManager;
    }

    public PricingManager getPricingManager() {
        return pricingManager;
    }
}
