Source: ZEventsApiSpeakerProfiles/ZEventsApiSpeakerProfiles.js

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

const ZEventsApiSpeakerProfile = ({ prototype }) => {
  prototype.normalizeSpeakerProfile = function (_data) {
    const data = this.normalizeData(_data)

    const mapProps = {
      id: ['id', val => parseInt(val)],
      name: 'name',
      about: 'about',
      email: 'email',
      avatar_url: 'avatarUrl'
    }

    return this.filterAndMapProps(data, mapProps)
  }

  prototype.normalizeSpeakerProfileOrUser = function (_data) {
    const data = this.normalizeData(_data)

    const ret = {
      id: parseInt(data.id),
      firstName: data.firstname,
      lastName: data.lastname,
      isKwivrrUser: !!data.is_kwivrr_user,
      avatarUrl: data.image_url
    }

    return ret
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @typedef {object} SpeakerProfile
   * @property {number} id - credit card id
   * @property {string} name - name of account holder
   * @property {string} about - last four digits of account
   * @property {string} email - is this the default payment method?
   * @property {string} avatarUrl - is this the default payment method?
   */

  /**
   * @function createSpeakerProfile
   * @param {object} payload - The payload
   * @param {string} [payload.userId='me'] - user id
   * @param {string} payload.name - speaker's name
   * @param {string} payload.email - speaker's email
   * @param {string} payload.about - about the speaker
   * @param {string} [payload.avatarUrl] - avatar image url
   * @param {string} [payload.avatarBase64] - uploaded avatar image (takes precedent over avatarUrl)
   * @returns {SpeakerProfile} - speaker profile object
   * @example
   *
   * createSpeakerProfile({
   *   name: 'Mitch Cain',
   *   email: 'mitch.cain@icentris.com',
   *   about: 'password',
   *   avatarUrl: 'https://imgur.com/coolphoto.jpg'
   * })
   */

  prototype.createSpeakerProfile = function (payload) {
    const {
      userId,
      avatarUrl,
      description,
      name,
      email
    } = payload

    const finalPayload = {
      userId: this.normalizeUserId(userId),
      name: name,
      about: description,
      email
    }

    if (hasKey(payload, 'avatarUrl')) finalPayload.avatar_url = avatarUrl
    if (hasKey(payload, 'avatarBase64')) finalPayload.avatar_base64 = payload.avatarBase64

    const raw = ifPromise(payload, () => this._createSpeakerProfile(finalPayload))
    return raw
      .then(res => this.normalizeSpeakerProfile(res.data))
      .catch(error => this.onError('createSpeakerProfile', error))
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function deleteSpeakerProfile
   * @param {object} payload - The payload
   * @param {string} [payload.userId='me'] - user id
   * @param {number} payload.id - speaker profile id
   * @returns {void}
   * @example
   *
   * deleteSpeakerProfile({
   *   id: 1
   * })
   */

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

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function getSpeakerProfile
   * @param {object} payload - The payload
   * @param {string} [payload.userId='me'] - user id
   * @param {number} payload.id - speaker profile id
   * @returns {SpeakerProfile} -  speaker profile
   * @example
   *
   * getSpeakerProfile({
   *   id: 1
   * })
   */
  prototype.getSpeakerProfile = function (payload) {
    const finalPayload = {
      userId: this.normalizeUserId(payload.userId),
      id: payload.id
    }
    const raw = ifPromise(payload, () => this._getSpeakerProfile(finalPayload))
    return raw
      .then(res => this.normalizeSpeakerProfile(res.data))
      .catch(error => this.onError('getSpeakerProfile', error))
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function getSpeakerProfiles
   * @param {object} payload - The payload object
   * @param {string} [payload.userId='me'] - user id context
   * @param {number} [payload.page=1] - page of results
   * @returns {SpeakerProfile[]} speakerProfiles
   * @example
   *
   * getSpeakerProfiles({
   *   page: 1
   * })
   */
  prototype.getSpeakerProfiles = function (payload = {}) {
    const {
      userId,
      page
    } = payload

    const finalPayload = {
      userId: this.normalizeUserId(userId),
      page: page || 1
    }

    const raw = ifPromise(payload, () => this._getSpeakerProfiles(finalPayload))
    return raw
      .then(res => this.normalizeListData(res.data, this.normalizeSpeakerProfile).entries) // AS: this needs pagerized
      .catch(error => this.onError('getSpeakerProfiles', error))
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @typedef {object} SpeakerProfileOrUser
   * @property {number} id - entity id
   * @property {string} firstName - first name
   * @property {string} lastName - last name
   * @property {string} email - email
   * @property {boolean} isKwivvrUser - is "id" a kwivrr account id or a speaker profile id?
   */

  /**
   * @typedef {object} getSearchSpeakerSummary
   * @property {number} page - page of results
   * @property {number} perPage - results per page
   * @property {boolean} hasMore - are more pages available?
   * @property {string} term - term searched against
   */

  /**
   * @typedef {object} getSearchSpeakerReturn
   * @property {SpeakerProfileOrUser[]} entries - list of speaker profile ids returned
   * @property {getSearchSpeakerSummary} listSummary - list summary object
   * @property {object} criteriaSummary - criteria summary object (empty)
   */

  /**
   * @function searchSpeakerProfilesAndUsers
   * @param {object} payload - The searchSpeakerProfiles payload
   * @param {string} [payload.userId='me'] - user id to scope against
   * @param {string} payload.term - term to filter against
   * @returns {getSearchSpeakerReturn} - searchSpeakersReturn
   * @example
   *
   *    searchSpeakerProfilesAndUsers({
   *     userId: 1,
   *     term: "stu",
   *    })
   */
  prototype.searchSpeakerProfilesAndUsers = function (payload) {
    const finalPayload = {
      userId: this.normalizeUserId(payload.userId),
      term: payload.term,
      page: payload?.page || 1
    }
    const raw = ifPromise(payload, () => this._searchSpeakerProfilesAndUsers(finalPayload))
    return raw
      .then(res => this.normalizeListDataDirect(res.data, this.normalizeSpeakerProfileOrUser))
      .catch(error => this.onError('searchSpeakerProfiles', error))
  }

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

    return this.authenticatedFetchWrap(payload)
  }

  /**
   * @function updateSpeakerProfile
   * @param {object} payload - The searchSpeakerProfiles payload
   * @param {string} [payload.userId='me'] - userId profile belongs to
   * @param {string} payload.id - speaker profile id
   * @param {string} payload.name - speaker's name
   * @param {string} payload.email - speaker's email
   * @param {string} payload.about - about the speaker
   * @param {string} [payload.avatarUrl] - avatar image url
   * @param {string} [payload.avatarBase64] - uploaded avatar image (takes precedent over avatarUrl)
   * @example
   * updateSpeakerProfile({
   *   id: 11
   *   name: 'Mitch Cain',
   *   email: 'mitch.cain@icentris.com',
   *   about: 'password',
   *   avatarUrl: 'https://imgur.com/coolphoto.jpg'
   * })
   * @returns {SpeakerProfile} - speaker profile object
   */
  prototype.updateSpeakerProfile = function (payload) {
    const raw = ifPromise(payload, () => this._updateSpeakerProfile(payload))
    return raw
      .then(res => this.normalizeSpeakerProfile(res.data))
      .catch(error => this.onError('updateSpeakerProfile', error))
  }
}

export default ZEventsApiSpeakerProfile