using Microsoft.AspNetCore.Mvc;

namespace ControlCenter.Controllers;

/// <summary>
/// REST API for sending control commands to agents.
/// Provides the Command Hub's action endpoints for agent lifecycle control.
///
/// <para>API contract for Rex (Frontend):</para>
/// <list type="bullet">
///   <item><c>POST /api/command/stop/{agentId}</c> — Stop/abort an agent's active session</item>
///   <item><c>POST /api/command/restart/{agentId}</c> — Restart an agent</item>
///   <item><c>POST /api/command/steer/{agentId}</c> — Inject a message into an agent's session</item>
/// </list>
///
/// <para>Commands are forwarded to the OpenClaw Gateway via the
/// WebSocket bridge service. The Gateway handles the actual execution.</para>
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class CommandController : ControllerBase
{
    private readonly ILogger<CommandController> _logger;

    public CommandController(ILogger<CommandController> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// Stops (aborts) an agent's active session.
    /// Sends an abort command to the OpenClaw Gateway.
    /// </summary>
    /// <param name="agentId">The agent identifier to stop.</param>
    /// <returns>Confirmation of the stop command.</returns>
    /// <response code="200">Stop command sent successfully.</response>
    /// <response code="404">No active session found for the agent.</response>
    [HttpPost("stop/{agentId}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public IActionResult StopAgent(string agentId)
    {
        _logger.LogInformation("Stop command received for agent {AgentId}", agentId);

        // TODO: Forward to Gateway via bridge service
        // await _bridgeService.SendRpcAsync("sessions.abort", new { sessionKey = ... });

        return Ok(new
        {
            agentId,
            command = "stop",
            status = "sent",
            timestamp = DateTime.UtcNow.ToString("o")
        });
    }

    /// <summary>
    /// Restarts an agent by aborting the current session and allowing
    /// a new one to start on the next incoming message.
    /// </summary>
    /// <param name="agentId">The agent identifier to restart.</param>
    /// <returns>Confirmation of the restart command.</returns>
    /// <response code="200">Restart command sent successfully.</response>
    [HttpPost("restart/{agentId}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public IActionResult RestartAgent(string agentId)
    {
        _logger.LogInformation("Restart command received for agent {AgentId}", agentId);

        // TODO: Forward to Gateway — abort current session + signal restart

        return Ok(new
        {
            agentId,
            command = "restart",
            status = "sent",
            timestamp = DateTime.UtcNow.ToString("o")
        });
    }

    /// <summary>
    /// Steers (injects a message into) an agent's active session.
    /// Used by operators to redirect an agent's task mid-execution.
    /// </summary>
    /// <param name="agentId">The agent identifier to steer.</param>
    /// <param name="request">The steering message to inject.</param>
    /// <returns>Confirmation of the steer command.</returns>
    /// <response code="200">Steer command sent successfully.</response>
    /// <response code="400">Missing or empty message.</response>
    [HttpPost("steer/{agentId}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public IActionResult SteerAgent(string agentId, [FromBody] SteerRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Message))
        {
            return BadRequest(new { error = "Message is required" });
        }

        _logger.LogInformation("Steer command received for agent {AgentId}: {Message}",
            agentId, request.Message.Length > 100
                ? request.Message[..100] + "..." : request.Message);

        // TODO: Forward to Gateway via bridge service
        // await _bridgeService.SendRpcAsync("sessions.steer", new { sessionKey = ..., message = request.Message });

        return Ok(new
        {
            agentId,
            command = "steer",
            message = request.Message,
            status = "sent",
            timestamp = DateTime.UtcNow.ToString("o")
        });
    }
}

/// <summary>
/// Request body for the steer command.
/// </summary>
/// <param name="Message">The message to inject into the agent's session.</param>
public record SteerRequest(string Message);