import { OnboardingGuide } from '@growth-lib/onboarding-guide';
import { PolicyWizardState } from '@growth-lib/policy-wizard-pages';
import { HomePage } from '@rebranded_home_page-lib/home-page';
import { ONBOARDING_GUIDE_SELECTORS } from './onboarding-guide.utils';

export const userWizardSelectors = {
  letsGoButton: '[data-testid="landing-page-cta-goto-wizard"]',
  usersLandingPageTitle: '[data-testid="user-landing-page-title"]',
  gotItNextButton: '[data-testid="users-wizard-cta-next"]',
  nextButton: '[data-testid="users-wizard-cta-next"]',
  backButton: '[data-testid="users-wizard-cta-back"]',
  firstNameBox: '[data-testid="user-first-name-{0}"]',
  lastNameBox: '[data-testid="user-last-name-{0}"]',
  workEmailBox: '[data-testid="user-email-{0}"]',
  saveDetailsButton: '[data-testid="save-user-details{0}"]',
  addAnotherUser: '[data-testid="add-another-user"]',
  closeUser: '[data-testid="close-user{0}"]',
  deleteUser: '[data-testid="delete-user{0}"]',
  userDetailsName: '[data-testid="user-table__user-details-{0}"] > b',
  userEmail: '[data-testid="user-table__email-{0}"]',
  usersList: '[data-testid="users-table"] tbody tr',
  usersListFirstLine: '[data-testid="users-table"] tbody tr:first-child',
  userRolesTravel: '[data-testid="select-role-traveler"]',
  userRolesExpense: '[data-testid="select-role-expense"]',
  addUserIndividualyButton: '[data-testid="radio-item-ADD_INDIVIDUALS"]',
  userBulkUploadButton: '[data-testid="radio-item-BULK_UPLOAD"]',
  addUsersHrisbutton: '[data-testid="radio-item-HRIS_INTEGRATION"]',
  travelRolesHeadline: '[data-testid="users-roles-title-travel"]',
  expenseRolesHeadline: '[data-testid="users-roles-title-expense"]',
  downloadTemplate: '[data-testid="template-download-cta"]',
  uploadFile: '[data-testid="drag-drop-file-section"] input[type="file"]',
  fileLoaded: '[data-testid="drag-drop-file-section"] .file-upload__actions__file-loaded',
  browserTitle: '[data-testid="browser-title"]',
  invitationTextArea: '[data-testid="send-invitations-textarea"]',
  usersTableEmail: '[data-testid="travel-role__{0}"]',
  modalTotal: '[data-testid="modal-total"]',
  closeModal: '[data-testid="upload-users__close-modal-cta"]',
  csvFile1User: 'bulk-1-file.csv',
  csvFilePath: 'cypress/fixtures/growth/'
};

const formatStr = function (inputText: string, value: string): string {
  return inputText.replace('{0}', value);
};

export interface user {
  userNum: string;
  firstName: string;
  lastName: string;
  email: string;
}

export class UsersWizardPages {
  static userCount = 0;

  static goToUsersWizardLandingPage(): void {
    cy.allure().logStep('go to Lets go users wizard page');
    OnboardingGuide.clickOn(ONBOARDING_GUIDE_SELECTORS.addUsersTask);
    OnboardingGuide.clickOn(ONBOARDING_GUIDE_SELECTORS.getStartedAddAndInviteUsers);
  }

  static patchUsersWizardState(
    policyWizardState: PolicyWizardState,
    token: string
  ): void {
    cy.allure().logStep(`policy wizard update policy ${policyWizardState} state`);
    cy.request({
      method: 'PATCH',
      url: `/api/selfSetup/company/usersSetup`,
      body: { wizardState: policyWizardState },
      headers: {
        Authorization: token
      }
    }).then((response) => {
      expect(response.status).to.eq(200);
    });
  }

  static checkLandingPageOpened(): void {
    cy.allure().logStep('check landing page opened');
    cy.get(userWizardSelectors.usersLandingPageTitle).should('exist');
    cy.wait('@usersLandingPageWizardOverview');
  }

  static checkRolesRadioButtons(): void {
    cy.allure().logStep('check roles radio buttons');
    cy.get(userWizardSelectors.travelRolesHeadline).should('exist');
    cy.get(userWizardSelectors.userRolesExpense).click();
    cy.get(userWizardSelectors.expenseRolesHeadline).should('exist');
  }

  static checkUsersTableCount(usersCount: number): void {
    cy.allure().logStep(`check that we have only ${usersCount} users`);
    cy.get(userWizardSelectors.usersList).should('have.length', usersCount);
  }
  static checkNoUserAddedCase(usersCount: number): void {
    cy.allure().logStep('check no user added - only admin is on the list');
    cy.get(userWizardSelectors.usersList).should('have.length', usersCount);
    cy.get(userWizardSelectors.usersListFirstLine)
      .find(formatStr(userWizardSelectors.userDetailsName, '0'))
      .should('contain', 'test test');
  }

  static checkUserInPreviewTable(
    rowIndex: number,
    fullName: string,
    email: string
  ): void {
    cy.allure().logStep('check user added');
    cy.get(formatStr(userWizardSelectors.userDetailsName, rowIndex.toString())).should(
      'contain',
      fullName
    );

    cy.get(`${userWizardSelectors.usersList}:nth-child(${rowIndex + 1})`)
      .get(formatStr(userWizardSelectors.userEmail, rowIndex.toString()))
      .should('contain', email);
  }

