import faker from '@faker-js/faker';
import { CreditCard } from '@flight-modal/model';
import { HttpRequest } from '@support-base/http_request';
import { Accept } from '@support-base/request_header';
import { HttpStatusCodes } from '@support-base/status_code';
import { AccountRegistrationClient } from '@support-onboard/lib';
import { Timeouts } from '@utility-lib/constants';
import { AUTH_TOKEN } from 'cypress/support/commands';

export function addCompanyPaymentMethod(
  companyResponse?: any,
  creditCardInfo?: CreditCard,
  current_attempt = 1
): Cypress.Chainable<any> {
  cy.allure().logStep('Add Company payment method');
  const companyUuid = companyResponse.uuid;
  cy.log('Company UUID: ' + JSON.stringify(companyUuid));
  const creditCard = creditCardInfo
    ? creditCardInfo
    : {
        fullName: 'JMeter',
        givenName: faker.name.firstName(),
        familyName: faker.name.lastName().replace(/'/g, ''),
        number: '4242424242424242',
        expirationMonth: '1',
        expirationYear: '2029',
        cvc: faker.finance.creditCardCVV()
      };

  return cy
    .request({
      method: HttpRequest.Post,
      url: AccountRegistrationClient.adminPaymentMethod,
      headers: {
        Authorization: AUTH_TOKEN,
        Accept: Accept.ApplicationJson
      },
      body: {
        billingAddress: {
          addressLine1: 'Strawinskylaan',
          addressLine2: '1337',
          state: 'AL',
          city: 'Amsterdam',
          country: 'NL',
          postalCode: '1337AM'
        },
        creditCard,
        requiresAction: false,
        tripFeePaymentMethodUuid: null,
        backupPaymentMethodUuid: null,
        issuerSupplierName: null,
        ownerType: 'COMPANY',
        companyUuid: companyUuid,
        itemMappings: {
          CAR: 'AVAILABLE',
          HOTEL: 'NOT_AVAILABLE',
          RAIL: 'NOT_AVAILABLE',
          FLIGHT: 'NOT_AVAILABLE',
          BLACK_CAR: 'NOT_AVAILABLE'
        },
        department: null,
        billTo: null,
        region: null,
        subsidiary: null,
        chargeTripBucks: false,
        availableForGuestInvitations: false,
        carRentalDirectBillInfo: null,
        corporate: false,
        ownerUuid: companyUuid,
        creditCardType: 'VISA',
        isVirtual: false
      },
      failOnStatusCode: false
    })
    .then(({ status, body }) => {
      cy.log(JSON.stringify(body));
      if ((status === 500 || status === 504) && current_attempt < 5) {
        cy.allure().logStep(
          'Retrying adding personal payment method, attempt: ' + current_attempt
        );
        cy.wait(Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout);
        cy.allure().logStep(
          'Applied wait time: ' + Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout
        );
        addCompanyPaymentMethod(companyResponse, creditCardInfo, ++current_attempt);
      }
      expect(status, 'Payment method updated').to.equal(HttpStatusCodes.Created);
      cy.task('putDataInCache', { key: 'paymentMethod', data: body });
      const paymentMethodUuId = body.uuid;
      cy.task('putDataInCache', {
        key: 'companyPaymentMethodUuId',
        data: paymentMethodUuId
      });
      cy.log('Company UUID: ' + companyUuid);
      return cy.wrap(companyResponse);
    });
}

export function addDirectBill(
  rentalCarCompany: string,
  directBillNumber: string,
  current_attempt = 1
): Cypress.Chainable<any> {
  return cy
    .task('getDataFromCache', 'companyPaymentMethodUuId')
    .then((paymentMethodUuId) => {
      return cy
        .request({
          method: HttpRequest.Post,
          url: AccountRegistrationClient.carDirectBillPaymentMethod,
          headers: {
            Authorization: AUTH_TOKEN,
            Accept: Accept.ApplicationJson
          },
          body: {
            allowRentalPaymentOption: true,
            allowGuestPaymentOption: '',
            availableForGuestInvitations: '',
            billTo: null,
            carRentalCompany: rentalCarCompany,
            department: null,
            directBillNumber: directBillNumber,
            nickname: 'DC123',
            tripFeePaymentMethodUuid: paymentMethodUuId,
            region: null,
            subsidiary: null,
            useForRentalCarPayment: true,
            itemMappings: {
              CAR: 'MANDATORY'
            },
            carRentalDirectBillInfo: {
              carRentalCompany: rentalCarCompany,
              directBillNumber: directBillNumber
            }
          },
          failOnStatusCode: false
        })
        .then(({ status, body }) => {
          cy.log(JSON.stringify(body));
          if ((status === 500 || status === 504) && current_attempt < 5) {
            cy.allure().logStep(
              'Retrying adding direct billing payment method, attempt: ' + current_attempt
            );
            cy.wait(Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout);
            cy.allure().logStep(
              'Applied wait time: ' + Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout
            );
          }
        });
    });
}
