Source: ZEventsApiPayoutMethods/ZEventsApiPayoutMethods.js

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

const ZEventsApiPayoutMethods = ({ prototype }) => {
  prototype.normalizePayoutMethod = function (_data) {
    const data = this.normalizeData(_data)

    const mapProps = {
      id: ['id', val => parseInt(val)],
      provider: 'provider',
      external_id: 'externalId',
      title: 'externalIdType',
      default: 'isDefault'
    }

    const ret = this.filterAndMapProps(data, mapProps)
    ret.isDefault = !!ret.isDefault

    return ret
  }

  prototype._getPayoutMethods = function ({ userId }) {
    const payload = {
      url: this.getUrl(`/api/v1/users/${userId}/payout_methods`),
      method: 'GET'
    }

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @typedef {object} getPayoutMethodsListSummary
   * @property {number} page - page of results
   * @property {number} perPage - results per page
   * @property {boolean} hasMore - are more pages available?
   */

  /**
   * @typedef {object} getPayoutMethodsReturn
   * @property {PayoutMethod[]} entries - list of users returned
   * @property {getPayoutMethodsListSummary} listSummary - list summary object
   * @property {object} criteriaSummary - criteria summary object (empty)
   */

  /**
   * @function getPayoutMethods
   * @param {object} payload - The payload object
   * @param {number} [payload.page=1] - page of result set
   * @returns {getPayoutMethodsReturn} searchUsersReturn
   * @example
   * getPayoutMethods({
   *   page: 1
   * })
   */

  prototype.getPayoutMethods = function (payload = {}) {
    const finalPayload = {
      userId: this.normalizeUserId(payload.userId)
    }
    const raw = ifPromise(payload, () => this._getPayoutMethods(finalPayload))
    return raw
      .then(res => this.normalizeListData(res.data, this.normalizePayoutMethod))
      // .catch(error => this.onError('getPayoutMethods', error))
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @typedef {object} PayoutMethod
   * @property {number} id - payout id
   * @property {string} provider - Venmo vs CashApp
   * @property {string} externalId - User identifier
   * @property {string} externalIdType - Type of identifier
   * @property {boolean} isDefault - whether or not it's the default payment
   */

  /**
   * @function createPayoutMethod
   * @param {object} payload - The user payload
   * @param {string} [payload.userId='me'] - user id
   * @param {string} payload.provider - Venmo vs CashApp
   * @param {string} payload.externalId - User identifier
   * @param {string} payload.externalIdType - Type of identifier
   * @param {boolean} payload.isDefault - whether or not it's the default payment
   * @returns {PayoutMethod} - payout method
   * @example
   *
   * createPayoutMethod({
   *   provider: 'venmo',
   *   externalId: 'andy123',
   *   externalIdType: 'username',
   *   isDefault: false
   * })
   */

  prototype.createPayoutMethod = function (payload) {
    const {
      userId,
      ...rest
    } = payload

    if (hasKey(rest, 'isDefault')) rest.isDefault = !!rest.isDefault

    const mapProps = {
      provider: 'provider',
      externalId: 'external_id',
      externalIdType: 'title',
      isDefault: 'default'
    }

    const mappedData = this.filterAndMapProps(rest, mapProps)

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

    const raw = ifPromise(payload, () => this._createPayoutMethod(finalPayload))
    return raw
      .then(res => {
        const data = this.normalizeData(res.data)
        data.default = !!data.default

        const mapProps = {
          id: 'id',
          provider: 'provider',
          external_id: 'externalId',
          title: 'externalIdType',
          default: 'isDefault'
        }

        return this.filterAndMapProps(data, mapProps)
      })
      .catch(error => this.onError('createPayoutMethod', error))
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function getPayoutMethod
   * @param {object} payload - The user payload
   * @param {string} [payload.userId='me'] - user id
   * @param {number} payload.id - payout method id
   * @returns {PayoutMethod} - loggedIn user
   * @example
   *
   * getPayoutMethod({
   *   id: 123
   * })
   */

  prototype.getPayoutMethod = function (payload) {
    const finalPayload = {
      userId: this.normalizeUserId(payload.userId),
      id: payload.id
    }
    const raw = ifPromise(payload, () => this._getPayoutMethod(finalPayload))
    return raw
      .then(res => this.normalizePayoutMethod(res.data))
      .catch(error => this.onError('getPayoutMethod', error))
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function updatePayoutMethod
   * @param {object} payload - The user payload
   * @param {string} [payload.userId='me'] - user id
   * @param {string} payload.id - payout method id
   * @param {string} payload.provider - Venmo vs CashApp
   * @param {string} payload.externalId - User identifier
   * @param {string} payload.externalIdType - Type of identifier
   * @param {boolean} payload.isDefault - whether or not it's the default payment
   * @returns {PayoutMethod} - payout method
   * @example
   *
   * updatePayoutMethod({
   *   id: 123,
   *   provider: 'venmo',
   *   externalId: 'andy123',
   *   externalIdType: 'username',
   *   isDefault: false
   * })
   */

  prototype.updatePayoutMethod = function (payload) {
    const raw = ifPromise(payload, () => this._updatePayoutMethod(payload))
    return raw
      .then(res => this.normalizePayoutMethod(res.data))
      .catch(error => this.onError('updatePayoutMethod', error))
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function deletePayoutMethod
   * @param {object} payload - The user payload
   * @param {string} [payload.userId='me'] - user id
   * @param {number} payload.id - payout method id
   * @returns {void}
   * @example
   *
   * deletePayoutMethod({
   *   id: 123
   * })
   */

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

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function setDefaultPayoutMethod
   * @param {object} payload - The payload
   * @param {string} [payload.userId='me'] - user id
   * @param {number} payload.id - payout method id
   * @returns {void}
   * @example
   *
   * setDefaultPayoutMethod({
   *   id: 123
   * })
   */

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

export default ZEventsApiPayoutMethods