namespace Nexus.Api.Data;

/// <summary>
/// Durable Nexus projection of one OpenClaw chat run. Nexus owns the
/// correlation and audit metadata; OpenClaw remains the execution authority.
/// </summary>
public sealed class OpenClawRun
{
    public Guid Id { get; init; } = Guid.NewGuid();
    public required string Title { get; set; }
    public required string Prompt { get; set; }
    public required string AgentId { get; set; }
    public required string SessionKey { get; set; }
    public string Status { get; set; } = OpenClawRunStates.Dispatching;
    public Guid? TaskId { get; set; }
    public Guid? ProjectId { get; set; }
    public string? OpenClawRunId { get; set; }
    public Guid? RetriedFromRunId { get; set; }
    public required string StartIdempotencyKey { get; set; }
    public required string CorrelationId { get; set; }
    public required string Actor { get; set; }
    public string? TraceParent { get; set; }
    public string? LastError { get; set; }
    public long? LastGatewaySequence { get; set; }
    public bool SequenceGapDetected { get; set; }
    public int Revision { get; set; }
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset? StartedAt { get; set; }
    public DateTimeOffset? FinishedAt { get; set; }
    public ICollection<OpenClawRunHistory> History { get; set; } = new List<OpenClawRunHistory>();
}

/// <summary>
/// Append-only action and state-transition ledger for an OpenClaw run.
/// </summary>
public sealed class OpenClawRunHistory
{
    public long Id { get; init; }
    public Guid RunId { get; set; }
    public OpenClawRun Run { get; set; } = null!;
    public required string Action { get; set; }
    public required string FromStatus { get; set; }
    public required string ToStatus { get; set; }
    public required string Message { get; set; }
    public required string Actor { get; set; }
    public required string CorrelationId { get; set; }
    public string? IdempotencyKey { get; set; }
    public string? TraceParent { get; set; }
    public string? GatewayEventId { get; set; }
    public long? GatewaySequence { get; set; }
    public bool SequenceGapDetected { get; set; }
    public Guid? ResultRunId { get; set; }
    public DateTimeOffset OccurredAt { get; set; } = DateTimeOffset.UtcNow;
}

public static class OpenClawRunStates
{
    public const string Dispatching = "dispatching";
    public const string Running = "running";
    public const string Stopping = "stopping";
    public const string Stopped = "stopped";
    public const string Completed = "completed";
    public const string Failed = "failed";
    public const string Blocked = "blocked";
    public const string Unsupported = "unsupported";

    public static bool IsTerminal(string state)
        => state is Stopped or Completed or Failed or Blocked or Unsupported;
}
