import { AmplitudeEvents, Persona } from '@growth-lib/index';
import VisitOptions = Cypress.VisitOptions;
import { getUserBaseUrlPrefix } from '../../../support/commands';
import { Timeouts, utilitySelector } from '@utility-lib/index';
import { GrowthAmplitudeEvents } from '@growth-lib/amplitude-events';
import { SignupReason } from '@growth-lib/persona';
const credentials = Cypress.env('newUser').NEW_USER_PASSWORD;

const selfSellSignupSelectors = {
  firstName: '[data-testid="selfSellFirstNameInput"]',
  lastName: '[data-testid="selfSellLastNameInput"]',
  companyName: '[data-testid="selfSellCompanyName"]',
  password: '[data-testid="selfPasswordInput"]',
  repeatPassword: '[data-testid="selfRepeatPasswordInput"]',
  termsAndConditionConfirmCheckbox: '[data-testid="selfTermsAndConditionCheck"] input',
  submit: '[data-testid="selfSellSubmit"] > button',
  mobileBlock: '.ta-mobile-blocker__body',
  continueOnAppButton: '[data-testid="goToDownloadApp"] button',
  downloadAppLink: '[data-testid="downloadAppLink"]',
  downloadGooglePlayLink: '[data-testid="downloadGooglePlayLink"]',
  downloadAppStoreLink: '[data-testid="downloadAppStoreLink"]',
  goToClaimAdminButton: '[data-testid="goToClaimAdmin"] button',
  goToConfigureCompanyButton: '[data-testid="goToConfigureCompany"] button',
  bookTripsForEmployees: '[data-testid="answer-BOOK_FOR_OTHERS"]',
  rogueTraveler: '[data-testid="answer-BOOK_TRIP"] > .square-container__body',
  monthlyAverageTravelers: '[data-testid="monthlyAverageTravelers"] > .ta-select',
  travelesNumberOption: ':nth-child(2) > .ta-select-option',
  hearAboutUs: '[data-testid="hearAboutUsSource"] > .ta-select',
  hearAboutUsOption: ':nth-child(10) > .ta-select-option > .ta-select-option__label',
  continueOnDesktopProposition: [
    '[data-testid="continue-on-desktop-proposition-MONITOR"]',
    '[data-testid="continue-on-desktop-proposition-CONTROL"]',
    '[data-testid="continue-on-desktop-proposition-MANAGE"]'
  ],
  continueOnDesktopEmail: '[data-testid="continue-on-desktop-email"]'
};

export class SignUp {
  static visitSignUp(
    token: string,
    origin = '',
    asMobileDevice = false,
    preSignUpReason?: SignupReason,
    tripUuid?: string
  ): void {
    this.signUpProcess('self-signup', token, origin, asMobileDevice, preSignUpReason, tripUuid);
    AmplitudeEvents.addExpectedAmplitudeEvents('$identify', 'self signup opened');
  }

  static visitPersonaSignUp(token: string, origin = '', asMobileDevice = false, tripUuid?: string): void {
    this.signUpProcess('self-signup/questionnaire', token, origin, asMobileDevice, undefined, tripUuid);
    AmplitudeEvents.addExpectedAmplitudeEvents('$identify', 'self signup opened');
  }

  static submitShouldBeDisabled(): void {
    cy.allure().logStep('Sign up should be disabled when form is empty');
    cy.get(selfSellSignupSelectors.submit).within(($content) => {
      expect($content.is('[disabled]'), 'submit button should be disabled').to.be.true;
    });
  }

