import { Random } from '@utility-lib/random';
import { stagingUsers } from '@fixtures/staging-users';
import { Accept, HttpRequest } from '../base';
import { AUTH_TOKEN } from '../commands';
import { GrowthRegistrationUrls } from '@growth-lib/model';

const { superAdmin } = stagingUsers;
const superAdminCredentials = Cypress.env('superAdmin').SUPER_ADMIN_PASSWORD;

const Apis = {
  signup: 'api/selfSell/signup',
  getLeadToken: (leadEmail: string) => `api/selfSell/automation/lead/email/${leadEmail}`
};

export enum SignupReason {
  SETUP_COMPANY = 'SETUP_COMPANY',
  EVALUATE_CORPORATE_TRAVEL = 'EVALUATE_CORPORATE_TRAVEL',
  TRAVEL_AND_EXPENSE_SOLUTION = 'TRAVEL_AND_EXPENSE_SOLUTION',
  TRAVEL_SOLUTION = 'TRAVEL_SOLUTION',
  BOOK_TRIP = 'BOOK_TRIP',
  TEAM_OFFSITE = 'TEAM_OFFSITE',
  BOOK_FOR_OTHERS = 'BOOK_FOR_OTHERS'
}

export enum UserRole {
  UNKNOWN = 'UNKNOWN',
  EXECUTIVE = 'EXECUTIVE',
  EXECUTIVE_ASSISTANCE = 'EXECUTIVE_ASSISTANCE',
  FINANCE = 'FINANCE',
  HR = 'HR',
  OPERATIONS = 'OPERATIONS',
  OFFICE_MANAGER = 'OFFICE_MANAGER',
  PROCUREMENT_MANAGER = 'PROCUREMENT_MANAGER',
  TRAVEL_MANAGER = 'TRAVEL_MANAGER',
  TRAVELER = 'TRAVELER'
}

export let LEAD_TOKEN: string;
export class LoginSelfSell {
  static createNewSelfSellLead(
    params: {
      affiliateName?: string;
      tag?: string;
      platformFundedRewards?: 'ON' | 'OFF';
      emailSuffix?: string;
      accountType?: 'TRAVEL_AND_LIQUID';
      signupReason?: SignupReason;
      userRole?: UserRole;
      registrationUrl?: GrowthRegistrationUrls;
      extraParams?: any;
      promotionCode?: string;
      companyDomain?: string;
      referralCode?: string;
      product?:
        | 'UNKNOWN'
        | 'TEAM_OFFSITE'
        | 'TRAVEL_AND_EXPENSE_SOLUTION'
        | 'TRAVEL_SOLUTION'
        | 'BOOK_TRIP';
    } = {}
  ): Cypress.Chainable<{
    token: string;
    companyDomain: string;
  }> {
    const email = superAdmin.email;
    const randomId = Random.randomString(12);
    const currentCompanyDomain =
      params.companyDomain !== undefined
        ? params.companyDomain
        : randomId + '-navan' + '.staging-prime.tripactions.xyz';
    const userTag = params.tag ? `-${params.tag}-` : '-';
    let userEmail: string;
    if (params.emailSuffix) {
      userEmail = params.emailSuffix + `@${currentCompanyDomain}`;
    } else {
      userEmail = `cypress${userTag}growths@${currentCompanyDomain}`;
    }
    console.info(`%c ${userEmail}`, 'background: black; color: lightgreen');
    cy.allure().logStep(`userEmail: ${userEmail}`);
    cy.task('putDataInCache', {
      key: 'userEmail',
      data: userEmail
    });
    cy.task('putDataInCache', {
      key: 'companyNameSuffix',
      data: randomId
    });
    cy.task('putDataInCache', {
      key: 'companyDomain',
      data: currentCompanyDomain
    });

    return cy
      .loginWithAuthToken({ email, password: superAdminCredentials, isSA: true })
      .then(() =>
        this.signup({
          userEmail: userEmail,
          affiliateName: params.affiliateName,
          platformFundedRewards: params.platformFundedRewards,
          accountType: params.accountType,
          registrationUrl: params.registrationUrl,
          extraParams: params.extraParams,
          promotionCode: params.promotionCode,
          product: params.product,
          signupReason: params.signupReason,
          userRole: params.userRole,
          referralCode: params.referralCode
        })
      )
      .then(() => this.getLeadToken(userEmail))
      .then((response) => {
        LEAD_TOKEN = response.body.selfSellToken;
        return {
          token: LEAD_TOKEN,
          companyDomain: currentCompanyDomain
        };
      });
  }

  private static signup(signupParams: {
    userEmail: string;
    affiliateName?: string;
    platformFundedRewards?: string;
    accountType?: string;
    registrationUrl?: GrowthRegistrationUrls;
    extraParams: any;
    promotionCode?: string;
    product?: string;
    signupReason?: SignupReason;
    userRole?: UserRole;
    referralCode?: string;
  }): Cypress.Chainable<Cypress.Response<any>> {
    const {
      userEmail,
      affiliateName,
      platformFundedRewards,
      accountType,
      registrationUrl,
      promotionCode,
      product,
      signupReason,
      userRole,
      referralCode
    } = signupParams;
    return cy.request({
      method: HttpRequest.Post,
      url: Apis.signup,
      headers: {
        Accept: Accept.ApplicationJson
      },
      retryOnStatusCodeFailure: true,
      body: {
        email: userEmail,
        affiliateName,
        platformFundedRewards,
        accountType,
        registrationUrl,
        promotionCode,
        product,
        signupReason,
        userRole,
        referralCode,
        ...signupParams.extraParams
      }
    });
  }

  private static getLeadToken(
    userEmail: string
  ): Cypress.Chainable<Cypress.Response<any>> {
    return cy.request({
      method: HttpRequest.Get,
      url: Apis.getLeadToken(userEmail),
      headers: {
        Authorization: AUTH_TOKEN,
        Accept: Accept.ApplicationJson
      },
      retryOnStatusCodeFailure: true
    });
  }
}
