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

/// <summary>One raw eligible booking the batch build consumes: which nurse earned it and this booking's payout
/// portion (IRR). Grouped by nurse in the handler to compute <c>gross_earnings_irr</c>.</summary>
public record EligibleBookingRow(long NurseId, long BookingId, long PayoutAmountIrr);

/// <summary>The eligibility preview row — per-nurse earnings for the window, the pending clawback that would be
/// netted, the resulting net, and whether the nurse has a verified primary IBAN to receive it (a nurse without
/// one is <b>flagged</b>, not silently dropped). Money crosses the wire as digit strings.</summary>
public record EligibleNurseEarningsDto(
    long NurseId,
    string? NurseName,
    int BookingCount,
    string GrossEarningsIrr,
    string ClawbackAppliedIrr,
    string NetAmountIrr,
    bool HasVerifiedPrimaryIban);

/// <summary>A batch header — periods (holiday-shifted), totals, status, and reconciliation timestamps.
/// Money is a digit string.</summary>
public record PayoutBatchDto(
    long Id,
    DateOnly PeriodStart,
    DateOnly PeriodEnd,
    DateOnly ProcessingDate,
    string TotalAmount,
    int PayoutCount,
    string Status,
    int? InitiatedByAdminId,
    DateTime? ProcessedAt,
    string? FailureNotes,
    DateTimeOffset CreatedAt);

/// <summary>The booking a payout covers — with the per-booking amount and (future) session id. Money is a digit
/// string.</summary>
public record PayoutBookingLinkDto(long BookingId, long? SessionId, string PayoutAmountIrr);

/// <summary>One payout in a batch detail — the decomposed amounts, status, the <b>masked</b> IBAN + transfer
/// reference, and the bookings it covers. Money is a digit string.</summary>
public record PayoutDto(
    long Id,
    long NurseId,
    string? NurseName,
    string MaskedIban,
    string GrossEarningsIrr,
    string ClawbackAppliedIrr,
    string NetAmountIrr,
    string Amount,
    int BookingCount,
    string Status,
    string? TransferReference,
    DateTime? PaidAt,
    string? FailureReason,
    IReadOnlyList<PayoutBookingLinkDto> Bookings);

/// <summary>A batch header plus its paginated payouts — the admin reconciliation detail view.</summary>
public record PayoutBatchDetailDto(PayoutBatchDto Batch, IReadOnlyList<PayoutDto> Payouts, int Total, int Page, int PageSize);

/// <summary>A nurse skipped during a batch build, with the reason — never silently dropped (the common case is
/// "no verified primary IBAN"). Money is a digit string.</summary>
public record SkippedNurseDto(long NurseId, string? NurseName, string GrossEarningsIrr, string Reason);

/// <summary>What <c>GeneratePayoutBatchCommand</c> returns — the draft batch, the materialized payouts for admin
/// preview, and the nurses skipped (with reasons).</summary>
public record GeneratePayoutBatchResult(
    PayoutBatchDto Batch,
    IReadOnlyList<PayoutDto> Payouts,
    IReadOnlyList<SkippedNurseDto> Skipped);

/// <summary>What <c>ExecutePayoutBatchCommand</c> returns — the settled batch status and per-outcome counts.</summary>
public record ExecutePayoutBatchResult(long BatchId, string Status, int PaidCount, int FailedCount, string TotalPaid);

/// <summary>A nurse's own payout-history row (tenancy-scoped) — status, net, the <b>masked</b> IBAN + reference,
/// the clawback that was applied, and the batch window it belongs to. Money crosses the wire as digit strings.</summary>
public record NursePayoutHistoryDto(
    long Id,
    long BatchId,
    string Status,
    string GrossEarningsIrr,
    string ClawbackAppliedIrr,
    string NetAmountIrr,
    string MaskedIban,
    string? TransferReference,
    DateTime? PaidAt,
    DateOnly PeriodStart,
    DateOnly PeriodEnd,
    string? FailureReason);

/// <summary>The nurse's four-bucket earnings balance + the ledger-derived <b>signed</b> net payable (may be
/// negative = "owed back"; never clamped). <c>paidTotalIrr</c> is a lifetime total and does NOT enter the net.
/// All money is IRR digit-strings.</summary>
public record NurseEarningsBalanceDto(
    string PendingTotalIrr,
    string EligibleTotalIrr,
    string PaidTotalIrr,
    string ClawbackOutstandingIrr,
    string NetPayableBalanceIrr);

/// <summary>One per-booking earnings row with its server-derived money-state
/// (<c>pending|eligible|paid|clawback_applied</c>). Money is IRR digit-strings.</summary>
public record NurseEarningsItemDto(
    long BookingId,
    string? PatientName,
    DateOnly ScheduledDate,
    string GrossPriceIrr,
    string BalinyaarCommissionIrr,
    string NursePayoutAmount,
    string State,
    DateTime? DisputeWindowEndsAt,
    DateTime? PayoutEligibleAt,
    DateTime? PaidAt,
    string? TransferReference,
    long? NursePayoutId,
    long? BatchId,
    string? ClawbackAppliedIrr,
    string? NetAmountIrr);

/// <summary>A nurse-scoped payout detail — the payout + its batch window + the bookings it covers, for
/// reconciliation. Money is IRR digit-strings.</summary>
public record NursePayoutDetailDto(
    long Id,
    long BatchId,
    string Status,
    string GrossEarningsIrr,
    string ClawbackAppliedIrr,
    string NetAmountIrr,
    string AmountIrr,
    string MaskedIban,
    string? TransferReference,
    DateTime? PaidAt,
    string? FailureReason,
    PayoutBatchDto Batch,
    IReadOnlyList<PayoutBookingLinkDto> Bookings);

/// <summary>The stable nurse-facing earnings-state codes.</summary>
public static class NurseEarningsState
{
    public const string Pending = "pending";
    public const string Eligible = "eligible";
    public const string Paid = "paid";
    public const string ClawbackApplied = "clawback_applied";
}
