namespace Pgo.Backend.Models;

public class BackgroundJobStatus
{
    public string? Id { get; set; }
    public bool IsCompleted { get; set; }
    public string? ErrorMessage { get; set; }
    public required IRequest? Request { get; set; }
    public Type? ResultType { get; set; }
    public object? Result { get; set; }
    public int RetryAfterSeconds { get; set; } = 2;

    public static BackgroundJobStatus Create(string? jobId, IRequest? request, bool isCompleted = false, string? errorMessage = null, object? result = null)
    {
        return new()
        {
            Id = jobId ?? Guid.NewGuid().ToString(),
            IsCompleted = isCompleted,
            ErrorMessage = errorMessage,
            Request = request,
            ResultType = result?.GetType(),
            Result = result
        };
    }

    public BackgroundJobStatus Complete(string? errorMessage = null, object? result = null)
    {
        IsCompleted = true;
        ErrorMessage = errorMessage ?? ErrorMessage ?? null;
        ResultType = result?.GetType();
        Result = result ?? null;
        return this;
    }

    public BackgroundJobStatus Fail(string errorMessage) => Complete(errorMessage);
    public BackgroundJobStatus Success(object result) => Complete(result: result);

    public bool IsError => !string.IsNullOrEmpty(ErrorMessage);

    /// <summary>
    /// A client SHOULD follow an exponential backoff approach when polling for status. 
    /// A server SHOULD supply a Retry-After header with a with a delay time in seconds.
    /// See <see cref="https://build.fhir.org/async-bundle.html"/>.
    /// </summary>
    public BackgroundJobStatus ApplyExponentialBackoff()
    {
        RetryAfterSeconds *= 2;
        return this;
    }
}