  private static signUpProcess(
    url: string,
    token: string,
    origin = '',
    asMobileDevice = false,
    preSignUpReason?: SignupReason,
    tripUuid?: string
  ): void {
    let visitOptions: Partial<VisitOptions> = {};
    if (asMobileDevice) {
      cy.viewport(400, 850);
      visitOptions = {
        onBeforeLoad: (win) => {
          Object.defineProperty(win.navigator, 'userAgent', {
            value:
              'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
          });
        }
      };
    }

    let signupLink;
    const preSignUpReasonString = preSignUpReason ? `&preSignUpReason=${preSignUpReason}` : '';
    if (!tripUuid) {
      signupLink = `${getUserBaseUrlPrefix()}/${url}?token=${token}&origin=${origin}${preSignUpReasonString}`;
    } else {
      signupLink = `${getUserBaseUrlPrefix()}/${url}?tripUuid=${tripUuid}&origin=${origin}`;
    }

    cy.visit(signupLink, visitOptions);

    cy.wait('@waitForReadInfo');
  }

  static fillUserDetail(): void {
    cy.allure().logStep('Fill signup form');
    cy.get(selfSellSignupSelectors.firstName).type('test');
    cy.get(selfSellSignupSelectors.lastName).type('test');
    cy.get(selfSellSignupSelectors.password).type(credentials, { log: false });
    cy.get(selfSellSignupSelectors.repeatPassword).type(credentials, { log: false });
    cy.get(utilitySelector.bodySelector).then((body) => {
      if (body.find(selfSellSignupSelectors.companyName).length > 0) {
        cy.get(selfSellSignupSelectors.companyName).type('test company');
      }
    });
    cy.get(utilitySelector.bodySelector).then((body) => {
      if (body.find(selfSellSignupSelectors.termsAndConditionConfirmCheckbox).length > 0) {
        cy.get(selfSellSignupSelectors.termsAndConditionConfirmCheckbox).click();
      }
    });
  }

  static clickSubmit(): void {
    cy.allure().logStep('Sign up should be enabled when form is full');
    cy.get(selfSellSignupSelectors.submit).as('submitButton');
    cy.get('@submitButton').within(($content) => {
      expect($content.is('[disabled]'), 'submit button should be enabled').to.be.false;
    });
    cy.get('@submitButton').click();
  }

  static submitSignUp(): void {
    this.clickSubmit();

    cy.wait('@waitForOnboard').then((res) => {
      if (res.response?.body?.companyUuid) {
        cy.task('putDataInCache', {
          key: 'companyUuid',
          data: res.response?.body?.companyUuid
        });
      }
    });
    AmplitudeEvents.addExpectedAmplitudeEvents('self signup completed');
  }

  static fillSignUpForm(token: string, origin = ''): void {
    SignUp.visitSignUp(token, origin);
    SignUp.fillUserDetail();
    SignUp.clickSubmit();
  }

  static fillSignUpFormMobileWeb(token: string, origin = ''): void {
    SignUp.visitSignUp(token, origin, true);
    SignUp.fillUserDetail();
    SignUp.clickSubmit();
  }

  static continueOnApp(): void {
    cy.url().should('include', 'self-signup/continue-on-app');
    AmplitudeEvents.addExpectedAmplitudeEvents('self signup continue on app opened');
    cy.get(selfSellSignupSelectors.downloadAppLink)
      .invoke('removeAttr', 'href') // remove link URL to avoid switching to external page
      .click();
    AmplitudeEvents.addExpectedAmplitudeEvents('self signup download app clicked');
  }

  static continueOnDesktop(): void {
    cy.url().should('include', 'continue-on-desktop');
    AmplitudeEvents.addExpectedAmplitudeEvents('self signup continue on app opened');
    selfSellSignupSelectors.continueOnDesktopProposition.forEach((proposition) => {
      cy.get(proposition).should('be.visible');
    });
    cy.get(selfSellSignupSelectors.continueOnDesktopEmail).should('be.visible');
  }

  static howItWorksForDelegate(): void {
    cy.url().should('include', 'how-it-works');
    AmplitudeEvents.addExpectedAmplitudeEvents('self signup continue on app opened');
    AmplitudeEvents.addExpectedAmplitudeEvents(GrowthAmplitudeEvents.OPEN_HOW_IT_WORKS_DELEGATE);
  }

