import { OnboardingGuide } from './onboarding-guide';
import { user } from './users-wizard-pages';

export const usersRolesSelectors = {
  travelRole: '[data-testid^="travel-role__{0}"]',
  delegateForAll:
    '[data-testid="user-role-checkbox-DELEGATE_FOR_ALL"] > .ta-checkbox input',
  travelRoleDone: '[data-testid="save-and-close-users-modal"] > .ta-button-v2',
  adminTravelRole: '[data-testid="user-role-checkbox-ADMIN"] > .ta-checkbox input',
  managerTravelRole: '[data-testid="user-role-checkbox-MANAGER"] > .ta-checkbox input',
  delegateSpecific:
    '[data-testid="user-role-checkbox-DELEGATE_FOR_SPECIFIC"] > .ta-checkbox input',
  delegateSpecificDrawer: '[data-testid="user-role-accordion-DELEGATE_FOR_SPECIFIC"]',
  searchDelegate:
    '[data-testid="user-role-accordion-DELEGATE_FOR_SPECIFIC"] [data-testid="search-box-search__input"]',
  selectUserDelegate: '[data-testid="add-user{0}"]:first',
  selectUserInManager:
    '[data-testid="user-role-accordion-MANAGER"] [data-testid="add-user{0}"]',
  delegateNoResults: '[data-testid="no-results"]',
  userRoleTag: '[data-testid="user-role-tag-{0}"]',
  userRoleTagRemove:
    '[data-testid="user-role-tag-{0}"] ta-icon.ta-user-tag-simple__remove'
};

export const formatStr = (text: string, replacement: string) =>
  text.replace('{0}', replacement);
interface ToggleRoleParam {
  userEmail: string;
  roleSelector: string;
  verifyUncheckedSelector?: string;
  clickDone: boolean;
  roleTextVerify?: string;
}

export class UsersRoles {
  static gotoUsersWizard(): void {
    OnboardingGuide.waitForGetTasks();

    cy.allure().logStep('navigate to users wizard page');
    cy.visit('app/company/users/users-wizard');
  }

  static openTravelRoleForUser(userEmail: string): void {
    cy.allure().logStep(`opening travel role modal for ${userEmail}`);

    cy.get(formatStr(usersRolesSelectors.travelRole, userEmail)).click();
  }

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

