import { guestInfoData } from '@fixtures/admin/guest_data';
import { SplitUtility } from '@split-lib/index';
import { Timeouts, InputDelays } from '@utility-lib/index';
import { GuestInfoShort } from '@guest-invite-lib/interface';

const inviteGuestModalPageSelectors = {
  firstNameField: 'input[data-testid="firstName"]',
  lastNameField: 'input[data-testid="lastName"]',
  emailField: '[data-testid="eMail"]',
  costCenterField: '[data-testid="costCenter"]',
  departmentField: '[data-testid="departmentField"]',
  guestInfoNextBtn: '[data-testid="guestInfoNextBtn"] button',
  eventName: '[data-testid="eventName"]',
  eventLocation: '[data-testid="eventLocation"]',
  locationDropdown: 'mat-option',
  inviteDatePicker: '[data-testid="dateRangePicker"]',
  nextMonthArrow: '.next',
  calendarMonth: '[role="grid"]',
  datePickerDayDecorator: '[bsdatepickerdaydecorator=""]',
  travelWindowDatePicker: '[data-testid="travelWindowsCalendar"]',
  travelWindowCalendarDay: '.ta-calendar-month-days',
  travelWindowDoneBtn: '.ta-date-trigger-v3-confirm',
  travelWindowsTime: '[formcontrolname="time"]',
  suggestedTravelTimeOption: '[role="option"]',
  eventDetailsNextBtn: '[data-testid="eventDetailsNextBtn"] button',
  additionalInfo: '[data-testid="additionalInfo"]',
  travelPolicyNextBtn: '[data-testid="travelPolicyNextBtn"] button',
  paymentMethod: '[data-testid="paymentMethod"]',
  dropDownList: '[role="listbox"]',
  tripPurpose: '#tripPurpose',
  billToClient: '#billToClient',
  projects: '#projects',
  paymentInfoNextBtn: '[data-testid="paymentInfoNextBtn"] button',
  sendInviteBtn: '[data-testid="sendInviteBtn"]',
  createBookingLinkBtn: '[data-testid="createInviteAndBookingLinkBtn"]',
  successInvitationMessage: '[data-testid="invitationSuccessLink"]',
  closeDialog: '[data-testid="closeGuestInviteDialog"]',
  extraGuestCheckBox: '[formcontrolname="extraGuestAllowed"] input',
  toastMessage: '#toast-container'
};

export class InviteGuestModalPage {
  static fillGuestInfo(guestInfo: GuestInfoShort) {
    const { firstName, lastName, email, costCenter = '', department = '' } = guestInfo;
    cy.allure().logStep('Fill guest information data');
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
    cy.get(inviteGuestModalPageSelectors.firstNameField).type(
      firstName,
      InputDelays.INPUT_DELAY_100_MILLIS
    );
    cy.get(inviteGuestModalPageSelectors.lastNameField).type(lastName);
    cy.get(inviteGuestModalPageSelectors.emailField).type(email);
    cy.get(inviteGuestModalPageSelectors.costCenterField).type(costCenter);
    cy.get(inviteGuestModalPageSelectors.departmentField).type(department);
  }

  static fillGuestInfoFromCachedUser() {
    cy.task('getDataFromCache', 'userInfo').then((userInfo: any) => {
      const guestInfo: GuestInfoShort = {
        firstName: userInfo.given_name,
        lastName: userInfo.family_name,
        email: userInfo.email,
        costCenter: guestInfoData.guestCostCenter,
        department: guestInfoData.guestDepartment
      };
      this.fillGuestInfo(guestInfo);
    });
  }

  static setExtraGuestAllowed() {
    cy.allure().logStep('Set extra guest allowed');
    cy.get(inviteGuestModalPageSelectors.extraGuestCheckBox).click({ force: true });
  }

  static selectNextOptionFromGuestInformation() {
    cy.get(inviteGuestModalPageSelectors.guestInfoNextBtn).click();
  }

  static setEventName(eventName: string) {
    cy.allure().logStep(`Set event name : ${eventName}`);
    cy.get(inviteGuestModalPageSelectors.eventName).type(eventName);
  }

  static setEventLocation(eventLocation: string) {
    cy.allure().logStep(`Set event location : ${eventLocation}`);
    cy.get(inviteGuestModalPageSelectors.eventLocation).type(eventLocation);
    cy.get(inviteGuestModalPageSelectors.locationDropdown)
      .contains(eventLocation)
      .click();
  }

  static setInviteDates(eventStartDate: string, eventEndDate: string) {
    cy.allure().logStep('set guest invite start/end dates');
    cy.get(inviteGuestModalPageSelectors.inviteDatePicker).click();
    cy.get(inviteGuestModalPageSelectors.nextMonthArrow).eq(1).click();
    cy.get(inviteGuestModalPageSelectors.calendarMonth)
      .eq(1)
      .find(inviteGuestModalPageSelectors.datePickerDayDecorator)
      .contains(eventStartDate)
      .click();
    cy.get(inviteGuestModalPageSelectors.calendarMonth)
      .eq(1)
      .find(inviteGuestModalPageSelectors.datePickerDayDecorator)
      .contains(eventEndDate)
      .click();
  }

