package com.spaceshipproject;

import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;

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

/**
 * - Connexion : insere/maj le joueur dans la table players, nettoie ses telecommandes.
 * - Deconnexion : decharge tous ses spaceships (sauvegarde les modifications + le contenu des coffres).
 */
public class PlayerListener implements Listener {

    private final SpaceShipProject plugin;
    /** Memorise le ship sur lequel le joueur est mort, pour respawn. */
    private final Map<UUID, Long> deathOnShip = new HashMap<>();

    public PlayerListener(SpaceShipProject plugin) {
        this.plugin = plugin;
    }

    @EventHandler(priority = EventPriority.MONITOR)
    public void onJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        plugin.getDatabaseManager().upsertPlayer(player);
        int removed = plugin.getSpaceshipManager().sanitizePlayerRemotes(player);
        if (removed > 0) {
            player.sendMessage(plugin.getConfigManager().prefix()
                    + ConfigManager.color("&7" + removed + " telecommande(s) invalide(s) ont ete supprimees."));
        }
    }

    @EventHandler(priority = EventPriority.MONITOR)
    public void onDeath(PlayerDeathEvent event) {
        Player player = event.getEntity();
        // Cherche un spaceship du joueur dont la BB contient la position du deces.
        Location loc = player.getLocation();
        if (loc.getWorld() == null) return;
        // Verifie d'abord les ships dont le joueur est proprietaire et qui sont charges.
        for (LoadedSpaceship loaded : plugin.getDatabaseManager().getLoadedByOwner(player.getUniqueId())) {
            if (loaded.contains(loc)) {
                deathOnShip.put(player.getUniqueId(), loaded.getSpaceshipId());
                return;
            }
        }
        // Fallback : premier ship charge du joueur, le cas echeant.
        List<LoadedSpaceship> all = plugin.getDatabaseManager().getLoadedByOwner(player.getUniqueId());
        if (!all.isEmpty()) deathOnShip.put(player.getUniqueId(), all.get(0).getSpaceshipId());
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void onRespawn(PlayerRespawnEvent event) {
        Player player = event.getPlayer();
        Long shipId = deathOnShip.remove(player.getUniqueId());
        if (shipId == null) return;
        Spaceship ship = plugin.getDatabaseManager().getSpaceship(shipId);
        if (ship == null) return;
        LoadedSpaceship loaded = plugin.getDatabaseManager().getLoaded(shipId);
        if (loaded == null) return;
        World world = loaded.getWorld();
        if (world == null) return;
        Location target = new Location(world,
                loaded.getOriginX() + ship.getSpawnX() + 0.5,
                loaded.getOriginY() + ship.getSpawnY(),
                loaded.getOriginZ() + ship.getSpawnZ() + 0.5);
        event.setRespawnLocation(target);
    }

    @EventHandler(priority = EventPriority.HIGHEST)
    public void onQuit(PlayerQuitEvent event) {
        Player player = event.getPlayer();
        try {
            // Si le joueur est sur l'un de ses ships, le tp au sol avant de decharger
            // (pour qu'il ne reapparaisse pas en plein ciel a sa prochaine connexion).
            Spaceship onShip = plugin.getSpaceshipManager().findOwnedShipPlayerIsOn(player);
            if (onShip != null) {
                plugin.getSpaceshipManager().teleportDown(player, onShip);
            }
            plugin.getSpaceshipManager().unloadAllForPlayer(player.getUniqueId());
        } catch (Exception ex) {
            plugin.getLogger().warning("Erreur quit pour " + player.getName() + " : " + ex.getMessage());
        }
    }
}
