package de.viper.survivalplus.commands;

import de.viper.survivalplus.SurvivalPlus;
import de.viper.survivalplus.util.Claim;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

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

public class ClaimCommand implements CommandExecutor {
    private SurvivalPlus plugin;
    private static final int MAX_CLAIMS = 10;
    private static final int MAX_AREA = 10000; // 100x100 blocks

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

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage(plugin.getMessage("commands.player-only"));
            return true;
        }
        Player player = (Player) sender;

        if (args.length == 0) {
            if (!player.hasPermission("survivalplus.claim.use")) {
                player.sendMessage(plugin.getMessage("commands.no-permission"));
                return true;
            }
            Location point1 = plugin.getPoint1(player);
            Location point2 = plugin.getPoint2(player);
            if (point1 == null || point2 == null) {
                player.sendMessage(plugin.getMessage("claim.points-not-set"));
                return true;
            }
            if (!point1.getWorld().equals(point2.getWorld())) {
                player.sendMessage(plugin.getMessage("claim.different-worlds"));
                return true;
            }
            int x1 = point1.getBlockX();
            int z1 = point1.getBlockZ();
            int x2 = point2.getBlockX();
            int z2 = point2.getBlockZ();
            int width = Math.abs(x2 - x1) + 1;
            int length = Math.abs(z2 - z1) + 1;
            if (width * length > MAX_AREA) {
                player.sendMessage(plugin.getMessage("claim.too-large").replace("%max%", String.valueOf(MAX_AREA)));
                return true;
            }
            Claim newClaim = new Claim(player, point1.getWorld().getName(), x1, z1, x2, z2);
            if (plugin.hasOverlap(newClaim)) {
                player.sendMessage(plugin.getMessage("claim.overlap"));
                return true;
            }
            if (plugin.getClaimCount(player) >= MAX_CLAIMS) {
                player.sendMessage(plugin.getMessage("claim.max-reached").replace("%max%", String.valueOf(MAX_CLAIMS)));
                return true;
            }
            plugin.addClaim(newClaim, player);
            player.sendMessage(plugin.getMessage("claim.success").replace("%count%", String.valueOf(plugin.getClaimCount(player))).replace("%max%", String.valueOf(MAX_CLAIMS)));
            plugin.clearSelections(player);
            return true;
        }

        switch (args[0].toLowerCase()) {
            case "mark":
                if (!player.hasPermission("survivalplus.claim.use")) {
                    player.sendMessage(plugin.getMessage("commands.no-permission"));
                    return true;
                }
                if (args.length < 2 || (!args[1].equals("1") && !args[1].equals("2"))) {
                    player.sendMessage(plugin.getMessage("claim.usage-mark"));
                    return true;
                }
                Location location = player.getLocation();
                if (args[1].equals("1")) {
                    plugin.setPoint1(player, location);
                    player.sendMessage(plugin.getMessage("claim.point1-set").replace("%x%", String.valueOf(location.getBlockX())).replace("%z%", String.valueOf(location.getBlockZ())));
                } else {
                    plugin.setPoint2(player, location);
                    player.sendMessage(plugin.getMessage("claim.point2-set").replace("%x%", String.valueOf(location.getBlockX())).replace("%z%", String.valueOf(location.getBlockZ())));
                }
                return true;

            case "unclaim":
                if (args.length == 1) {
                    if (!player.hasPermission("survivalplus.claim.use")) {
                        player.sendMessage(plugin.getMessage("commands.no-permission"));
                        return true;
                    }
                    Claim claim = plugin.getClaim(player.getLocation());
                    if (claim == null || !claim.getOwner().equals(player.getUniqueId())) {
                        player.sendMessage(plugin.getMessage("claim.not-owner"));
                        return true;
                    }
                    plugin.removeClaim(player.getLocation(), player);
                    player.sendMessage(plugin.getMessage("claim.unclaimed"));
                    return true;
                } else if (args.length == 2 && player.isOp()) {
                    Player target = Bukkit.getPlayer(args[1]);
                    UUID targetUUID;
                    if (target != null) {
                        targetUUID = target.getUniqueId();
                    } else {
                        try {
                            targetUUID = UUID.fromString(args[1]);
                        } catch (IllegalArgumentException e) {
                            player.sendMessage(plugin.getMessage("commands.player-not-found"));
                            return true;
                        }
                    }
                    int removedCount = removePlayerClaims(targetUUID);
                    if (removedCount > 0) {
                        player.sendMessage(plugin.getMessage("claim.op-unclaimed")
                                .replace("%player%", args[1])
                                .replace("%count%", String.valueOf(removedCount)));
                    } else {
                        player.sendMessage(plugin.getMessage("claim.no-claims-found")
                                .replace("%player%", args[1]));
                    }
                    return true;
                } else {
                    player.sendMessage(plugin.getMessage("claim.usage"));
                    return true;
                }

            case "trust":
                if (!player.hasPermission("survivalplus.claim.trust")) {
                    player.sendMessage(plugin.getMessage("commands.no-permission"));
                    return true;
                }
                if (args.length < 2) {
                    player.sendMessage(plugin.getMessage("claim.usage-trust"));
                    return true;
                }
                Player target = Bukkit.getPlayer(args[1]);
                if (target == null) {
                    player.sendMessage(plugin.getMessage("commands.player-not-found"));
                    return true;
                }
                Claim claim = plugin.getClaim(player.getLocation());
                if (claim == null || !claim.getOwner().equals(player.getUniqueId())) {
                    player.sendMessage(plugin.getMessage("claim.not-owner"));
                    return true;
                }
                claim.addTrusted(target.getUniqueId());
                player.sendMessage(plugin.getMessage("claim.trusted").replace("%player%", args[1]));
                plugin.saveClaims();
                break;

            case "untrust":
                if (!player.hasPermission("survivalplus.claim.trust")) {
                    player.sendMessage(plugin.getMessage("commands.no-permission"));
                    return true;
                }
                if (args.length < 2) {
                    player.sendMessage(plugin.getMessage("claim.usage-untrust"));
                    return true;
                }
                target = Bukkit.getPlayer(args[1]);
                if (target == null) {
                    player.sendMessage(plugin.getMessage("commands.player-not-found"));
                    return true;
                }
                claim = plugin.getClaim(player.getLocation());
                if (claim == null || !claim.getOwner().equals(player.getUniqueId())) {
                    player.sendMessage(plugin.getMessage("claim.not-owner"));
                    return true;
                }
                claim.removeTrusted(target.getUniqueId());
                player.sendMessage(plugin.getMessage("claim.untrusted").replace("%player%", args[1]));
                plugin.saveClaims();
                break;

            case "info":
                if (!player.hasPermission("survivalplus.claim.use")) {
                    player.sendMessage(plugin.getMessage("commands.no-permission"));
                    return true;
                }
                claim = plugin.getClaim(player.getLocation());
                if (claim == null) {
                    player.sendMessage(plugin.getMessage("claim.no-claim-at-location"));
                    return true;
                }
                String ownerName = Bukkit.getOfflinePlayer(claim.getOwner()).getName();
                if (ownerName == null) {
                    ownerName = claim.getOwner().toString(); // Fallback to UUID if name not found
                }
                player.sendMessage(plugin.getMessage("claim.info")
                        .replace("%owner%", ownerName)
                        .replace("%world%", claim.getWorldName())
                        .replace("%x1%", String.valueOf(claim.getX1()))
                        .replace("%z1%", String.valueOf(claim.getZ1()))
                        .replace("%x2%", String.valueOf(claim.getX2()))
                        .replace("%z2%", String.valueOf(claim.getZ2())));
                return true;

            default:
                player.sendMessage(plugin.getMessage("claim.usage"));
        }
        return true;
    }

    private int removePlayerClaims(UUID targetUUID) {
        Map<String, Claim> claims = new HashMap<>(plugin.getClaims());
        int removedCount = 0;
        for (Map.Entry<String, Claim> entry : claims.entrySet()) {
            if (entry.getValue().getOwner().equals(targetUUID)) {
                plugin.removeClaimByKey(entry.getKey(), targetUUID);
                removedCount++;
            }
        }
        if (removedCount > 0) {
            plugin.saveClaims();
        }
        return removedCount;
    }
}