#nullable enable
namespace Baya.Infrastructure.Persistence.Services.Seeding;

/// <summary>
/// The static, deterministic description of the Development <b>lifecycle</b> demo world the
/// <see cref="DemoLifecycleSeeder"/> materialises on top of <see cref="DemoWorldDefinitions"/>'s personas:
/// which booking scenario exists in which state, the fixed ticket reference codes, and the one extra
/// partner-center persona. Kept as plain data so the exact scenario table reads at a glance and stays the
/// single source of truth for the runbook / testing plan.
/// <para>
/// All timestamps are expressed as <b>day/hour offsets from seed time</b> (negative = past) because the
/// scenario meanings are relative ("completed inside the 72h dispute window"), not absolute dates.
/// </para>
/// </summary>
internal static class DemoLifecycleDefinitions
{
    /// <summary>The partner-center dashboard owner (no admin/nurse role — the portal keys off the center's
    /// <c>admin_user_id</c>; the customer role only gives the login a sane landing).</summary>
    public const string PartnerAdminPhone = "09120000030";
    public const string PartnerAdminUserName = "demo_partner_rastegar";
    public const string PartnerAdminName = "بهنام";
    public const string PartnerAdminFamilyName = "رستگار";

    public const string PartnerCenterName = "مرکز پرستاری آرامش";
    public const string PartnerCenterPermitNo = "MOH-C-1001"; // the natural idempotency key
    public const string PartnerCenterEnamad = "ENAMAD-DEMO-771";

    /// <summary>The extra 5-session package variant seeded for the multi-session booking scenario
    /// (PostSurgery × Night so its option-set hash can never collide with the base seeder's variants).</summary>
    public const string PackageVariantDisplayName = "پکیج ۵ جلسه‌ای مراقبت پس از جراحی";
    public const long PackageVariantPricePerSession = 900_000;
    public const int PackageVariantSessionCount = 5;

    // Fixed, human-greppable ticket reference codes — UNIQUE-indexed, so they double as idempotency guards.
    public const string RefundTicketCard = "TKT-DEMORF01";
    public const string RefundTicketBnpl = "TKT-DEMORF02";
    public const string RefundTicketClawback = "TKT-DEMORF03";
    public const string SupportTicketOpen = "TKT-DEMOSUP1";
    public const string SupportTicketClosed = "TKT-DEMOSUP2";
    public const string EmergencyTicket = "TKT-DEMOEMG1";

    /// <summary>Prefix for the fake Shaparak reference codes (filtered-UNIQUE column — each txn appends its
    /// scenario key).</summary>
    public const string GatewayRefPrefix = "demo-shaparak-";

    /// <summary>
    /// The booking scenario table. One row per engagement, keyed by <see cref="Key"/> (stable, greppable).
    /// Offsets are in days relative to seed time unless noted. A null <see cref="CompletedDaysAgo"/> means the
    /// booking never completed. The request behind every booking is <c>converted</c>; the request-only
    /// scenarios (pending/accepted/rejected/expired/cancelled) are seeded separately in the seeder.
    /// </summary>
    public static readonly BookingScenario[] Bookings =
    [
        // B1 — paid, upcoming, care instructions written; the "what does a fresh confirmed booking look like" case.
        new("upcoming", Customer: 0, Nurse: 0, VariantIndex: 0, ScheduledInDays: 3,
            ConfirmedDaysAgo: 1, CompletedDaysAgo: null, Cancelled: false, WithCareInstructions: true),

        // B2 — the multi-session package, mid-engagement today: 2 sessions done, session 3 checked-in now.
        new("in_progress", Customer: 0, Nurse: 0, VariantIndex: -1 /* the seeded package variant */, ScheduledInDays: 0,
            ConfirmedDaysAgo: 4, CompletedDaysAgo: null, Cancelled: false, WithCareInstructions: true),

        // B3 — completed yesterday: dispute window still open, review still pending moderation.
        new("completed_in_window", Customer: 0, Nurse: 0, VariantIndex: 2, ScheduledInDays: -1,
            ConfirmedDaysAgo: 3, CompletedDaysAgo: 1, Cancelled: false, WithCareInstructions: false),

        // B4 — completed long ago, paid out, carries the published 5★ review.
        new("completed_paid", Customer: 0, Nurse: 0, VariantIndex: 0, ScheduledInDays: -10,
            ConfirmedDaysAgo: 12, CompletedDaysAgo: 10, Cancelled: false, WithCareInstructions: false),

        // B5 — completed, window closed, waiting in the draft batch; carries the hidden 1★ review + the
        //      out-of-range EVV check-in that feeds the admin EVV queue.
        new("completed_eligible", Customer: 1, Nurse: 1, VariantIndex: 0, ScheduledInDays: -5,
            ConfirmedDaysAgo: 7, CompletedDaysAgo: 5, Cancelled: false, WithCareInstructions: false),

        // B6 — paid via BNPL (settled net-of-fee), then disputed: a processing bnpl_revert refund excludes it
        //      from every payout batch.
        new("bnpl_settled", Customer: 1, Nurse: 1, VariantIndex: 1, ScheduledInDays: -6,
            ConfirmedDaysAgo: 8, CompletedDaysAgo: 6, Cancelled: false, WithCareInstructions: false),

        // B7 — cancelled ≥24h ahead (standard_24h, 100%): the succeeded card refund.
        new("cancelled_refunded", Customer: 0, Nurse: 0, VariantIndex: 2, ScheduledInDays: 2,
            ConfirmedDaysAgo: 3, CompletedDaysAgo: null, Cancelled: true, WithCareInstructions: false),

        // C8 — completed + paid out, then refunded: the post-payout clawback case.
        new("clawback", Customer: 0, Nurse: 0, VariantIndex: 1, ScheduledInDays: -11,
            ConfirmedDaysAgo: 13, CompletedDaysAgo: 11, Cancelled: false, WithCareInstructions: false),
    ];
}

/// <summary>One booking scenario row. <see cref="Customer"/>/<see cref="Nurse"/> index into
/// <see cref="DemoWorldDefinitions.Customers"/>/<see cref="DemoWorldDefinitions.Nurses"/>;
/// <see cref="VariantIndex"/> indexes the nurse's variants in creation order (−1 = the seeded 5-session
/// package variant).</summary>
internal sealed record BookingScenario(
    string Key,
    int Customer,
    int Nurse,
    int VariantIndex,
    int ScheduledInDays,
    int ConfirmedDaysAgo,
    int? CompletedDaysAgo,
    bool Cancelled,
    bool WithCareInstructions);
