import { signupUserData } from '@fixtures/signup/signup';

const createAccountPageSelectors = {
  signupWelcomeTile: '.signup-welcome',
  createAccountContinueButton: '.ta-button__content',
  firstNameField: '[formcontrolname="firstName"]',
  lastNameField: '[formcontrolname="lastName"]',
  passwordField: '[formcontrolname="pwd"]',
  repeatPasswordField: '[formcontrolname="pwd2"]',
  birthdayField: '[formcontrolname="birthday"]',
  birthdayFieldError: '.signup-passenger__birthday .ta-form-wrap__error',
  genderField: '[formcontrolname="gender"]',
  idCheckBox: '[formcontrolname="checkId"]',
  agreementCheckBox: '[formcontrolname="checkAgree"]',
  popOverContent: '.popover-content',
  mobileNumberField: '[formcontrolname="phone"]',
  seatPreference: '[formcontrolname="seatPreference"]',
  skipScan: '.signup-final__skip',
  maybeLaterButton: '.signup-frame__footer-skip',
  continueButton: '.signup-frame__footer-continue',
  personalEmailField: '[formcontrolname="altEmail"]',
  validationErrorMessage: '.ta-form-wrap__error',
  createButton: '.ta-button',
  emailVerificationStatus: '.email-container'
};

export class CreateAccountPage {
  static visitCreateAccountPageWithToken(email: string) {
    cy.allure().logStep('visit create account page');
    cy.intercept('GET', /api\/lookup\/v1\/uaa\/emailinfo?/).as('waitForEmail');
    cy.retrieveSignUpToken(email).then((response) => {
      cy.visit(`/signup?token=${response.body}&email=${response.email}`);
    });
    cy.get(createAccountPageSelectors.signupWelcomeTile).should('be.visible');
    cy.wait('@waitForEmail');
  }

  static createAccountContinue() {
    cy.allure().logStep('click on continue button');
    cy.get(createAccountPageSelectors.createAccountContinueButton)
      .contains('Continue')
      .click();
  }

  static createAccountDisabled() {
    cy.allure().logStep('click on continue button disabled');
    cy.get(createAccountPageSelectors.createButton).should('be.disabled');
  }

  static createAccountButton() {
    cy.allure().logStep('click on continue button');
    cy.get(createAccountPageSelectors.createAccountContinueButton)
      .contains('Create account')
      .click();
  }

  static fillUserCredentials(firstName: string, lastName: string, password: string) {
    cy.allure().logStep('fill user credentials');
    cy.get(createAccountPageSelectors.firstNameField).type(firstName);
    cy.get(createAccountPageSelectors.lastNameField).type(lastName);
    cy.get(createAccountPageSelectors.passwordField).type(password, { log: false });
    cy.get(createAccountPageSelectors.repeatPasswordField).type(password, { log: false });
    this.createAccountContinue();
  }

  static fillUserDetailsAndPassword(
    firstName: string,
    lastName: string,
    password: string
  ) {
    cy.allure().logStep('fill user credentials');
    cy.get(createAccountPageSelectors.firstNameField).type(firstName);
    cy.get(createAccountPageSelectors.lastNameField).type(lastName);
    cy.get(createAccountPageSelectors.passwordField).type(password, { log: false });
    cy.get(createAccountPageSelectors.repeatPasswordField).type(password, { log: false });
  }

  static validateUserDetailsAndPassword(
    invalidFirstLastName: string,
    invalidPassword: string,
    unmatchedPassword: string
  ) {
    cy.allure().logStep('Validate user credentials');
    cy.get(createAccountPageSelectors.firstNameField).type(invalidFirstLastName);
    cy.get(createAccountPageSelectors.lastNameField).click();
    cy.get(createAccountPageSelectors.validationErrorMessage)
      .should('be.visible')
      .contains('Name can not contain numbers and special characters');
    cy.get(createAccountPageSelectors.lastNameField).type(invalidFirstLastName);
    cy.get(createAccountPageSelectors.firstNameField).click();
    cy.get(createAccountPageSelectors.validationErrorMessage)
      .should('be.visible')
      .contains('Name can not contain numbers and special characters');
    cy.get(createAccountPageSelectors.passwordField).type(invalidPassword, {
      log: false
    });
    cy.get(createAccountPageSelectors.firstNameField).click();
    cy.get(createAccountPageSelectors.validationErrorMessage)
      .should('be.visible')
      .contains(
        ' Password must be at least 8 characters including one uppercase letter, one lowercase letter and one number '
      );
    cy.get(createAccountPageSelectors.repeatPasswordField).type(unmatchedPassword, {
      log: false
    });
    cy.get(createAccountPageSelectors.firstNameField).click();
    cy.get(createAccountPageSelectors.validationErrorMessage)
      .should('be.visible')
      .contains(' Both password fields must match');
  }

