namespace Femto.Common.Infrastructure.Outbox;

public class OutboxEntry
{
    private const int MaxRetries = 5;

    public Guid Id { get; private set; }

    public string EventType { get; private set; } = null!;
    public Guid AggregateId { get; private set; }

    public string Payload { get; private set; } = null!;

    public DateTime CreatedAt { get; private set; }

    public DateTime? ProcessedAt { get; private set; }
    public DateTime? NextRetryAt { get; private set; }
    public int RetryCount { get; private set; } = 0;
    public string? LastError { get; private set; }
    public OutboxEntryStatus Status { get; private set; }

    private OutboxEntry() { }

    public OutboxEntry(Guid eventId, Guid aggregateId, string eventType, string payload)
    {
        this.Id = eventId;
        this.EventType = eventType;
        this.AggregateId = aggregateId;
        this.Payload = payload;
        this.CreatedAt = DateTime.UtcNow;
    }

    public void Succeed()
    {
        this.ProcessedAt = DateTime.UtcNow;
        this.Status = OutboxEntryStatus.Completed;
    }

    public void Fail(string error)
    {
        if (this.RetryCount >= MaxRetries)
        {
            this.Status = OutboxEntryStatus.Failed;
        }
        else
        {
            this.LastError = error;
            this.NextRetryAt = DateTime.UtcNow.AddSeconds(Math.Pow(2, this.RetryCount));
            this.RetryCount++;
        }
    }
}

public enum OutboxEntryStatus
{
    Pending = 0,
    Completed = 1,
    Failed = 2,
}
