#nullable enable
namespace Baya.Domain.Entities.Verification;

/// <summary>
/// Maps the verification status enums to/from the stable snake_case codes stored in the DB and sent on the
/// wire. Kept explicit (no reflection) so the persisted/contract vocabulary is greppable and can never
/// drift from an accidental enum rename.
/// </summary>
public static class VerificationCodes
{
    public static string ToCode(this VerificationStatus status) => status switch
    {
        VerificationStatus.NotStarted => "not_started",
        VerificationStatus.Pending => "pending",
        VerificationStatus.InReview => "in_review",
        VerificationStatus.Approved => "approved",
        VerificationStatus.Rejected => "rejected",
        VerificationStatus.Suspended => "suspended",
        _ => throw new ArgumentOutOfRangeException(nameof(status), status, null)
    };

    public static string ToCode(this VerificationStepStatus status) => status switch
    {
        VerificationStepStatus.NotStarted => "not_started",
        VerificationStepStatus.Pending => "pending",
        VerificationStepStatus.InReview => "in_review",
        VerificationStepStatus.Passed => "passed",
        VerificationStepStatus.Failed => "failed",
        VerificationStepStatus.Expired => "expired",
        _ => throw new ArgumentOutOfRangeException(nameof(status), status, null)
    };

    public static VerificationStatus ParseStatus(string code) => code switch
    {
        "not_started" => VerificationStatus.NotStarted,
        "pending" => VerificationStatus.Pending,
        "in_review" => VerificationStatus.InReview,
        "approved" => VerificationStatus.Approved,
        "rejected" => VerificationStatus.Rejected,
        "suspended" => VerificationStatus.Suspended,
        _ => throw new ArgumentOutOfRangeException(nameof(code), code, "Unknown verification status code.")
    };

    public static VerificationStepStatus ParseStepStatus(string code) => code switch
    {
        "not_started" => VerificationStepStatus.NotStarted,
        "pending" => VerificationStepStatus.Pending,
        "in_review" => VerificationStepStatus.InReview,
        "passed" => VerificationStepStatus.Passed,
        "failed" => VerificationStepStatus.Failed,
        "expired" => VerificationStepStatus.Expired,
        _ => throw new ArgumentOutOfRangeException(nameof(code), code, "Unknown verification step status code.")
    };

    /// <summary>Lenient parse for a query-string filter; returns null for a missing/unknown value.</summary>
    public static VerificationStepStatus? TryParseStepStatus(string? code) => code switch
    {
        "not_started" => VerificationStepStatus.NotStarted,
        "pending" => VerificationStepStatus.Pending,
        "in_review" => VerificationStepStatus.InReview,
        "passed" => VerificationStepStatus.Passed,
        "failed" => VerificationStepStatus.Failed,
        "expired" => VerificationStepStatus.Expired,
        _ => null
    };
}
