package us.talabrek.ultimateskyblock.event;

import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent;
import us.talabrek.ultimateskyblock.uSkyBlock;

import static dk.lockfuglsang.minecraft.po.I18nUtil.tr;

/**
 * This class is handling the event listeners for stopping various exploits.
 */
public class ExploitEvents implements Listener {
    private final uSkyBlock plugin;

    private final boolean visitorVillagerTradingProtected;
    private final boolean usePortals;
    private final boolean mountEnabled;
    private final boolean breakVehicleEnabled;
    private final boolean anyVillagerTradingAllowed;

    public ExploitEvents(uSkyBlock plugin) {
        this.plugin = plugin;
        FileConfiguration config = plugin.getConfig();
        visitorVillagerTradingProtected = config.getBoolean("options.protection.visitors.villager-trading", true);
        anyVillagerTradingAllowed = config.getBoolean("options.protection.villager-trading-enabled", true);
        usePortals = config.getBoolean("options.protection.visitors.use-portals", false);
        mountEnabled = config.getBoolean("options.protection.visitors.vehicle-enter", false);
        breakVehicleEnabled = config.getBoolean("options.protection.visitors.vehicle-break", false);
    }

    @EventHandler(priority = EventPriority.MONITOR)
    public void onPortalEvent(PlayerPortalEvent event) {
        Player player = event.getPlayer();
        if (usePortals || event.getTo() == null ||
                (!plugin.getWorldManager().isSkyAssociatedWorld(event.getTo().getWorld())
                        && !plugin.getWorldManager().isSkyAssociatedWorld(event.getFrom().getWorld())))
        {
            return; // We only care about portals going into or out of skyworld
        }
        if (player.hasPermission("usb.mod.bypassprotection") || plugin.playerIsOnIsland(player) || plugin.playerIsInSpawn(player)) {
            return;
        }
        if (event.getCause() == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL ||
            event.getCause() == PlayerTeleportEvent.TeleportCause.END_PORTAL) {
            us.talabrek.ultimateskyblock.api.IslandInfo islandInfo = plugin.getIslandInfo(player);
            if (islandInfo == null || (!islandInfo.contains(event.getTo()) && !islandInfo.contains(event.getFrom()))) {
                event.setCancelled(true);
                player.sendMessage(tr("\u00a7eYou can not use another island''s portals!"));
            }
        }
    }

    @EventHandler
    public void onVillagerTrade(InventoryOpenEvent event) {
        if (!plugin.getWorldManager().isSkyAssociatedWorld(event.getPlayer().getWorld())) {
            return;
        }
        if (!(event.getPlayer() instanceof Player)) {
            return;
        }
        if (!anyVillagerTradingAllowed && event.getInventory().getType() == InventoryType.MERCHANT) {
            event.setCancelled(true);
            event.getPlayer().sendMessage(tr("\u00a7eVillager-trading isn't allowed."));
            return;
        }
        if (visitorVillagerTradingProtected
                && event.getPlayer() instanceof Player
                && !(event.getPlayer().hasPermission("usb.mod.bypassprotection"))
                && event.getInventory().getType() == InventoryType.MERCHANT
                && !plugin.playerIsOnIsland((Player)event.getPlayer())) {
            event.setCancelled(true);
            event.getPlayer().sendMessage(tr("\u00a7eTrading isn't allowed on other islands. Do it in spawn."));
        }
    }

    @EventHandler
    public void on(VehicleEnterEvent e) {
        if (mountEnabled
                || !(e.getEntered() instanceof Player)
                || !plugin.getWorldManager().isSkyAssociatedWorld(e.getVehicle().getWorld())
        ) {
            return;
        }
        Player player = (Player) e.getEntered();
        if (player.hasPermission("usb.mod.bypassprotection") || plugin.playerIsOnIsland(player)) {
            return;
        }
        e.setCancelled(true);
        player.sendMessage(tr("\u00a7eRiding is only allowed on your own island!"));
    }

    @EventHandler
    public void on(VehicleDamageEvent e) {
        if (breakVehicleEnabled
                || !(e.getAttacker() instanceof Player)
                || !plugin.getWorldManager().isSkyAssociatedWorld(e.getVehicle().getWorld())
        ) {
            return;
        }
        Player player = (Player) e.getAttacker();
        if (player.hasPermission("usb.mod.bypassprotection") || plugin.playerIsOnIsland(player)) {
            return;
        }
        e.setCancelled(true);
        player.sendMessage(tr("\u00a7eYou cannot break vehicles while being a visitor!"));
    }

    @EventHandler
    public void on(VehicleDestroyEvent e) {
        if (breakVehicleEnabled
                || !(e.getAttacker() instanceof Player)
                || !plugin.getWorldManager().isSkyAssociatedWorld(e.getVehicle().getWorld())
        ) {
            return;
        }
        Player player = (Player) e.getAttacker();
        if (player.hasPermission("usb.mod.bypassprotection") || plugin.playerIsOnIsland(player)) {
            return;
        }
        e.setCancelled(true);
        player.sendMessage(tr("\u00a7eYou cannot break vehicles while being a visitor!"));
    }
}