/**
 * Shell Card Management APIsLib
 *
 * This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ).
 */

import { ApiResponse, RequestOptions } from '../core.js';
import { AccountReq, accountReqSchema } from '../models/accountReq.js';
import { AccountRes, accountResSchema } from '../models/accountRes.js';
import { AuditReq, auditReqSchema } from '../models/auditReq.js';
import { AuditResponse, auditResponseSchema } from '../models/auditResponse.js';
import { CardGroupReq, cardGroupReqSchema } from '../models/cardGroupReq.js';
import { CardGroupRes, cardGroupResSchema } from '../models/cardGroupRes.js';
import { CardTypeReq, cardTypeReqSchema } from '../models/cardTypeReq.js';
import { CardTypeRes, cardTypeResSchema } from '../models/cardTypeRes.js';
import {
  CreateCardGroupRequest,
  createCardGroupRequestSchema,
} from '../models/createCardGroupRequest.js';
import {
  CreateCardGroupRes,
  createCardGroupResSchema,
} from '../models/createCardGroupRes.js';
import { CustomerReq, customerReqSchema } from '../models/customerReq.js';
import { CustomerRes, customerResSchema } from '../models/customerRes.js';
import {
  LoggedInUserReq,
  loggedInUserReqSchema,
} from '../models/loggedInUserReq.js';
import {
  LoggedInUserRes,
  loggedInUserResSchema,
} from '../models/loggedInUserRes.js';
import { PayerReq, payerReqSchema } from '../models/payerReq.js';
import { PayerRes, payerResSchema } from '../models/payerRes.js';
import {
  UpdateCardGroupRequest,
  updateCardGroupRequestSchema,
} from '../models/updateCardGroupRequest.js';
import {
  UpdateCardGroupRes,
  updateCardGroupResSchema,
} from '../models/updateCardGroupRes.js';
import { optional, string } from '../schema.js';
import { BaseController } from './baseController.js';
import { ErrorObjectError } from '../errors/errorObjectError.js';

export class CustomerController extends BaseController {
  /**
   * This operation allows querying the user data of the logged in user.
   * This operation should be called only after successful authentication of the end user in client
   * application. This operation will return the user access details such as payers and/or accounts.
   * This operation will also validate that logged in user has access to the requested operation, on
   * failure it will return HasAPIAccess flag as false in the response.
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for requests and
   *                                               responses. This will be played back in the response from the request.
   * @param body
   * @return Response from the API call
   */
  async loggedinUser(
    requestId: string,
    body: LoggedInUserReq,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<LoggedInUserRes>> {
    const req = this.createRequest('POST', '/user-management/v1/loggedinuser');
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, loggedInUserReqSchema],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(loggedInUserResSchema, requestOptions);
  }

  /**
   * This API allows querying the payer accounts details from the Shell Cards
   * Platform. It provides flexible search criteria for searching payer
   * information and supports paging.
   *
   * Paging is applicable only when all the
   * payers passed in the input are from the same ColCo.
   *
   * However, paging will
   * be ignored and the API will return all the matching data by merging the
   * data queried from each ColCo when payers passed in the input are from
   * multiple ColCos.
   *
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for requests and
   *                                        responses. This will be played back in the response from the request.
   * @param body
   * @return Response from the API call
   */
  async customerPayers(
    requestId: string,
    body: PayerReq,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<PayerRes>> {
    const req = this.createRequest('POST', '/customer-management/v1/payers');
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, payerReqSchema],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(payerResSchema, requestOptions);
  }

  /**
   * This API allows querying the card delivery addresses of a given account from the Shell Cards
   * Platform. Only active delivery addresses will be returned.
   *
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for requests and
   *                                           responses. This will be played back in the response from the request.
   * @param body
   * @return Response from the API call
   */
  async customerDetail(
    requestId: string,
    body: CustomerReq,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<CustomerRes>> {
    const req = this.createRequest('POST', '/customer-management/v1/customer');
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, customerReqSchema],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(customerResSchema, requestOptions);
  }

  /**
   * This API allows querying the customer account details from the Shell Cards Platform. It provides a
   * flexible search criterion and supports pagination.
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for requests and
   *                                          responses. This will be played back in the response from the request.
   * @param body
   * @return Response from the API call
   */
  async postCardAccounts(
    requestId: string,
    body: AccountReq,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<AccountRes>> {
    const req = this.createRequest('POST', '/customer-management/v1/accounts');
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, accountReqSchema],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(accountResSchema, requestOptions);
  }

  /**
   * 
   * This API provides allows querying the active card types that are associated to the given account.
   *
   * The API returns the card type configurations, purchase categories associated with the card type and
   * the card type restriction limits.
   *
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for requests and
   *                                           responses. This will be played back in the response from the request.
   * @param body
   * @return Response from the API call
   */
  async customerCardType(
    requestId: string,
    body: CardTypeReq,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<CardTypeRes>> {
    const req = this.createRequest('POST', '/customer-management/v2/cardtype');
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, cardTypeReqSchema],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(cardTypeResSchema, requestOptions);
  }

