#nullable enable
namespace Baya.Application.Models.Booking;

/// <summary>
/// The full booking view returned by convert/detail/transition/cancel. Money crosses the wire as strings of
/// IRR-Rial digits (integer money, no floats). The <b>nurse</b> view omits the encrypted address snapshot;
/// the <b>customer/admin</b> view includes it. Care-instruction clinical fields are <b>never</b> here — they
/// live behind the gated care-instructions read.
/// </summary>
public record BookingDetailDto(
    long Id,
    long BookingRequestId,
    string Status,
    long NurseId,
    string NurseName,
    long PatientId,
    string PatientName,
    long VariantId,
    string VariantSnapshotJson,
    long CustomerAddressId,
    string? AddressSnapshotJson,
    string GrossPriceIrr,
    string BalinyaarCommissionIrr,
    decimal PlatformFeeRate,
    string NursePayoutAmount,
    string? PspFeeAmount,
    short SessionCount,
    DateOnly ScheduledDate,
    TimeOnly ScheduledTimeStart,
    TimeOnly ScheduledTimeEnd,
    DateTime? ConfirmedAt,
    DateTime? CompletedAt,
    DateTime? CancelledAt,
    string? CancelledBy,
    string? CancellationReason,
    string? CancellationPolicyCode,
    decimal? CancellationRefundPercentage,
    string? RefundableAmountIrr,
    DateTime? DisputeWindowEndsAt,
    DateTimeOffset CreatedAt,
    IReadOnlyList<BookingSessionSummaryDto> Sessions);

/// <summary>Per-visit summary embedded in the booking detail — schedule, status, payout, and EVV state.</summary>
public record BookingSessionSummaryDto(
    long Id,
    int SessionIndex,
    DateOnly ScheduledDate,
    TimeOnly ScheduledTimeStart,
    TimeOnly ScheduledTimeEnd,
    string Status,
    string VisitPayoutAmount,
    DateTime? PayoutEligibleAt,
    string EvvStatus,
    DateTime? CheckInAt,
    DateTime? CheckOutAt,
    bool? CheckInAddressMatch);

/// <summary>The role-scoped "My bookings" list item — counterparty is the nurse (customer view) or the
/// patient (nurse view); <see cref="AmountIrr"/> is the gross (customer) or the payout (nurse).</summary>
public record BookingListItemDto(
    long Id,
    string Status,
    string CounterpartyName,
    DateOnly ScheduledDate,
    short SessionCount,
    string AmountIrr,
    DateTime? DisputeWindowEndsAt,
    DateTimeOffset CreatedAt);

/// <summary>The nurse's "today" session-list item, with the per-session check-in/out CTA state.</summary>
public record BookingSessionListItemDto(
    long SessionId,
    long BookingId,
    int SessionIndex,
    string PatientName,
    DateOnly ScheduledDate,
    TimeOnly ScheduledTimeStart,
    TimeOnly ScheduledTimeEnd,
    string Status,
    string EvvStatus);

/// <summary>The decrypted stage-2 clinical fields — returned <b>only</b> to the assigned nurse + admin,
/// <b>only</b> post-confirmation. Never projected into a list or logged.</summary>
public record CareInstructionsDto(
    long BookingId,
    string? CurrentConditions,
    string? Medications,
    string? Allergies,
    string? SpecialInstructions,
    string? EmergencyContactName,
    string? EmergencyContactPhone);

/// <summary>Per-session EVV detail — raw GPS gated to the owning nurse + admin.</summary>
public record VisitVerificationDto(
    long Id,
    long BookingSessionId,
    string Status,
    DateTime? CheckInAt,
    decimal? CheckInLat,
    decimal? CheckInLng,
    DateTime? CheckOutAt,
    decimal? CheckOutLat,
    decimal? CheckOutLng,
    bool? CheckInAddressMatch,
    decimal? CheckInDistanceMeters);

/// <summary>An item in the admin EVV-review queue (location mismatch or no-show).</summary>
public record AdminEvvItemDto(
    long SessionId,
    long BookingId,
    long NurseId,
    string SessionStatus,
    DateOnly ScheduledDate,
    TimeOnly ScheduledTimeStart,
    DateTime? CheckInAt,
    bool? CheckInAddressMatch,
    decimal? CheckInDistanceMeters);

/// <summary>Admin-facing cancellation-policy row.</summary>
public record CancellationPolicyDto(
    long Id,
    string Code,
    string AppliesTo,
    int? HoursBeforeStartMin,
    int? HoursBeforeStartMax,
    decimal RefundPercentage,
    string FeeAmountIrr,
    decimal? FeeRate,
    bool IsActive);

/// <summary>The outcome of a cancellation — the frozen policy snapshot + computed refundable amount. No
/// refund ledger is posted here (that is b11); this is the figure b11 will consume.</summary>
public record CancellationResultDto(
    long BookingId,
    long? SessionId,
    string BookingStatus,
    string PolicyCode,
    decimal RefundPercentage,
    string RefundableAmountIrr);

/// <summary>How many sessions the no-show sweep flagged (idempotent — re-running with none returns zero).</summary>
public record NoShowSweepResult(int Missed);