  static goToAdminClaim(
    expectedUrls: {
      valuePropsUrl: string;
      configureAdminUrl: string;
    } = {
      valuePropsUrl: 'self-signup/configure-company-preview',
      configureAdminUrl: 'self-signup/configure-company'
    }
  ): void {
    cy.url().should('include', 'self-signup/welcome?firstName=test');
    AmplitudeEvents.addExpectedAmplitudeEvents(
      'self signup persona questions opened',
      'self signup persona questions clicked'
    );
    cy.get(selfSellSignupSelectors.goToClaimAdminButton).click();

    cy.url().should('include', expectedUrls.valuePropsUrl);
    AmplitudeEvents.addExpectedAmplitudeEvents('self signup value proposition opened');

    cy.get(selfSellSignupSelectors.goToConfigureCompanyButton).click();
    AmplitudeEvents.addExpectedAmplitudeEvents('admin claim clicked');

    cy.url().should('include', expectedUrls.configureAdminUrl);
  }

  static adminClaimSuccessWithoutMaxEmployees(): void {
    cy.url().should('include', `self-signup/company-configured`);
    AmplitudeEvents.addExpectedAmplitudeEvents('self signup company configured successfully opened');
  }

  static signupFlow(token: string, origin: string, asMobileDevice = false): void {
    SignUp.visitSignUp(token, origin, asMobileDevice);
    SignUp.submitShouldBeDisabled();
    SignUp.fillUserDetail();
  }

  static clickOnBookTripsForEmployees(): void {
    cy.allure().logStep('Press on "Book Trips for Employees"');
    cy.get(selfSellSignupSelectors.bookTripsForEmployees).click();
    cy.wait(Timeouts.SHORT_TIMEOUT_5_SEC.timeout);
  }

  static signupFlowDelegate(): void {
    SignUp.clickOnBookTripsForEmployees();

    cy.wait('@waitForOnboard').then((res) => {
      if (res.response?.body?.companyUuid) {
        cy.task('putDataInCache', {
          key: 'companyUuid',
          data: res.response?.body?.companyUuid
        });
      }
    });
    AmplitudeEvents.addExpectedAmplitudeEvents('self signup completed');
  }

  static signupWithSkipAdmin(token: string, signupReason: SignupReason, asMobileDevice: boolean): void {
    SignUp.visitPersonaSignUp(token, 'MARKETING_PAGE', asMobileDevice);
    Persona.fillPersonaBeforeSignup(signupReason);
    SignUp.fillUserDetail();
    SignUp.submitSignUp();
  }
  static signupWithSkipAdminForExperimentalSignUp(
    token: string,
    signupReason: SignupReason,
    asMobileDevice: boolean
  ): void {
    SignUp.visitPersonaSignUp(token, 'MARKETING_PAGE', asMobileDevice);
    Persona.fillPersonaBeforeSignup(signupReason);
    SignUp.fillUserDetail();
    SignUp.chooseMonthlyAverageTravelers();
    SignUp.chooseWhereDidYouHearOption();
    SignUp.submitSignUp();
  }

  static signupWithSkipAdminForSecondBFOUser(token: string, signupReason: SignupReason, asMobileDevice: boolean): void {
    SignUp.visitPersonaSignUp(token, 'MARKETING_PAGE', asMobileDevice);
    cy.get(selfSellSignupSelectors.bookTripsForEmployees).should('not.exist');
    cy.get(selfSellSignupSelectors.rogueTraveler).click();
    SignUp.fillUserDetail();
    SignUp.submitSignUp();
  }

  static chooseMonthlyAverageTravelers(): void {
    cy.allure().logStep('Choose monthly average travelers');
    cy.get(selfSellSignupSelectors.monthlyAverageTravelers).click();
    cy.get(selfSellSignupSelectors.travelesNumberOption).click();
  }

  static chooseWhereDidYouHearOption(): void {
    cy.allure().logStep('Choose where did you hear option');
    cy.get(selfSellSignupSelectors.hearAboutUs).click();
    cy.get(selfSellSignupSelectors.hearAboutUsOption).click();
  }
}