  static setTravelWindowDates(departureDate: string, returnDate: string) {
    cy.allure().logStep('set guest invite travel window dates');
    cy.get(inviteGuestModalPageSelectors.travelWindowDatePicker).click();
    cy.get(inviteGuestModalPageSelectors.travelWindowCalendarDay)
      .eq(0)
      .contains(departureDate)
      .click();
    cy.get(inviteGuestModalPageSelectors.travelWindowCalendarDay)
      .eq(0)
      .contains(returnDate)
      .click();
    cy.get(inviteGuestModalPageSelectors.travelWindowDoneBtn).click();
  }

  static setLatestArrivalTime(latestArrivalTime: string) {
    cy.allure().logStep('set suggested latest arrival time');
    cy.get(inviteGuestModalPageSelectors.travelWindowsTime).eq(0).click();
    cy.get(inviteGuestModalPageSelectors.suggestedTravelTimeOption)
      .contains(latestArrivalTime)
      .click();
  }

  static setEarliestReturningTime(earliestReturningTime: string) {
    cy.allure().logStep('set suggested earliest returning time');
    cy.get(inviteGuestModalPageSelectors.travelWindowsTime).eq(1).click();
    cy.get(inviteGuestModalPageSelectors.suggestedTravelTimeOption)
      .contains(earliestReturningTime)
      .click();
  }

  static selectNextOptionFromEventDetails() {
    cy.get(inviteGuestModalPageSelectors.eventDetailsNextBtn).click();
  }

  static setAdditionalInfo(info: string) {
    cy.allure().logStep(`Set additional information : ${info}`);
    cy.get(inviteGuestModalPageSelectors.additionalInfo).type(info);
  }

  static selectNextOptionFromTravelPolicy() {
    cy.get(inviteGuestModalPageSelectors.travelPolicyNextBtn).click();
  }

  static selectPaymentMethod(paymentMethod: string) {
    cy.allure().logStep(`Set payment method : ${paymentMethod}`);
    cy.get(inviteGuestModalPageSelectors.paymentMethod).click();
    cy.get(inviteGuestModalPageSelectors.dropDownList).contains(paymentMethod).click();
  }

  static selectTripPurpose(tripPurpose: string) {
    cy.allure().logStep(`Set trip purpose : ${tripPurpose}`);
    cy.get(inviteGuestModalPageSelectors.tripPurpose).click();
    cy.get(inviteGuestModalPageSelectors.dropDownList).contains(tripPurpose).click();
  }

  static selectBillToClient(billToClient: string) {
    cy.allure().logStep(`Set bill to client : ${billToClient}`);
    cy.get(inviteGuestModalPageSelectors.billToClient).type(billToClient);
  }

  static selectProjects(project: string) {
    cy.allure().logStep(`Set projects : ${project}`);
    cy.get(inviteGuestModalPageSelectors.projects).type(project);
  }

  static selectReviewOption() {
    cy.get(inviteGuestModalPageSelectors.paymentInfoNextBtn).click();
  }

  static selectOnlyInviteOption() {
    cy.updateSplits();
    SplitUtility.isSplitOn('GROUP_TRAVEL_REFACTOR').then((refactored) => {
      if (refactored) {
        cy.intercept('POST', /api\/v1\/user\/guest-travel-events\/bulk-create/).as(
          'generateInviteLink'
        );
        cy.get(inviteGuestModalPageSelectors.createBookingLinkBtn).click();
        cy.wait('@generateInviteLink').then((interception) => {
          cy.task('putDataInCache', {
            key: 'tripInvitationId',
            data: interception.response?.body.guestTravelEventReports[0].travelEventId
          });
        });
      } else {
        cy.intercept('POST', /api\/admin\/tripInvitationsV2?/).as('generateInviteLink');
        cy.get(inviteGuestModalPageSelectors.createBookingLinkBtn).click();
        cy.wait('@generateInviteLink').then((interception) => {
          cy.task('putDataInCache', {
            key: 'tripInvitationId',
            data: interception.response?.body[0].tripInvitationUuid
          });
        });
      }
    });
  }

  static sendInvitation() {
    cy.get(inviteGuestModalPageSelectors.sendInviteBtn)
      .contains('Send email invite now')
      .click();
  }

  static verifySuccessToastMessage() {
    cy.allure().logStep('Verify toast success message');
    cy.get(inviteGuestModalPageSelectors.toastMessage)
      .should('be.visible')
      .and('contain', 'Invite has been created');
  }

  static verifyInvitationSuccessMessage() {
    cy.allure().logStep('Verify invitation success message');
    cy.get(inviteGuestModalPageSelectors.successInvitationMessage).should('be.visible');
    cy.get(inviteGuestModalPageSelectors.closeDialog).click();
  }
}
