namespace Books.Api.Banking;

/// <summary>
/// Client for Enable Banking Open Banking API
/// https://enablebanking.com/docs/api/reference/
/// </summary>
public interface IEnableBankingClient
{
    /// <summary>
    /// Get list of available ASPSPs (banks) for a country
    /// </summary>
    Task<IReadOnlyList<Aspsp>> GetAspspsAsync(string country = "DK", CancellationToken ct = default);

    /// <summary>
    /// Start authorization flow for connecting a bank account
    /// </summary>
    Task<AuthorizationResponse> StartAuthorizationAsync(
        string aspspName,
        string redirectUrl,
        string state,
        string psuType = "personal",
        string? psuIpAddress = null,
        string? psuUserAgent = null,
        CancellationToken ct = default);

    /// <summary>
    /// Complete authorization and create a session
    /// </summary>
    Task<SessionResponse> CreateSessionAsync(
        string authorizationCode,
        string? psuIpAddress = null,
        string? psuUserAgent = null,
        CancellationToken ct = default);

    /// <summary>
    /// Get account details
    /// </summary>
    Task<AccountDetails> GetAccountDetailsAsync(string sessionId, string accountId, CancellationToken ct = default);

    /// <summary>
    /// Get account balances
    /// </summary>
    Task<IReadOnlyList<Balance>> GetBalancesAsync(string sessionId, string accountId, CancellationToken ct = default);

    /// <summary>
    /// Get account transactions
    /// </summary>
    Task<TransactionsResponse> GetTransactionsAsync(
        string sessionId,
        string accountId,
        DateOnly? dateFrom = null,
        DateOnly? dateTo = null,
        CancellationToken ct = default);
}

// DTOs for Enable Banking API responses

public record Aspsp(
    string Name,
    string Country,
    string Logo,
    IReadOnlyList<string> PsuTypes,
    bool BusinessAccounts,
    bool PersonalAccounts);

public record AuthorizationResponse(
    string AuthorizationId,
    string Url);

public record SessionResponse(
    string SessionId,
    string AspspName,
    IReadOnlyList<SessionAccount> Accounts,
    DateTimeOffset ValidUntil);

public record SessionAccount(
    string AccountId,
    string Iban,
    string Currency,
    string? AccountName);

public record AccountDetails(
    string AccountId,
    string Iban,
    string Currency,
    string? Name,
    string? OwnerName,
    string? Product);

public record Balance(
    string BalanceType,
    decimal Amount,
    string Currency,
    DateTimeOffset? ReferenceDate);

public record TransactionsResponse(
    IReadOnlyList<Transaction> Transactions,
    string? ContinuationKey);

public record Transaction(
    string TransactionId,
    decimal Amount,
    string Currency,
    DateOnly BookingDate,
    DateOnly? ValueDate,
    string? CreditorName,
    string? DebtorName,
    string? RemittanceInformation,
    string? EndToEndId,
    bool IsDebit);
