/**
 * Account and Transaction API SpecificationLib
 *
 * This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ).
 */

import { array, lazy, object, optional, Schema, string } from '../schema';
import { Amount, amountSchema } from './amount';
import { Balance, balanceSchema } from './balance';
import {
  BankTransactionCode,
  bankTransactionCodeSchema,
} from './bankTransactionCode';
import { CardInstrument, cardInstrumentSchema } from './cardInstrument';
import {
  CreditDebitIndicatorEnum,
  creditDebitIndicatorEnumSchema,
} from './creditDebitIndicatorEnum';
import { CreditorAccount, creditorAccountSchema } from './creditorAccount';
import { CreditorAgent, creditorAgentSchema } from './creditorAgent';
import { CurrencyExchange, currencyExchangeSchema } from './currencyExchange';
import { DebtorAccount, debtorAccountSchema } from './debtorAccount';
import { DebtorAgent, debtorAgentSchema } from './debtorAgent';
import { MerchantDetails, merchantDetailsSchema } from './merchantDetails';
import {
  ProprietaryBankTransactionCode,
  proprietaryBankTransactionCodeSchema,
} from './proprietaryBankTransactionCode';
import {
  TransactionReference,
  transactionReferenceSchema,
} from './transactionReference';
import {
  TransactionStatusEnum,
  transactionStatusEnumSchema,
} from './transactionStatusEnum';

export interface TransactionModel {
  /** A unique and immutable identifier used to identify the account resource. This identifier has no meaning to the account owner. */
  accountId: string;
  /** Unique identifier for the transaction within an servicing institution. This identifier is both unique and immutable. */
  transactionId?: string;
  transactionReference?: TransactionReference;
  /** Unique reference for the statement. This reference may be optionally populated if available. */
  statementReference?: string[];
  /** Amount of money of the cash balance. */
  amount: Amount;
  /** Indicates whether the balance is a credit or a debit balance. Usage: A zero balance is considered to be a credit balance. */
  creditDebitIndicator: CreditDebitIndicatorEnum;
  /** Status of a transaction entry on the books of the account servicer. */
  status: TransactionStatusEnum;
  /**
   * Date and time when a transaction entry is posted to an account on the account servicer's books. Usage: Booking date is the expected booking date, unless the status is booked, in which case it is the actual booking date.
   * All dates in the JSON payloads are represented in ISO 8601 date-time format.
   * All date-time fields in responses must include the timezone. An example is below:
   * 2017-04-05T10:43:07+00:00
   */
  bookingDateTime: string;
  /**
   * Date and time at which assets become available to the account owner in case of a credit entry, or cease to be available to the account owner in case of a debit entry.  Usage: If entry status is pending and value date is present, then the value date refers to an expected/requested value date. For entries subject to availability/float and for which availability information is provided, the value date must not be used. In this case the availability component identifies the  number of availability days.
   * All dates in the JSON payloads are represented in ISO 8601 date-time format.
   * All date-time fields in responses must include the timezone. An example is below:
   * 2017-04-05T10:43:07+00:00
   */
  valueDateTime?: string;
  /** Information that locates and identifies a specific address, as defined by postal services, that is presented in free format text. */
  addressLine?: string;
  /** Set of elements used to fully identify the type of underlying transaction resulting in an entry. */
  bankTransactionCode?: BankTransactionCode;
  /** Set of elements to fully identify a proprietary bank transaction code. */
  proprietaryBankTransactionCode?: ProprietaryBankTransactionCode;
  /** Set of elements used to provide details on the currency exchange. */
  currencyExchange?: CurrencyExchange;
  /**
   * Party that manages the account on behalf of the account owner, that is manages the registration and booking of entries on the account, calculates balances on the account and provides information about the account.
   * This is the servicer of the beneficiary account.
   */
  creditorAgent?: CreditorAgent;
  /** Financial institution servicing an account for the debtor. */
  debtorAgent?: DebtorAgent;
  /** Set of elements to describe the card instrument used in the transaction. */
  cardInstrument?: CardInstrument;
  /** Further details of the transaction. This is the transaction narrative, which is unstructured text. */
  transactionInformation?: string;
  /** Set of elements used to define the balance as a numerical representation of the net increases and decreases in an account after a transaction entry is applied to the account. */
  balance?: Balance;
  /** Details of the merchant involved in the transaction. */
  merchantDetails?: MerchantDetails;
  /** Unambiguous identification of the account of the creditor, in the case of a debit transaction. */
  creditorAccount?: CreditorAccount;
  /** Unambiguous identification of the account of the debtor, in the case of a crebit transaction. */
  debtorAccount?: DebtorAccount;
}

export const transactionModelSchema: Schema<TransactionModel> = object({
  accountId: ['AccountId', string()],
  transactionId: ['TransactionId', optional(string())],
  transactionReference: [
    'TransactionReference',
    optional(lazy(() => transactionReferenceSchema)),
  ],
  statementReference: ['StatementReference', optional(array(string()))],
  amount: ['Amount', lazy(() => amountSchema)],
  creditDebitIndicator: [
    'CreditDebitIndicator',
    creditDebitIndicatorEnumSchema,
  ],
  status: ['Status', transactionStatusEnumSchema],
  bookingDateTime: ['BookingDateTime', string()],
  valueDateTime: ['ValueDateTime', optional(string())],
  addressLine: ['AddressLine', optional(string())],
  bankTransactionCode: [
    'BankTransactionCode',
    optional(lazy(() => bankTransactionCodeSchema)),
  ],
  proprietaryBankTransactionCode: [
    'ProprietaryBankTransactionCode',
    optional(lazy(() => proprietaryBankTransactionCodeSchema)),
  ],
  currencyExchange: [
    'CurrencyExchange',
    optional(lazy(() => currencyExchangeSchema)),
  ],
  creditorAgent: ['CreditorAgent', optional(lazy(() => creditorAgentSchema))],
  debtorAgent: ['DebtorAgent', optional(lazy(() => debtorAgentSchema))],
  cardInstrument: [
    'CardInstrument',
    optional(lazy(() => cardInstrumentSchema)),
  ],
  transactionInformation: ['TransactionInformation', optional(string())],
  balance: ['Balance', optional(lazy(() => balanceSchema))],
  merchantDetails: [
    'MerchantDetails',
    optional(lazy(() => merchantDetailsSchema)),
  ],
  creditorAccount: [
    'CreditorAccount',
    optional(lazy(() => creditorAccountSchema)),
  ],
  debtorAccount: ['DebtorAccount', optional(lazy(() => debtorAccountSchema))],
});