  static nextUntilHowAddUsersPage(): void {
    cy.allure().logStep('click next until how add users page');
    this.clickOnLetsGoButton();
    this.checkRolesRadioButtons();
    this.clickGotItNextButton();
  }

  static clickOnLetsGoButton(): void {
    cy.allure().logStep('click on lets go button');
    cy.get(userWizardSelectors.letsGoButton).click();
  }

  static clickGotItNextButton(): void {
    cy.allure().logStep('click on got it next button');
    cy.get(userWizardSelectors.gotItNextButton).click();
  }
  static DELAY = 1000;
  static waitUserPlatformPermissionsApi(): void {
    cy.wait('@userPlatformPermissions');

    cy.wait('@apiAdminUsers');
    cy.wait(this.DELAY);
  }

  static clickNextButton(): void {
    cy.allure().logStep('click on next button');
    cy.get(userWizardSelectors.nextButton).click();
  }

  static clickBackButton(): void {
    cy.allure().logStep('click on back button');
    cy.get(userWizardSelectors.backButton).click();
  }
  static fillNewUser({ userNum, firstName, lastName, email }: user): void {
    cy.allure().logStep('fill new user');
    cy.get(formatStr(userWizardSelectors.firstNameBox, userNum)).type(firstName);
    cy.get(formatStr(userWizardSelectors.lastNameBox, userNum)).type(lastName);
    cy.get(formatStr(userWizardSelectors.workEmailBox, userNum)).type(email);

    this.clickSaveDetailsButton(userNum);
    this.userCount += 1;
  }

  static clickSaveDetailsButton(userNum: string): void {
    cy.allure().logStep('click on save details button');
    cy.get(formatStr(userWizardSelectors.saveDetailsButton, userNum)).click();
  }

  static clickOn(selector: string): void {
    cy.allure().logStep(`click on ${selector}`);
    cy.get(selector).click();
  }

  static checkDownloadTemplate(): void {
    cy.allure().logStep(`click on download template`);
    cy.get(userWizardSelectors.downloadTemplate).should('exist');
  }

  static modifyCsvFile(file: string, textReplacement: string): Cypress.Chainable<any> {
    return cy.readFile(file).then((fileText: string) => {
      const uniqueCsvfile = fileText.replace('{0}', textReplacement);
      return cy.writeFile(file.replace('.csv', '-temp.csv'), uniqueCsvfile);
    });
  }
  static uploadBulkFile(companyDomain: string, filePath: string, fileName: string): void {
    cy.allure().logStep(`uploading file "${fileName}"`);
    UsersWizardPages.modifyCsvFile(filePath + fileName, companyDomain).then(() => {
      cy.get(userWizardSelectors.uploadFile).selectFile(
        filePath + fileName.replace('.csv', '-temp.csv'),
        {
          action: 'drag-drop',
          force: true
        }
      );
    });
  }

  static verifyFileLoaded(fileName: string): void {
    cy.allure().logStep(`verifying file "${fileName}"`);
    cy.get(userWizardSelectors.fileLoaded).should('contain', fileName);
    cy.get(userWizardSelectors.browserTitle).should('contain', '1 user uploaded');
  }

  static fillInvitationText(): void {
    cy.allure().logStep(`filling invitation text`);
    cy.get(userWizardSelectors.invitationTextArea).type('welcome to navan');
  }

  static completeWizardAndWaitForFile(): void {
    cy.allure().logStep(`complete wizard and wait for file upload`);

    UsersWizardPages.clickNextButton();
    cy.wait('@usersWizardWaitForFileUpload');
  }
  static completeWizardAndWaitForInvitations(): void {
    cy.allure().logStep(`complete wizard and wait for invitations`);

    UsersWizardPages.clickNextButton();
    cy.wait('@usersWizardBulkUsersInvitation');
  }

  static checkNewUserInUsersTable(email: string): void {
    cy.allure().logStep("checking new user's email exist in users table");

    cy.get(formatStr(userWizardSelectors.usersTableEmail, email)).should('exist');
  }

  static checkInvitationsModalTotal(totalCount: string): void {
    cy.allure().logStep('checking invitation sent modal');

    cy.get(userWizardSelectors.modalTotal).should('contain', totalCount);
    cy.get(userWizardSelectors.closeModal).click();
  }

  static completeTheWizardAndAddUsers(users: user[]): void {
    UsersWizardPages.clickOnLetsGoButton();
    UsersWizardPages.waitUserPlatformPermissionsApi();
    UsersWizardPages.clickNextButton();
    UsersWizardPages.clickOn(userWizardSelectors.addUserIndividualyButton);
    UsersWizardPages.clickNextButton();
    for (const myUser of users) {
      UsersWizardPages.fillNewUser(myUser);
      UsersWizardPages.clickOn(userWizardSelectors.addAnotherUser);
    }
    UsersWizardPages.clickOn(
      formatStr(userWizardSelectors.closeUser, users.length.toString())
    );
    UsersWizardPages.clickOn(
      formatStr(userWizardSelectors.deleteUser, users.length.toString())
    );

    UsersWizardPages.clickNextButton();
    UsersWizardPages.fillInvitationText();
    UsersWizardPages.completeWizardAndWaitForInvitations();
  }
}
