package de.viper.survivalplus.listeners;

import de.viper.survivalplus.SurvivalPlus;
import de.viper.survivalplus.util.Claim;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Monster;
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.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.event.player.PlayerMoveEvent;

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

public class ClaimListener implements Listener {
    private final SurvivalPlus plugin;
    private final Map<UUID, Claim> lastClaim = new HashMap<>();

    public ClaimListener(SurvivalPlus plugin) {
        this.plugin = plugin;
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
        Player player = event.getPlayer();
        if (player.isOp()) return;
        Claim claim = plugin.getClaim(event.getBlock().getLocation());
        if (claim != null && !claim.getOwner().equals(player.getUniqueId()) && !claim.getTrusted().contains(player.getUniqueId())) {
            event.setCancelled(true);
            player.sendMessage(plugin.getMessage("claim.no-break"));
        }
    }

    @EventHandler
    public void onBlockPlace(BlockPlaceEvent event) {
        Player player = event.getPlayer();
        if (player.isOp()) return;
        Claim claim = plugin.getClaim(event.getBlock().getLocation());
        if (claim != null && !claim.getOwner().equals(player.getUniqueId()) && !claim.getTrusted().contains(player.getUniqueId())) {
            event.setCancelled(true);
            player.sendMessage(plugin.getMessage("claim.no-place"));
        }
    }

    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event) {
        Player player = event.getPlayer();
        UUID playerId = player.getUniqueId();
        Claim currentClaim = plugin.getClaim(event.getTo());
        Location to = event.getTo();
        
        // --- NEU: BAN CHECK ---
        if (currentClaim != null) {
            // Checken ob Spieler in der Ban-Liste der Claims Config steht
            String claimKey = getClaimKeyFromLocation(to);
            if (claimKey != null) {
                FileConfiguration config = plugin.getClaimsConfig();
                if (config.contains(claimKey + ".banned")) {
                    if (config.getStringList(claimKey + ".banned").contains(playerId.toString())) {
                        event.setCancelled(true);
                        player.sendMessage(ChatColor.RED + "Du bist aus diesem Gebiet verbannt!");
                        // Optional: Knockback effect
                        player.teleport(event.getFrom().add(0, 0.2, 0));
                        return;
                    }
                }
            }
        }

        // Prüfe, ob sich der Claim-Status geändert hat
        Claim previousClaim = lastClaim.getOrDefault(playerId, null);
        if (currentClaim != previousClaim) {
            if (currentClaim != null) {
                // Spieler betritt einen Claim
                String ownerName = plugin.getServer().getOfflinePlayer(currentClaim.getOwner()).getName();
                if (ownerName == null) {
                    ownerName = currentClaim.getOwner().toString(); // Fallback auf UUID
                }
                player.sendMessage(plugin.getMessage("claim.enter").replace("%owner%", ownerName));
            } else if (previousClaim != null) {
                // Spieler verlässt einen Claim
                String ownerName = plugin.getServer().getOfflinePlayer(previousClaim.getOwner()).getName();
                if (ownerName == null) {
                    ownerName = previousClaim.getOwner().toString(); // Fallback auf UUID
                }
                player.sendMessage(plugin.getMessage("claim.leave").replace("%owner%", ownerName));
            }
            lastClaim.put(playerId, currentClaim);
        }
    }

    // --- NEU: Schutz vor Monstern im Claim ---
    @EventHandler
    public void onMobTarget(EntityTargetLivingEntityEvent event) {
        // 1. Prüfen, ob das Ziel ein Spieler ist
        if (!(event.getTarget() instanceof Player)) return;

        // 2. Prüfen, ob das Angreifer ein Monster ist (Zombie, Skelett, etc.)
        if (!(event.getEntity() instanceof Monster)) return;

        Player player = (Player) event.getTarget();
        Location loc = player.getLocation();

        // 3. Prüfen, ob der Spieler in einem Claim steht
        Claim claim = plugin.getClaim(loc);

        if (claim != null) {
            // 4. Prüfen, ob der Spieler dort Rechte hat (Owner oder Trusted)
            if (claim.getOwner().equals(player.getUniqueId()) || claim.getTrusted().contains(player.getUniqueId())) {
                // Das Targeting abbrechen -> Monster greift nicht an
                event.setCancelled(true);
            }
        }
    }
    
    // Helper für ClaimListener (Kopiert, da wir die Methode in Command nicht sehen können)
    private String getClaimKeyFromLocation(Location loc) {
        // Da wir hier keinen direkten Zugriff auf den Key haben, iterieren wir kurz
        for (String key : plugin.getClaims().keySet()) {
             if (plugin.getClaims().get(key).isInside(loc)) {
                 return key;
             }
        }
        return null;
    }
}