#nullable enable
using Baya.Domain.Common;

namespace Baya.Domain.Entities.SupportAlerts;

/// <summary>
/// An internal staff worklist item (low rating, EVV no-show, expired verification, payment anomaly…).
/// NEVER user-facing — it must not appear in any user-facing endpoint, query, or join. The subject is a
/// polymorphic <c>(EntityType, EntityId)</c> validated at the application layer (no DB FK); the common
/// booking/review cases also set the typed FK. Status is forward-only: open → assigned → resolved.
/// </summary>
public class SupportAlert : BaseEntity<long>
{
    public string Type { get; set; } = string.Empty;

    public string Severity { get; set; } = SupportAlertSeverity.Medium;

    public string Status { get; set; } = SupportAlertStatus.Open;

    public string EntityType { get; set; } = string.Empty;

    public string EntityId { get; set; } = string.Empty;

    // Typed FK columns for the common cases. The bookings/reviews tables arrive in later phases; the FK
    // constraints are added there, so no relationship is configured now (the migration stays additive-safe).
    public long? BookingId { get; set; }

    public long? ReviewId { get; set; }

    public int? OwnerUserId { get; set; }

    public string? ResolutionNote { get; set; }

    public DateTimeOffset? ResolvedAt { get; set; }
}

/// <summary>Stable codes for <see cref="SupportAlert.Type"/>.</summary>
public static class SupportAlertType
{
    public const string LowRating = "low_rating";
    public const string EvvNoShow = "evv_no_show";
    public const string EvvLocationMismatch = "evv_location_mismatch";
    public const string VerificationExpired = "verification_expired";
    public const string SharedSim = "shared_sim";
    public const string PaymentAnomaly = "payment_anomaly";
    public const string FraudSignal = "fraud_signal";

    /// <summary>A refund on an already-paid booking opened a nurse clawback receivable (b11) — staff must
    /// track recovery. Iranian IBAN transfers are irreversible, so this is always worth a human look.</summary>
    public const string NurseClawback = "nurse_clawback";

    /// <summary>An on-site emergency was logged by the assigned nurse (b15) — the aftermath of the emergency-call
    /// playbook. Always worth a human review.</summary>
    public const string Emergency = "emergency";

    public static readonly IReadOnlyList<string> All =
    [
        LowRating, EvvNoShow, EvvLocationMismatch, VerificationExpired, SharedSim, PaymentAnomaly, FraudSignal, NurseClawback, Emergency
    ];
}

/// <summary>Stable codes for <see cref="SupportAlert.Severity"/>.</summary>
public static class SupportAlertSeverity
{
    public const string Low = "low";
    public const string Medium = "medium";
    public const string High = "high";

    public static readonly IReadOnlyList<string> All = [Low, Medium, High];
}

/// <summary>Stable codes for <see cref="SupportAlert.Status"/> (forward-only).</summary>
public static class SupportAlertStatus
{
    public const string Open = "open";
    public const string Assigned = "assigned";
    public const string Resolved = "resolved";

    public static readonly IReadOnlyList<string> All = [Open, Assigned, Resolved];
}
