package rip.tilly.bedwars.listeners.game;

import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import rip.tilly.bedwars.BedWars;
import rip.tilly.bedwars.game.Game;
import rip.tilly.bedwars.game.GameState;
import rip.tilly.bedwars.game.GameTeam;
import rip.tilly.bedwars.playerdata.PlayerData;
import rip.tilly.bedwars.playerdata.PlayerState;

public class WorldListener implements Listener {

    private final BedWars plugin = BedWars.getInstance();

    private boolean isInGame(PlayerData playerData) {
        return playerData.getPlayerState() == PlayerState.PLAYING;
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
        Player player = event.getPlayer();
        if (player.getGameMode() == GameMode.CREATIVE && player.isOp()) {
            return;
        }

        PlayerData playerData = this.plugin.getPlayerDataManager().getPlayerData(player.getUniqueId());
        if (playerData == null) {
            this.plugin.getLogger().warning(player.getName() + "'s player data is null");
            event.setCancelled(true);
            return;
        }

        if (!this.isInGame(playerData)) {
            event.setCancelled(true);
            return;
        }

        Game game = this.plugin.getGameManager().getGame(player.getUniqueId());
        if (game == null) {
            event.setCancelled(true);
            return;
        }

        if (game.getGameState() != GameState.FIGHTING) {
            event.setCancelled(true);
            return;
        }

        Block block = event.getBlock();
        if (!game.isBreakable(block)) {
            event.setCancelled(true);
            return;
        }

        if (block.getType() == Material.BED_BLOCK) {
            GameTeam playerTeam = game.getTeams().get(playerData.getTeamId());
            if ((playerTeam.getId() == 1 ? game.getCopiedArena().getA().toBukkitLocation() : game.getCopiedArena().getB().toBukkitLocation()).distance(block.getLocation()) < 20) {
                event.setCancelled(true);
                return;
            }

            GameTeam opposingTeam = playerData.getTeamId() == 0 ? game.getTeams().get(1) : game.getTeams().get(0);
            opposingTeam.destroyBed();
            game.broadcastWithSound(playerTeam.getPlayerTeam().getChatColor() + player.getName() + " &ehas destroyed " + opposingTeam.getPlayerTeam().getChatColor() + opposingTeam.getPlayerTeam().getName() + "'s &ebed!", Sound.ENDERDRAGON_GROWL);
            game.broadcastSound(Sound.ENDERDRAGON_GROWL);

            playerData.setGameBedsDestroyed(playerData.getGameBedsDestroyed() + 1);
            playerData.setBedsDestroyed(playerData.getBedsDestroyed() + 1);

            block.getDrops().clear();
            Location location = block.getLocation();
            World world = location.getWorld();
            world.playEffect(location, Effect.CRIT, 1, 400);
            world.playEffect(location, Effect.FLAME, 1, 400);
            world.playEffect(location, Effect.MOBSPAWNER_FLAMES, 1, 400);
            world.playEffect(location, Effect.PARTICLE_SMOKE, 1, 400);
            world.playEffect(location, Effect.VILLAGER_THUNDERCLOUD, 1, 400);
            world.playEffect(location, Effect.LARGE_SMOKE, 1, 400);
            world.playEffect(location, Effect.SMOKE, 1, 400);
            world.playEffect(location, Effect.PARTICLE_SMOKE, 1, 400);
            return;
        }

        player.getInventory().addItem(block.getDrops().toArray(new ItemStack[0]));
        game.removePlacedBlock(block);
        block.setType(Material.AIR);
    }

    @EventHandler
    public void onBlockPlace(BlockPlaceEvent event) {
        Player player = event.getPlayer();
        if (player.getGameMode() == GameMode.CREATIVE && player.isOp()) {
            return;
        }

        PlayerData playerData = this.plugin.getPlayerDataManager().getPlayerData(player.getUniqueId());
        if (playerData == null) {
            this.plugin.getLogger().warning(player.getName() + "'s player data is null");
            event.setCancelled(true);
            return;
        }

        if (!this.isInGame(playerData)) {
            event.setCancelled(true);
            return;
        }

        Game game = this.plugin.getGameManager().getGame(player.getUniqueId());
        if (game == null) {
            event.setCancelled(true);
            return;
        }

        if (game.getGameState() != GameState.FIGHTING) {
            event.setCancelled(true);
            return;
        }

        Block block = event.getBlock();
        if (block.getLocation().getBlockY() >= game.getArena().getBuildMax()) {
            event.setCancelled(true);
            return;
        }

        if (!game.isPlaceable(block.getLocation(), game)) {
            event.setCancelled(true);
            return;
        }

        if (game.isInside(block.getLocation(), game)) {
            event.setCancelled(true);
            return;
        }

        game.addPlacedBlock(block);
    }
}
