package com.spaceshipproject;

import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;

/**
 * Gere les interactions avec la telecommande boussole.
 *
 *  - Clic gauche
 *      - ship non charge          -> invoquer
 *      - ship charge && joueur PAS dessus -> decharger (sauvegarde les modifications)
 *      - ship charge && joueur dessus     -> rien (utilise clic droit pour redescendre)
 *
 *  - Clic droit
 *      - ship non charge          -> invoquer puis teleporter
 *      - ship charge && joueur PAS dessus -> teleporter sur le ship
 *      - ship charge && joueur dessus     -> redescendre au sol
 *
 *  - Shift + clic droit           -> ouvrir le GUI parametres
 */
public class RemoteListener implements Listener {

    private final SpaceShipProject plugin;
    private final SpaceshipManager manager;
    private final RemoteManager remotes;
    private final ConfigManager cfg;

    public RemoteListener(SpaceShipProject plugin) {
        this.plugin = plugin;
        this.manager = plugin.getSpaceshipManager();
        this.remotes = plugin.getRemoteManager();
        this.cfg = plugin.getConfigManager();
    }

    @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = false)
    public void onInteract(PlayerInteractEvent event) {
        if (event.getHand() != EquipmentSlot.HAND) return;

        ItemStack item = event.getItem();
        if (item == null || !remotes.isRemote(item)) return;

        Player player = event.getPlayer();
        long shipId = remotes.getShipId(item);
        if (shipId <= 0) return;

        Spaceship ship = plugin.getDatabaseManager().getSpaceship(shipId);
        if (ship == null) {
            player.sendMessage(cfg.prefix() + ConfigManager.color("&cCe spaceship n'existe plus, telecommande retiree."));
            // Retire la telecommande obsolete pour eviter le spam.
            int slot = player.getInventory().getHeldItemSlot();
            ItemStack mainHand = player.getInventory().getItemInMainHand();
            if (plugin.getRemoteManager().isRemote(mainHand)
                    && plugin.getRemoteManager().getShipId(mainHand) == shipId) {
                player.getInventory().setItem(slot, null);
            }
            event.setCancelled(true);
            return;
        }

        // Securite : seul le proprietaire (ou un admin) peut utiliser la telecommande.
        if (!ship.getOwnerUuid().equals(player.getUniqueId())
                && !player.hasPermission("spaceship.admin")) {
            player.sendMessage(cfg.msgNotOwner());
            event.setCancelled(true);
            return;
        }

        Action action = event.getAction();

        // Shift + clic droit -> GUI parametres
        if (player.isSneaking()
                && (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK)) {
            event.setCancelled(true);
            new SpaceshipGUI(plugin, player, ship).open();
            return;
        }

        // Clic gauche
        if (action == Action.LEFT_CLICK_AIR || action == Action.LEFT_CLICK_BLOCK) {
            event.setCancelled(true);
            handleLeftClick(player, ship);
            return;
        }

        // Clic droit
        if (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK) {
            event.setCancelled(true);
            handleRightClick(player, ship);
        }
    }

    private void handleLeftClick(Player player, Spaceship ship) {
        boolean loaded = manager.isLoaded(ship.getId());
        if (!loaded) {
            manager.summon(player, ship);
        } else if (manager.isPlayerOnShip(player, ship)) {
            // Sur le ship -> on n'unload pas (le joueur tomberait), on indique la marche a suivre
            player.sendMessage(cfg.prefix() + ConfigManager.color(
                    "&eUtilisez le clic droit pour redescendre avant de decharger."));
        } else {
            manager.unload(player, ship);
        }
    }

    private void handleRightClick(Player player, Spaceship ship) {
        boolean loaded = manager.isLoaded(ship.getId());
        if (!loaded) {
            // Invoque puis teleporte
            if (manager.summon(player, ship)) {
                manager.teleportToShip(player, ship);
            }
        } else if (manager.isPlayerOnShip(player, ship)) {
            manager.teleportDown(player, ship);
        } else {
            manager.teleportToShip(player, ship);
        }
    }
}
