using ScadaLink.Commons.Types.Enums;

namespace ScadaLink.Commons.Entities.Audit;

/// <summary>
/// Single source of truth for AuditLog (#23) rows. Central rows leave ForwardState null;
/// site rows leave IngestedAtUtc null until ingest. Append-only.
/// </summary>
public sealed record AuditEvent
{
    /// <summary>Idempotency key; uniquely identifies one audit lifecycle event.</summary>
    public Guid EventId { get; init; }

    /// <summary>UTC timestamp when the audited action occurred at its source.</summary>
    public DateTime OccurredAtUtc { get; init; }

    /// <summary>UTC timestamp when the row was ingested at central; null on the site hot-path.</summary>
    public DateTime? IngestedAtUtc { get; init; }

    /// <summary>Trust-boundary channel the audited action crossed.</summary>
    public AuditChannel Channel { get; init; }

    /// <summary>Specific event kind within the channel (see alog.md §4).</summary>
    public AuditKind Kind { get; init; }

    /// <summary>Correlation id linking related audit rows (e.g. the cached-op lifecycle).</summary>
    public Guid? CorrelationId { get; init; }

    /// <summary>Site id where the action originated; null for central-direct events.</summary>
    public string? SourceSiteId { get; init; }

    /// <summary>Instance id where the action originated, when applicable.</summary>
    public string? SourceInstanceId { get; init; }

    /// <summary>Script that initiated the action (script trust boundary), when applicable.</summary>
    public string? SourceScript { get; init; }

    /// <summary>Authenticated actor for inbound paths (API key name, user, etc.).</summary>
    public string? Actor { get; init; }

    /// <summary>Target of the action: external system name, db connection name, list name, or inbound method.</summary>
    public string? Target { get; init; }

    /// <summary>Lifecycle status of this row.</summary>
    public AuditStatus Status { get; init; }

    /// <summary>HTTP status code where applicable (outbound API + inbound API).</summary>
    public int? HttpStatus { get; init; }

    /// <summary>Duration of the audited action in milliseconds, when measurable.</summary>
    public int? DurationMs { get; init; }

    /// <summary>Human-readable error summary on failure rows.</summary>
    public string? ErrorMessage { get; init; }

    /// <summary>Verbose error detail (stack/exception) on failure rows.</summary>
    public string? ErrorDetail { get; init; }

    /// <summary>Truncated/redacted request summary; capped per AuditLogOptions.</summary>
    public string? RequestSummary { get; init; }

    /// <summary>Truncated/redacted response summary; capped per AuditLogOptions.</summary>
    public string? ResponseSummary { get; init; }

    /// <summary>True when Request/Response summaries were truncated to the payload cap.</summary>
    public bool PayloadTruncated { get; init; }

    /// <summary>Free-form JSON extension column for channel-specific extras.</summary>
    public string? Extra { get; init; }

    /// <summary>Site-local forwarding state; null on central rows.</summary>
    public AuditForwardState? ForwardState { get; init; }
}
