package dev._2lstudios.exploitfixer.bukkit;

import java.util.logging.Logger;

import org.bukkit.Server;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;

import dev._2lstudios.exploitfixer.bukkit.commands.ExploitFixerCommand;
import dev._2lstudios.exploitfixer.bukkit.listener.hamsterapi.HamsterAPIListenerInitializer;
import dev._2lstudios.exploitfixer.bukkit.listener.ListenerInitializer;
import dev._2lstudios.exploitfixer.bukkit.managers.ExploitPlayerManager;
import dev._2lstudios.exploitfixer.bukkit.managers.ModuleManager;
import dev._2lstudios.exploitfixer.bukkit.utils.ConfigurationUtil;
import dev._2lstudios.exploitfixer.bukkit.utils.VersionUtil;

public class ExploitFixer extends JavaPlugin {
	private static ExploitFixer exploitFixer;
	private ConfigurationUtil configurationUtil;
	private ModuleManager moduleManager;
	private ListenerInitializer listenerInitializer;
	private HamsterAPIListenerInitializer hamsterAPIListenerInitializer;

	@Override
	public void onEnable() {
		final Server server = this.getServer();
		final BukkitScheduler scheduler = server.getScheduler();

		this.configurationUtil = new ConfigurationUtil(this);

		createConfigurations();

		final YamlConfiguration configYml = this.configurationUtil.getConfiguration("%datafolder%/config.yml");
		final YamlConfiguration messagesYml = this.configurationUtil.getConfiguration("%datafolder%/messages.yml");

		VersionUtil.initialize(server);

		exploitFixer = this;
		this.moduleManager = new ModuleManager(this, configYml, messagesYml);
		this.listenerInitializer = new ListenerInitializer(this, moduleManager);

		registerListeners();
		registerCommands();

		if (checkHamsterAPI()) {
			server.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");

			this.hamsterAPIListenerInitializer = new HamsterAPIListenerInitializer(this, moduleManager);

			registerHamsterApi();
		} else {
			scheduler.runTaskTimer(this, () -> this.getLogger().severe(
					"ExploitFixer requires HamsterAPI 0.0.8 or newer to work! Download: https://www.spigotmc.org/resources/78831/"),
					20L, 20L);
		}

		scheduler.runTaskTimerAsynchronously(this, () -> {
			final ExploitPlayerManager exploitPlayerManager = moduleManager.getExploitPlayerManager();

			exploitPlayerManager.clear();
		}, 9000L, 9000L);
	}

	@Override
	public void onDisable() {
		final Server server = this.getServer();
		final BukkitScheduler scheduler = server.getScheduler();

		scheduler.cancelTasks(this);

		this.listenerInitializer.unregister();

		if (checkHamsterAPI()) {
			this.hamsterAPIListenerInitializer.unregister();
		}
	}

	public void reload() {
		final Server server = getServer();

		server.getMessenger().unregisterIncomingPluginChannel(this);

		createConfigurations();

		final YamlConfiguration configYml = this.configurationUtil.getConfiguration("%datafolder%/config.yml");
		final YamlConfiguration messagesYml = this.configurationUtil.getConfiguration("%datafolder%/messages.yml");
		final YamlConfiguration spigotYml = this.configurationUtil.getConfiguration("%datafolder%/../spigot.yml");

		moduleManager.reload(configYml, messagesYml, spigotYml);

		registerCommands();
		registerListeners();

		if (checkHamsterAPI()) {
			registerHamsterApi();
		}
	}

	private boolean checkHamsterAPI() {
		final Server server = this.getServer();
		final PluginManager pluginManager = server.getPluginManager();

		if (pluginManager.isPluginEnabled("HamsterAPI")) {
			return (Integer
					.valueOf(pluginManager.getPlugin("HamsterAPI").getDescription().getVersion().replace(".", "")) > 7);
		} else {
			return false;
		}
	}

	private void createConfigurations() {
		this.configurationUtil.createConfiguration("%datafolder%/config.yml");
		this.configurationUtil.createConfiguration("%datafolder%/messages.yml");
	}

	private void registerListeners() {
		final Logger logger = this.getLogger();

		if (this.listenerInitializer.isRegistered()) {
			this.listenerInitializer.unregister();
		}

		this.listenerInitializer.register();

		logger.info("Successfully registered listeners!");
	}

	private void registerHamsterApi() {
		final Logger logger = this.getLogger();

		if (this.hamsterAPIListenerInitializer.isRegistered()) {
			this.hamsterAPIListenerInitializer.unregister();
		}

		this.hamsterAPIListenerInitializer.register();

		logger.info("Successfully hooked with HamsterAPI!");
	}

	private void registerCommands() {
		getCommand("exploitfixer").setExecutor(new ExploitFixerCommand(moduleManager, checkHamsterAPI()));
	}

	public static ExploitFixer getInstance() {
		return exploitFixer;
	}
}