  static fillPersonalDetails(birthday: string, gender: string) {
    cy.allure().logStep('fill personal details');

    cy.get(createAccountPageSelectors.genderField).click();
    cy.get(createAccountPageSelectors.popOverContent).contains(gender).click();

    cy.get(createAccountPageSelectors.birthdayField).as('birthdayField');
    cy.get('@birthdayField').type(birthday);

    if (cy.checkIfExist(createAccountPageSelectors.birthdayFieldError)) {
      cy.reload();
      const birthdayTrim = birthday.replace(/\//g, '');
      cy.get(createAccountPageSelectors.genderField).click();
      cy.get(createAccountPageSelectors.popOverContent).contains(gender).click();
      cy.get('@birthdayField').click();
      cy.get('@birthdayField').clear();
      cy.get('@birthdayField').type(birthdayTrim);
    }

    cy.get(createAccountPageSelectors.idCheckBox).click();
    cy.get(createAccountPageSelectors.agreementCheckBox).click();
    cy.wait('@waitForUserDetails');
    this.createAccountContinue();
  }

  static fillMobileNumber(mobileNumber: string) {
    cy.allure().logStep('add mobile number');
    cy.get(createAccountPageSelectors.mobileNumberField).type(mobileNumber);
    this.createAccountContinue();
  }

  static setSeatPreference(preference: string) {
    cy.allure().logStep('set seat preference');
    cy.intercept('PUT', /api\/user\/passenger/).as('waitForUpdateSeatPreference');
    cy.get(createAccountPageSelectors.seatPreference).click();
    cy.get(createAccountPageSelectors.popOverContent).contains(preference).click();
    this.createAccountContinue();
    cy.wait('@waitForUpdateSeatPreference');
  }

  static skipScanVerification() {
    cy.allure().logStep('skip scan verification');
    cy.get(createAccountPageSelectors.skipScan).contains('Skip').click();
  }

  static clickMaybeLaterButton() {
    cy.allure().logStep('Click Maybe later button');
    cy.get(createAccountPageSelectors.maybeLaterButton).click();
  }

  static joinNavanRewards(personalEmail: string) {
    cy.allure().logStep('Signing up for Navan Rewards with ' + personalEmail);
    cy.get(createAccountPageSelectors.personalEmailField).type(personalEmail);
    cy.get(createAccountPageSelectors.continueButton).click();
  }

  static completeOnboardingFlow(email: string, password: string, personalEmail?: string) {
    cy.allure().logStep('Completing onboarding flow');
    this.visitCreateAccountPageWithToken(email);
    this.createAccountContinue();
    this.fillUserCredentials(signupUserData.firstName, signupUserData.lastName, password);
    this.fillPersonalDetails(signupUserData.birthday, signupUserData.gender);
    this.fillMobileNumber(signupUserData.mobile);
    this.setSeatPreference(signupUserData.seatPreference);
    this.createAccountContinue();
    if (personalEmail == null) {
      this.clickMaybeLaterButton();
    } else {
      this.joinNavanRewards(personalEmail);
    }
    this.skipScanVerification();
  }

  static completeUnfiedOnboardingCreateAccount(email: string, password: string) {
    cy.allure().logStep('Completing unified user onboarding flow');
    this.visitCreateAccountPageWithToken(email);
    this.fillUserDetailsAndPassword(
      signupUserData.firstName,
      signupUserData.lastName,
      password
    );
    this.createAccountButton();
  }

  static validateNameAndPwdInCreateAccount(
    email: string,
    invalidFirstLastName: string,
    invalidPassword: string,
    unmatchedPassword: string
  ) {
    cy.allure().logStep('validate name and password in create account');
    this.visitCreateAccountPageWithToken(email);
    cy.get(createAccountPageSelectors.emailVerificationStatus)
      .should('be.visible')
      .contains('Verified email');
    this.validateUserDetailsAndPassword(
      invalidFirstLastName,
      invalidPassword,
      unmatchedPassword
    );
    this.createAccountDisabled();
  }
}
