using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using System.Diagnostics;
using System.Security.Claims;
using Nexus.Api.DTOs;
using Nexus.Api.Services;

namespace Nexus.Api.Controllers;

[Authorize(Roles = "owner")]
[ApiController]
[Route("api/v1/chat")]
public class ChatController(
    IOpenClawChatService chat,
    ILogger<ChatController> logger) : ControllerBase
{
    [HttpPost]
    [EnableRateLimiting("agents")]
    public async Task<IResult> Chat([FromBody] ChatRequest request, CancellationToken ct)
    {
        var message = request.Message?.Trim();
        if (string.IsNullOrWhiteSpace(message) || message.Length > 8000)
            return Results.ValidationProblem(new Dictionary<string, string[]> { ["message"] = ["Message must contain between 1 and 8000 characters."] });

        var agentId = string.IsNullOrWhiteSpace(request.AgentId) ? "iris" : request.AgentId.Trim().ToLowerInvariant();
        if (agentId is not ("iris" or "main"))
            return Results.ValidationProblem(new Dictionary<string, string[]> { ["agentId"] = ["Only iris and main are supported."] });

        var conversationId = string.IsNullOrWhiteSpace(request.ConversationId)
            ? $"nexus-{Guid.NewGuid():N}"
            : request.ConversationId.Trim();
        if (conversationId.Length > 160)
            return Results.ValidationProblem(new Dictionary<string, string[]> { ["conversationId"] = ["Conversation id is too long."] });

        try
        {
            var contextualMessage = MissionControlContextFormatter.Format(message, request.Context);
            var invocationContext = OpenClawInvocationContextFactory.Create(
                User.FindFirst("sub")?.Value
                    ?? User.FindFirst(ClaimTypes.NameIdentifier)?.Value
                    ?? User.Identity?.Name,
                Request.Headers["Idempotency-Key"].FirstOrDefault(),
                Request.Headers["X-Correlation-ID"].FirstOrDefault()
                    ?? HttpContext.TraceIdentifier,
                Request.Headers["traceparent"].FirstOrDefault()
                    ?? Activity.Current?.Id);
            var invocation = new Nexus.Api.Models.OpenClawInvocationMetadata(
                invocationContext.IdempotencyKey,
                invocationContext.CorrelationId,
                invocationContext.Actor,
                invocationContext.TraceParent);
            Response.Headers["X-Correlation-ID"] = invocation.CorrelationId;
            return Results.Ok(await chat.SendAsync(
                contextualMessage,
                conversationId,
                agentId,
                invocation,
                ct));
        }
        catch (ArgumentException exception)
        {
            return Results.ValidationProblem(new Dictionary<string, string[]>
            {
                ["requestMetadata"] = [exception.Message]
            });
        }
        catch (Exception exception)
        {
            logger.LogWarning(exception, "OpenClaw chat request failed for agent {AgentId}", agentId);
            return Results.Problem(
                title: "OpenClaw chat unavailable",
                detail: "The trusted OpenClaw chat endpoint is not enabled or reachable.",
                statusCode: StatusCodes.Status503ServiceUnavailable);
        }
    }

}
