package com.tiedup.remake.commands;

import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.tiedup.remake.cells.CampOwnership;
import com.tiedup.remake.cells.CellDataV2;
import com.tiedup.remake.cells.CellRegistryV2;
import com.tiedup.remake.prison.PrisonerManager;
import com.tiedup.remake.prison.PrisonerRecord;
import java.util.List;
import java.util.UUID;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;

/**
 * Debug commands for the unified captivity system.
 *
 * Commands:
 *   /tiedup debug prisoner <player> - Show captivity state for a player
 *   /tiedup debug validate - Validate captivity system consistency
 *   /tiedup debug repair - Repair inconsistencies (WARNING: modifies data)
 *   /tiedup debug camp <campIdPrefix> - Show camp info and indexed cells
 */
public class CaptivityDebugCommand {

    /**
     * Create the /tiedup debug command tree.
     */
    public static LiteralArgumentBuilder<
        CommandSourceStack
    > createDebugCommand() {
        return Commands.literal("debug")
            .requires(CommandHelper.REQUIRES_OP) // Admin only
            // /tiedup debug prisoner <player>
            .then(
                Commands.literal("prisoner").then(
                    Commands.argument(
                        "player",
                        EntityArgument.player()
                    ).executes(CaptivityDebugCommand::debugPrisoner)
                )
            )
            // /tiedup debug validate
            .then(
                Commands.literal("validate").executes(
                    CaptivityDebugCommand::validateSystem
                )
            )
            // /tiedup debug repair
            .then(
                Commands.literal("repair").executes(
                    CaptivityDebugCommand::repairSystem
                )
            )
            // /tiedup debug camp <campIdPrefix>
            .then(
                Commands.literal("camp").then(
                    Commands.argument(
                        "campIdPrefix",
                        StringArgumentType.string()
                    ).executes(CaptivityDebugCommand::debugCamp)
                )
            );
    }

    /**
     * Show captivity state for a player.
     * /tiedup debug prisoner <player>
     */
    private static int debugPrisoner(CommandContext<CommandSourceStack> ctx) {
        try {
            ServerPlayer target = EntityArgument.getPlayer(ctx, "player");
            ServerLevel level = target.serverLevel();

            PrisonerManager manager = PrisonerManager.get(level);
            PrisonerRecord record = manager.getRecord(target.getUUID());

            StringBuilder debugInfo = new StringBuilder();
            debugInfo
                .append("Player: ")
                .append(target.getName().getString())
                .append("\n");
            debugInfo.append("State: ").append(record.getState()).append("\n");
            debugInfo
                .append("Camp ID: ")
                .append(record.getCampId())
                .append("\n");
            debugInfo
                .append("Cell ID: ")
                .append(record.getCellId())
                .append("\n");
            debugInfo
                .append("Captor ID: ")
                .append(record.getCaptorId())
                .append("\n");
            debugInfo
                .append("Protection Expiry: ")
                .append(record.getProtectionExpiry())
                .append("\n");
            debugInfo
                .append("Is Protected: ")
                .append(record.isProtected(level.getGameTime()))
                .append("\n");
            debugInfo
                .append("Is Captive: ")
                .append(record.isCaptive())
                .append("\n");

            // Send debug info to command executor
            ctx
                .getSource()
                .sendSuccess(
                    () ->
                        Component.translatable(
                            "command.tiedup.debug.prisoner_header"
                        ).append(Component.literal("\n" + debugInfo)).withStyle(ChatFormatting.YELLOW),
                    false
                );

            return 1; // Success
        } catch (Exception e) {
            ctx
                .getSource()
                .sendFailure(
                    Component.translatable("command.tiedup.debug.error", e.getMessage()).withStyle(
                        ChatFormatting.RED
                    )
                );
            return 0; // Failure
        }
    }

    /**
     * Validate captivity system consistency.
     * /tiedup debug validate
     * NOTE: CaptivitySystemValidator was removed. This now shows a summary of the prison system.
     */
    private static int validateSystem(CommandContext<CommandSourceStack> ctx) {
        try {
            ServerLevel level = ctx.getSource().getLevel();

            ctx
                .getSource()
                .sendSuccess(
                    () ->
                        Component.translatable(
                            "command.tiedup.debug.validate_checking"
                        ).withStyle(ChatFormatting.YELLOW),
                    true
                );

            // Show PrisonerManager stats instead
            PrisonerManager manager = PrisonerManager.get(level);
            String debugInfo = manager.toDebugString();

            ctx
                .getSource()
                .sendSuccess(
                    () ->
                        Component.literal(debugInfo).withStyle(ChatFormatting.GREEN),
                    true
                );

            return 1; // Success
        } catch (Exception e) {
            ctx
                .getSource()
                .sendFailure(
                    Component.translatable(
                        "command.tiedup.debug.error", e.getMessage()
                    ).withStyle(ChatFormatting.RED)
                );
            return 0; // Failure
        }
    }