    cy.get(selector).click();
  }

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

    cy.get(selector).click({ force: true });
  }

  static scrollIntoView(selector: string): void {
    cy.allure().logStep(`scrollIntoView ${selector}`);

    cy.get(selector).scrollIntoView();
  }

  static verifyContains(selector: string, expectedText: string): void {
    cy.allure().logStep(`verifying element contains ${expectedText}`);

    cy.get(selector).contains(expectedText);
  }

  static verifyNotContains(selector: string, expectedText: string): void {
    cy.allure().logStep(`verifying element not contains ${expectedText}`);

    cy.get(selector).should('not.contain.text', expectedText);
  }

  static verifyExist(selector: string): void {
    cy.allure().logStep(`verifying element exist ${selector}`);

    cy.get(selector).should('exist');
  }

  static verifyUnchecked(selector: string): void {
    cy.allure().logStep(`verifying ${selector} unchecked`);

    cy.get(selector).should('not.have.class', 'has-icon');
  }

  static searchDelegate(username: string): void {
    cy.allure().logStep(`searching for ${username}`);

    cy.get(usersRolesSelectors.searchDelegate).should('be.visible');
    cy.get(usersRolesSelectors.searchDelegate).type(username);
  }

  static waitForUsers(): void {
    cy.allure().logStep('waiting for users');

    cy.wait('@apiAdminUsers');
  }

  static waitForUsersWithRoles(): void {
    cy.allure().logStep('waiting for users with roles');

    cy.wait('@apiAdminUsersWithRoles');
  }

  static testTravelDelegateAllRole(userEmail: string): void {
    UsersRoles.toggleRoleToUser({
      userEmail,
      roleSelector: usersRolesSelectors.delegateForAll,
      verifyUncheckedSelector: usersRolesSelectors.delegateSpecific,
      clickDone: true,
      roleTextVerify: 'Delegate'
    });
  }

  static testTravelDelegateSpecific(userA: user, userB: user): void {
    const userBFullName = `${userB.firstName} ${userB.lastName}`;

    UsersRoles.toggleRoleToUser({
      userEmail: userA.email,
      roleSelector: usersRolesSelectors.delegateSpecific,
      verifyUncheckedSelector: usersRolesSelectors.delegateForAll,
      clickDone: false
    });
    UsersRoles.searchDelegate(userB.firstName);
    UsersRoles.waitForUsers();
    UsersRoles.clickOn(formatStr(usersRolesSelectors.selectUserDelegate, userBFullName));
    UsersRoles.verifyExist(formatStr(usersRolesSelectors.userRoleTag, userBFullName));
    UsersRoles.clickOn(usersRolesSelectors.travelRoleDone);

    UsersRoles.verifyContains(
      formatStr(usersRolesSelectors.travelRole, userA.email),
      'Delegate'
    );
  }

  static testDelegateSpecificAllUsers([userA, userB, userC]: user[]): void {
    const userBFullName = `${userB.firstName} ${userB.lastName}`;
    const userCFullName = `${userC.firstName} ${userC.lastName}`;

    UsersRoles.openTravelRoleForUser(userA.email);
    UsersRoles.waitForUsers();

    UsersRoles.verifyExist(formatStr(usersRolesSelectors.userRoleTag, userBFullName));

    UsersRoles.clickOn(usersRolesSelectors.delegateSpecificDrawer);
    UsersRoles.clickOn(formatStr(usersRolesSelectors.selectUserDelegate, userCFullName));
    UsersRoles.clickOn(formatStr(usersRolesSelectors.selectUserDelegate, 'test test'));

    UsersRoles.verifyExist(formatStr(usersRolesSelectors.userRoleTag, userCFullName));
    UsersRoles.verifyExist(usersRolesSelectors.delegateNoResults);
    UsersRoles.clickOn(formatStr(usersRolesSelectors.userRoleTagRemove, userCFullName));
    UsersRoles.verifyExist(
      formatStr(usersRolesSelectors.selectUserDelegate, userCFullName)
    );

    UsersRoles.clickOn(usersRolesSelectors.travelRoleDone);
  }

  static testSelectAdminRoleForUser(userEmail: string): void {
    UsersRoles.toggleRoleToUser({
      userEmail,
      roleSelector: usersRolesSelectors.adminTravelRole,
      verifyUncheckedSelector: usersRolesSelectors.delegateForAll,
      clickDone: true,
      roleTextVerify: 'Admin'
    });
  }

  static testAddManagerRoleForUser(userEmail: string, userB: user): void {
    const userBFullName = `${userB.firstName} ${userB.lastName}`;
    UsersRoles.toggleRoleToUser({
      userEmail,
      roleSelector: usersRolesSelectors.managerTravelRole,
      verifyUncheckedSelector: usersRolesSelectors.delegateForAll,
      clickDone: false
    });
    UsersRoles.scrollIntoView(
      formatStr(usersRolesSelectors.selectUserInManager, userBFullName)
    );
    UsersRoles.clickOnWithForce(
      formatStr(usersRolesSelectors.selectUserInManager, userBFullName)
    );
    UsersRoles.clickOn(usersRolesSelectors.travelRoleDone);
    UsersRoles.verifyContains(
      formatStr(usersRolesSelectors.travelRole, userEmail),
      'Manager'
    );
  }

  static toggleRoleToUser = ({
    userEmail,
    roleSelector,
    verifyUncheckedSelector,
    clickDone,
    roleTextVerify
  }: ToggleRoleParam): void => {
    UsersRoles.openTravelRoleForUser(userEmail);
    UsersRoles.waitForUsers();
    UsersRoles.clickOn(roleSelector);
    if (verifyUncheckedSelector) {
      UsersRoles.verifyUnchecked(verifyUncheckedSelector);
    }
    if (clickDone) {
      UsersRoles.clickOn(usersRolesSelectors.travelRoleDone);
    }
    if (roleTextVerify) {
      UsersRoles.verifyContains(
        formatStr(usersRolesSelectors.travelRole, userEmail),
        roleTextVerify
      );
    }
  };
}