  /**
   * This API allows querying the card group details from the Shell Cards
   * Platform. It provides flexible search criteria and supports paging.
   *
   * When the account is not passed in the input and card group type is configured as
   * â€˜Verticalâ€™ in the cards platform, this API will return all card groups from
   * the payer as well as from all the accounts under the payer.
   *
   * When the account is not passed in the input and card group type is configured as
   * â€˜Horizontalâ€™ in cards platform, this API will return all card groups
   * configured directly under the payer.
   *
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for requests and
   *                                            responses. This will be played back in the response from the request.
   * @param body
   * @return Response from the API call
   */
  async cardGroups(
    requestId: string,
    body: CardGroupReq,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<CardGroupRes>> {
    const req = this.createRequest(
      'POST',
      '/customer-management/v1/cardgroups'
    );
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, cardGroupReqSchema],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(cardGroupResSchema, requestOptions);
  }

  /**
   * This operation allows users to fetch audit data of account or card operations performed by users of
   * a given customer
   *
   * The audit data includes details of below API operations
   *
   *
   *
   * * Order Card
   *
   * * Create Card Group
   *
   * * PIN reminder
   *
   * * Move Cards
   *
   * * Update Card Status
   *
   * * Update Card Group
   *
   * * Auto renew
   *
   * * Bulk card order
   *
   * * Bulk card block
   *
   * * Bulk Card Order (Multi Account)
   *
   * * BCOSummary
   *
   * * BCOMultiAccountSummary
   *
   * * BCBSummary
   *
   * * Mobile Payment Registration
   *
   * * Fund Transfer (Scheduled & Realtime)
   *
   * * Delivery Address Update.
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for requests and
   *                                        responses. This will be played back in the response from the request.
   * @param body         request body
   * @return Response from the API call
   */
  async auditReport(
    requestId: string,
    body?: AuditReq,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<AuditResponse>> {
    const req = this.createRequest(
      'POST',
      '/customer-management/v1/auditreport'
    );
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, optional(auditReqSchema)],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(auditResponseSchema, requestOptions);
  }

  /**
   * This API allows creating a new Card Group in the Shell Cards Platform. It will
   * also allow moving of cards (up to 500 cards) into the newly created
   * card-group.
   *
   * Move Card requests are queued after
   * passing the below validations
   *
   * - Given PAN matches with only one
   * card.
   * - Card is allowed to be moved to the Target Card Group and/or
   * Target account requested.
   * - There is no pending Move Card request for
   * the same card in the queue which is submitted on the same date
   * (customerâ€™s local) and is yet to be processed or has been processed
   * successfully
   *
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for
   *                                                      requests and responses. This will be played back in the
   *                                                      response from the request.
   * @param body
   * @return Response from the API call
   */
  async customerCreateCardGroup(
    requestId: string,
    body: CreateCardGroupRequest,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<CreateCardGroupRes>> {
    const req = this.createRequest(
      'POST',
      '/customer-management/v1/createcardgroup'
    );
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, createCardGroupRequestSchema],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(createCardGroupResSchema, requestOptions);
  }

  /**
   * This API allows updating or removing a Card Group in the Shell Cards
   * Platform.
   *
   * It also allows moving of cards out of a card group or from one card group to another existing card
   * group.
   *
   * The request for updating or removing of the card group, creationg of a new card group (where-
   * applicable) and moving of card into another card group will be queued after passing the basic
   * validations.
   *
   *
   * @param requestId    Mandatory UUID (according to RFC 4122 standards) for
   *                                                      requests and responses. This will be played back in the
   *                                                      response from the request.
   * @param body
   * @return Response from the API call
   */
  async customerUpdateCardGroup(
    requestId: string,
    body: UpdateCardGroupRequest,
    requestOptions?: RequestOptions
  ): Promise<ApiResponse<UpdateCardGroupRes>> {
    const req = this.createRequest(
      'POST',
      '/customer-management/v1/updatecardgroup'
    );
    const mapped = req.prepareArgs({
      requestId: [requestId, string()],
      body: [body, updateCardGroupRequestSchema],
    });
    req.header('RequestId', mapped.requestId);
    req.header('Content-Type', 'application/json');
    req.json(mapped.body);
    req.throwOn(
      400,
      ErrorObjectError,
      'The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).'
    );
    req.throwOn(
      401,
      ErrorObjectError,
      'The request has not been applied because it lacks valid  authentication credentials for the target resource.'
    );
    req.throwOn(403, ErrorObjectError, 'Forbidden');
    req.throwOn(
      404,
      ErrorObjectError,
      'The origin server did not find a current representation  for the target resource or is not willing to disclose  that one exists.'
    );
    req.throwOn(
      500,
      ErrorObjectError,
      'The server encountered an unexpected condition that  prevented it from fulfilling the request.'
    );
    req.authenticate([{ bearerToken: true }]);
    return req.callAsJson(updateCardGroupResSchema, requestOptions);
  }
}