    /**
     * Repair captivity system inconsistencies.
     * /tiedup debug repair
     * NOTE: CaptivitySystemValidator was removed. This command is now a placeholder.
     */
    private static int repairSystem(CommandContext<CommandSourceStack> ctx) {
        try {
            ctx
                .getSource()
                .sendSuccess(
                    () ->
                        Component.translatable(
                            "command.tiedup.debug.repair_simplified"
                        ).withStyle(ChatFormatting.YELLOW),
                    true
                );

            ctx
                .getSource()
                .sendSuccess(
                    () ->
                        Component.translatable(
                            "command.tiedup.debug.repair_auto"
                        ).withStyle(ChatFormatting.GREEN),
                    true
                );

            return 1; // Success
        } catch (Exception e) {
            ctx
                .getSource()
                .sendFailure(
                    Component.translatable("command.tiedup.debug.error", e.getMessage()).withStyle(
                        ChatFormatting.RED
                    )
                );
            return 0; // Failure
        }
    }

    /**
     * Debug camp information and indexed cells.
     * /tiedup debug camp <campIdPrefix>
     */
    private static int debugCamp(CommandContext<CommandSourceStack> ctx) {
        try {
            ServerLevel level = ctx.getSource().getLevel();
            String campIdPrefix = StringArgumentType.getString(
                ctx,
                "campIdPrefix"
            );

            CampOwnership ownership = CampOwnership.get(level);
            CellRegistryV2 cellRegistry = CellRegistryV2.get(level);

            // Find camps matching prefix
            UUID matchingCamp = null;
            for (CampOwnership.CampData camp : ownership.getAllCamps()) {
                String campIdStr = camp.getCampId().toString();
                if (campIdStr.startsWith(campIdPrefix)) {
                    matchingCamp = camp.getCampId();
                    break;
                }
            }

            if (matchingCamp == null) {
                ctx
                    .getSource()
                    .sendFailure(
                        Component.translatable(
                            "command.tiedup.debug.camp_not_found", campIdPrefix
                        ).withStyle(ChatFormatting.RED)
                    );
                return 0;
            }

            // Get camp info
            CampOwnership.CampData campData = ownership.getCamp(matchingCamp);
            StringBuilder sb = new StringBuilder();
            sb.append(
                String.format(
                    "=== Camp %s ===\n",
                    matchingCamp.toString().substring(0, 8)
                )
            );
            sb.append(String.format("Trader: %s\n", campData.getTraderUUID()));
            sb.append(String.format("Maid: %s\n", campData.getMaidUUID()));
            sb.append(String.format("Alive: %s\n", campData.isAlive()));
            sb.append(String.format("Center: %s\n", campData.getCenter()));

            // Get indexed cells
            List<CellDataV2> cells = cellRegistry.getCellsByCamp(matchingCamp);
            sb.append(
                String.format("\n=== Indexed Cells (%d) ===\n", cells.size())
            );

            if (cells.isEmpty()) {
                sb.append("⚠ NO CELLS INDEXED for this camp!\n");
            } else {
                for (CellDataV2 cell : cells.subList(
                    0,
                    Math.min(cells.size(), 10)
                )) {
                    sb.append(
                        String.format(
                            "- Cell %s at %s (type=%s, owner=%s, interior=%d, walls=%d)\n",
                            cell.getId().toString().substring(0, 8),
                            cell.getCorePos().toShortString(),
                            cell.isCampOwned() ? "CAMP" : "PLAYER",
                            cell.getOwnerId() != null
                                ? cell.getOwnerId().toString().substring(0, 8)
                                : "null",
                            cell.getInteriorBlocks().size(),
                            cell.getWallBlocks().size()
                        )
                    );
                }
                if (cells.size() > 10) {
                    sb.append(
                        String.format("... and %d more\n", cells.size() - 10)
                    );
                }
            }

            final String campInfo = sb.toString();
            ctx
                .getSource()
                .sendSuccess(
                    () ->
                        Component.literal(campInfo).withStyle(
                            ChatFormatting.YELLOW
                        ),
                    false
                );

            return 1; // Success
        } catch (Exception e) {
            ctx
                .getSource()
                .sendFailure(
                    Component.translatable("command.tiedup.debug.error", e.getMessage()).withStyle(
                        ChatFormatting.RED
                    )
                );
            return 0; // Failure
        }
    }
}
