package com.loganmagnan.eventcore;

import aether.Aether;
import com.loganmagnan.eventcore.managers.*;
import com.loganmagnan.eventcore.managers.event.EventManager;
import com.loganmagnan.eventcore.managers.hotbar.HotBarManager;
import com.loganmagnan.eventcore.managers.mongo.MongoManager;
import com.loganmagnan.eventcore.menusystem.PlayerMenuUtil;
import com.loganmagnan.eventcore.playerdata.PlayerData;
import com.loganmagnan.eventcore.runnables.CooldownRunnable;
import com.loganmagnan.eventcore.scoreboard.ScoreboardProvider;
import com.loganmagnan.eventcore.utils.ClassRegistrationUtils;
import com.loganmagnan.eventcore.utils.ColorUtils;
import com.loganmagnan.eventcore.utils.Constants;
import com.loganmagnan.eventcore.utils.Utils;
import com.loganmagnan.eventcore.utils.command.CommandFramework;
import com.loganmagnan.eventcore.utils.config.FileConfig;
import com.loganmagnan.eventcore.utils.config.file.Config;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

@Getter
@Setter
public class EventCore extends JavaPlugin {

    // Main Class Instance
    @Getter private static EventCore instance;

    // Configuration Files
    private Config mainConfig;
    private FileConfig messagesConfig;

    // Managers
    private MongoManager mongoManager;
    private PlayerDataManager playerDataManager;
    private SpawnManager spawnManager;
    private ChatManager chatManager;
    private CooldownManager cooldownManager;
    private HotBarManager hotBarManager;
    private StaffManager staffManager;
    private EventManager eventManager;

    // Menu System
    private HashMap<Player, PlayerMenuUtil> playerMenuUtilMap = new HashMap<>();

    // Command Framework
    private CommandFramework commandFramework = new CommandFramework(this);

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

        this.saveDefaultConfig();
        this.mainConfig = new Config("config", this);
        this.messagesConfig = new FileConfig(this, "messages.yml");

        new Constants();

        this.getServer().getConsoleSender().sendMessage(Utils.chatBar);
        this.getServer().getConsoleSender().sendMessage(ColorUtils.getMessageType("&dEventCore &7- &av" + this.getDescription().getVersion()));
        this.getServer().getConsoleSender().sendMessage(ColorUtils.getMessageType("&7Made by &eLoganM Development"));
        this.getServer().getConsoleSender().sendMessage(Utils.chatBar);
        this.loadCommands();
        this.loadManagers();
        this.loadListeners();
        this.loadRunnables();
    }

    @Override
    public void onDisable() {
        List<UUID> playersInStaffMode = new ArrayList<UUID>(this.staffManager.getPlayersInStaffMode());

        for (Player player : this.getServer().getOnlinePlayers()) {
            PlayerData playerData = this.playerDataManager.getPlayerData(player.getUniqueId());

            this.playerDataManager.savePlayerData(playerData);
        }

        for (UUID playerInStaffModeUUID : playersInStaffMode) {
            Player playerInStaffMode = this.getServer().getPlayer(playerInStaffModeUUID);

            if (playerInStaffMode == null) {
                continue;
            }

            this.staffManager.setStaffMode(playerInStaffMode, false);
        }

        this.eventManager.saveConfig();
        this.mongoManager.disconnect();

        instance = null;
    }

    private void loadCommands() {
        ClassRegistrationUtils.loadCommands("com.loganmagnan.eventcore.commands");
    }

    private void loadManagers() {
        this.mongoManager = new MongoManager();
        this.playerDataManager = new PlayerDataManager();
        this.spawnManager = new SpawnManager();
        this.chatManager = new ChatManager();
        this.cooldownManager = new CooldownManager();
        this.hotBarManager = new HotBarManager();
        this.staffManager = new StaffManager();
        this.eventManager = new EventManager();
    }

    private void loadListeners() {
        ClassRegistrationUtils.loadListeners("com.loganmagnan.eventcore.listeners");
    }

    private void loadRunnables() {
        new Aether(this, new ScoreboardProvider());

        this.getServer().getScheduler().runTaskTimerAsynchronously(this, new CooldownRunnable(), 0, 20);
    }

    public PlayerMenuUtil getPlayerMenuUtil(Player player) {
        PlayerMenuUtil playerMenuUtil;

        if (playerMenuUtilMap.containsKey(player)) {
            return playerMenuUtilMap.get(player);
        } else {
            playerMenuUtil = new PlayerMenuUtil(player);

            playerMenuUtilMap.put(player, playerMenuUtil);

            return playerMenuUtil;
        }
    }
}
