#nullable enable
using Baya.Application.Models.Identity;
using Baya.Domain.Entities.Identity;

namespace Baya.Application.Contracts.Persistence;

public interface INurseBankAccountRepository
{
    Task AddAsync(NurseBankAccount account, CancellationToken cancellationToken);

    /// <summary>Tracked, tenancy-scoped lookup — returns the account only if it belongs to
    /// <paramref name="nurseId"/>, else null.</summary>
    Task<NurseBankAccount?> GetOwnedAsync(long id, long nurseId, CancellationToken cancellationToken);

    /// <summary>Atomically makes <paramref name="accountId"/> the nurse's primary account and clears any
    /// prior primary, in a single transaction (clear-then-set order) so the filtered
    /// <c>UNIQUE(nurse_id) WHERE is_primary = 1</c> index never trips. The account must already be owned
    /// by the nurse — the caller verifies tenancy first.</summary>
    Task SetPrimaryAsync(long nurseId, long accountId, CancellationToken cancellationToken);

    /// <summary>Whether any account already carries this deterministic IBAN hash — the clean duplicate
    /// guard (the <c>UNIQUE(iban_hash)</c> index is the authoritative backstop).</summary>
    Task<bool> IbanHashExistsAsync(string ibanHash, CancellationToken cancellationToken);

    /// <summary>Whether the nurse already has at least one account (decides whether a new one defaults to
    /// primary).</summary>
    Task<bool> HasAnyAsync(long nurseId, CancellationToken cancellationToken);

    /// <summary>Tracked primary account for the nurse (the payout destination the verification bank-ownership
    /// step re-checks) — null if the nurse has no primary account yet.</summary>
    Task<NurseBankAccount?> GetPrimaryAsync(long nurseId, CancellationToken cancellationToken);

    /// <summary>No-tracking projection of the nurse's accounts with the IBAN masked (last 4 only).</summary>
    Task<IReadOnlyList<NurseBankAccountDto>> ListAsync(long nurseId, CancellationToken cancellationToken);
}
