using Nexus.Api.Integrations;
using Nexus.Api.Models;

namespace Nexus.Api.Services;

public interface IOpenClawChatService
{
    Task<AgentChatResult> SendAsync(
        string message,
        string conversationId,
        string agentId,
        OpenClawInvocationMetadata invocation,
        CancellationToken cancellationToken = default);
}

/// <summary>
/// The single Iris/agent chat dispatch path. Every message becomes a durable
/// Nexus run and crosses the Protocol-v4 chat.send boundary; Nexus never calls
/// OpenClaw's OpenAI-compatible /v1/chat/completions endpoint.
/// </summary>
public sealed class OpenClawChatService(IOpenClawRunService runs) :
    IOpenClawChatService
{
    public async Task<AgentChatResult> SendAsync(
        string message,
        string conversationId,
        string agentId,
        OpenClawInvocationMetadata invocation,
        CancellationToken cancellationToken = default)
    {
        var normalizedAgent = agentId.Trim().ToLowerInvariant();
        var operation = await runs.StartAsync(
            new StartOpenClawRunRequest(
                message,
                normalizedAgent,
                $"agent:{normalizedAgent}:main",
                Title: $"Chat with {normalizedAgent}"),
            invocation,
            cancellationToken);

        if (!operation.Ok)
        {
            throw new OpenClawChatDispatchException(
                operation.State,
                operation.Message,
                operation.Run.Id);
        }

        return new AgentChatResult(
            "OpenClaw Protocol v4",
            normalizedAgent,
            conversationId,
            operation.Message,
            operation.Run.Id,
            operation.State,
            operation.Operation);
    }
}

public sealed class OpenClawChatDispatchException(
    string state,
    string message,
    Guid runId) : InvalidOperationException(message)
{
    public string State { get; } = state;
    public Guid RunId { get; } = runId;
}
