Source: ZEventsApiEChecks/ZEventsApiEChecks.js

import ifPromise from 'onyx-common/ifPromise'
import stripWhitespace from 'onyx-common/stripWhitespace'

const ZEventsApi = ({ prototype }) => {
  prototype.normalizeAccountNumber = function (accountNumber) {
    return stripWhitespace(accountNumber)
  }

  prototype.encryptECheck = function (accountNumber) {
    const finalAccountNumber = this.normalizeAccountNumber(accountNumber)
    return this.encrypt({ input: finalAccountNumber })
  }

  prototype.maskAccountNumber = function (accountNumber) {
    const finalAccountNumber = this.normalizeAccountNumber(accountNumber)
    return this.getLastFour(finalAccountNumber)
  }

  prototype.normalizeBankAccount = function (entry) {
    const data = this.normalizeData(entry)

    const mapBankAccount = {
      id: ['id', val => parseInt(val)],
      account_holder_name: 'accountHolderName',
      default: ['isDefault', val => !!val],
      masked_bank_account_number: 'lastFour'
    }

    return this.filterAndMapProps(data, mapBankAccount)
  }

  prototype._createECheck = function ({ userId, ...rest }) {
    const payload = {
      url: this.getUrl(`/api/v1/users/${userId}/echecks`),
      method: 'POST',
      requestType: 'json',
      data: rest
    }

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @typedef {object} BankAccount
   * @property {number} id - credit card id
   * @property {string} accountHolderName - name of account holder
   * @property {string} lastFour - last four digits of account
   * @property {boolean} isDefault - is this the default payment method?
   */

  /**
   * @function createECheck
   * @param {object} payload - The eCheck payload
   * @param {string} [payload.userId='me'] - userid to assign this echeck
   * @param {string} [payload.nickname] - nickname for account
   * @param {string} payload.accountHolderName - name of account holder
   * @param {string} payload.routingNumber - routing number of account
   * @param {string} payload.accountNumber - account number of account
   * @param {boolean} payload.isDefault - whether or not default
   * @returns {BankAccount} - new bank account entitty
   * @example
   *
   * createECheck({
   *   nickname: 'Primary Checking',
   *   accountHolderName: 'Joe Jones',
   *   routingNumber: '1212121212121',
   *   accountNumber: '123444332422223'
   * })
   */
  prototype.createECheck = function (payload) {
    const {
      userId,
      nickname,
      accountHolderName,
      routingNumber,
      accountNumber,
      isDefault
    } = payload

    const finalPayload = {
      userId: this.normalizeUserId(userId),
      echeck: {
        description: nickname,
        account_holder_name: accountHolderName,
        routing_number: routingNumber,
        encrypted_bank_account_number: this.encryptECheck(accountNumber),
        masked_bank_account_number: this.maskAccountNumber(accountNumber),
        default: isDefault
      }
    }

    const raw = ifPromise(payload, () => this._createECheck(finalPayload))
    return raw
      .then(res => this.normalizeBankAccount(res.data))
      .catch(error => this.onError('createECheck', error))
  }

  prototype._deleteECheck = function ({ userId, id }) {
    const payload = {
      url: this.getUrl(`/api/v1/users/${userId}/echecks/${id}`),
      method: 'DELETE'
    }

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function deleteECheck
   * @param {object} payload - The eCheck payload
   * @param {string} [payload.userId='me'] - userid to assign this echeck
   * @param {number} payload.id - eCheck id
   * @returns {void}
   * @example
   *
   * deleteECheck({
   *   id: 1234
   * })
   */
  prototype.deleteECheck = function (payload) {
    const {
      userId,
      id
    } = payload

    const finalPayload = {
      userId: this.normalizeUserId(userId),
      id
    }

    const raw = ifPromise(payload, () => this._deleteECheck(finalPayload))
    return raw
      .catch(error => this.onError('deleteECheck', error))
  }

  prototype._getECheck = function ({ userId, id, ...rest }) {
    const payload = {
      url: this.getUrl(`/api/v1/users/${userId}/echecks/${id}`),
      method: 'GET',
      requestType: 'json',
      data: rest
    }

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function getECheck
   * @param {object} payload - The eCheck payload
   * @param {string} [payload.userId='me'] - userid to assign this echeck
   * @param {number} payload.id - eCheck id
   * @example
   *
   *     getECheck({
   *        id: 1234
   *     })
   */

  prototype.getECheck = function (payload) {
    const raw = ifPromise(payload, () => this._getECheck(payload))
    return raw
      .then(res => Promise.resolve(this.normalizeAndCamelize(res)))
      .catch(error => {
        Promise.reject(Error('loginError', error))
      })
  }

  prototype._getEChecks = function ({ userId, ...rest }) {
    const payload = {
      url: this.getUrl(`/api/v1/users/${userId}/echecks`),
      method: 'GET',
      requestType: 'json',
      data: rest
    }

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @typedef {object} getEchecksReturn
   * @property {number} id - echeck id
   * @property {string} accountHolderName - name on account
   * @property {string} lastFour - last for of account number
   * @property {string} isDefault - whether or not it's the default payment
   */

  /**
   * @function getEChecks
   * @param {object} payload - The eChecks payload
   * @param {string} [payload.userId='me'] - userid to assign this echeck
   * @param {number} [payload.page=0] - page of results
   * @returns {getEchecksReturn} - array of echeck objects
   * @example
   *
   *     getEChecks({
   *        page: 0
   *     })
   */

  prototype.getEChecks = function (payload) {
    const finalPayload = {
      page: payload?.page || 1
    }

    const raw = ifPromise(payload, () => this._getEChecks(finalPayload))
    return raw
      .then(res => {
        const normalizedListData = this.normalizeListData(res.data)
        return normalizedListData
      })
      .catch(error => this.onError('getEchecks', error))
  }

  prototype._setDefaultECheck = function ({ userId, id }) {
    const payload = {
      url: this.getUrl(`/api/v1/users/${userId}/echecks/${id}/set_default`),
      method: 'PUT'
    }

    return this.authenticatedFetchWrap(payload)
  }
  prototype.setDefaultECheck = function (payload) {
    const finalPayload = {
      id: payload.id,
      userId: this.normalizeUserId(payload.userId)
    }
    const raw = ifPromise(payload, () => this._setDefaultECheck(finalPayload))
    return raw
      .catch(error => this.onError('setDefaultECheck', error))
  }
}

export default ZEventsApi