package rip.tilly.bedwars;

import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import rip.tilly.bedwars.game.Game;
import rip.tilly.bedwars.listeners.game.*;
import rip.tilly.bedwars.listeners.*;
import rip.tilly.bedwars.managers.CommandManager;
import rip.tilly.bedwars.managers.GameManager;
import rip.tilly.bedwars.managers.PlayerDataManager;
import rip.tilly.bedwars.managers.SpawnManager;
import rip.tilly.bedwars.managers.arena.ArenaManager;
import rip.tilly.bedwars.managers.arena.chunk.ChunkClearingManager;
import rip.tilly.bedwars.managers.arena.chunk.ChunkManager;
import rip.tilly.bedwars.managers.hotbar.HotbarManager;
import rip.tilly.bedwars.managers.mongo.MongoManager;
import rip.tilly.bedwars.managers.party.PartyManager;
import rip.tilly.bedwars.managers.queue.QueueManager;
import rip.tilly.bedwars.menusystem.PlayerMenuUtil;
import rip.tilly.bedwars.providers.scoreboard.ScoreboardProvider;
import rip.tilly.bedwars.utils.CC;
import rip.tilly.bedwars.utils.assemble.Assemble;
import rip.tilly.bedwars.utils.assemble.AssembleStyle;
import rip.tilly.bedwars.utils.config.file.Config;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by Lucanius & Trixkz
 * Project: BedWars
 */
@Getter
public final class BedWars extends JavaPlugin {

    @Getter private static BedWars instance;

    private Config mainConfig, arenasConfig;

    private MongoManager mongoManager;
    private ChunkClearingManager chunkClearingManager;
    private PlayerDataManager playerDataManager;
    private SpawnManager spawnManager;
    private ArenaManager arenaManager;
    private ChunkManager chunkManager;
    private HotbarManager hotbarManager;
    private CommandManager commandManager;
    private GameManager gameManager;
    private PartyManager partyManager;
    private QueueManager queueManager;

    private final HashMap<Player, PlayerMenuUtil> playerMenuUtilMap = new HashMap<Player, PlayerMenuUtil>();

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

        this.saveDefaultConfig();

        this.mainConfig = new Config("config", this);
        this.arenasConfig = new Config("arenas", this);

        Bukkit.getConsoleSender().sendMessage("------------------------------------------------");
        Bukkit.getConsoleSender().sendMessage(CC.translate("&dBedWars &8- &av" + getDescription().getVersion()));
        Bukkit.getConsoleSender().sendMessage(CC.translate("&7Made on &dTilly RIP &7by &eTrixkz &7& &eLucanius"));
        Bukkit.getConsoleSender().sendMessage("------------------------------------------------");

        this.loadManagers();
        this.loadListeners();

        Assemble assemble = new Assemble(this, new ScoreboardProvider());
        assemble.setTicks(2);
        assemble.setAssembleStyle(AssembleStyle.VIPER);

        for (World world : Bukkit.getWorlds()) {
            for (Entity entity : world.getEntities()) {
                if (entity.getType() != EntityType.PLAYER && entity.getType() != EntityType.ITEM_FRAME) {
                    entity.remove();
                }
            }

            world.setGameRuleValue("doDaylightCycle", "false");
            world.setTime(0L);
            world.setStorm(false);
        }
    }

    @Override
    public void onDisable() {
        instance = null;

        for (Map.Entry<UUID, Game> entry : this.gameManager.getGames().entrySet()) {
            Game game = entry.getValue();
            this.chunkClearingManager.resetArena(game.getCopiedArena());
        }

        for (World world : Bukkit.getWorlds()) {
            for (Entity entity : world.getEntities()) {
                if (entity.getType() == EntityType.DROPPED_ITEM) {
                    entity.remove();
                }
            }
            for (Chunk chunk : world.getLoadedChunks()) {
                chunk.unload(true);
            }
        }

        this.mongoManager.disconnect();
    }

    private void loadManagers() {
        this.mongoManager = new MongoManager();
        this.chunkClearingManager = new ChunkClearingManager();
        this.playerDataManager = new PlayerDataManager();
        this.spawnManager = new SpawnManager();
        this.arenaManager = new ArenaManager();
        this.chunkManager = new ChunkManager();
        this.hotbarManager = new HotbarManager();
        this.commandManager = new CommandManager();
        this.gameManager = new GameManager();
        this.partyManager = new PartyManager();
        this.queueManager = new QueueManager();
    }

    private void loadListeners() {
        Arrays.asList(
                new PlayerDataListener(), new RandomListeners(), new InteractListener(), new ButtonListener(), new MenuListener(),
                new GameStartListener(), new GameEndListener(), new WorldListener(), new MovementListener(),
                new PlayerKillListener()
        ).forEach(listener -> this.getServer().getPluginManager().registerEvents(listener, this));
    }

    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;
        }
    }
}
