import { HotelCheckout, HotelSearchResults } from '@hotel-lib/index';
import { EventDetails } from 'cypress/e2e/gme/group_events/lib/event_details';
import { Timeouts } from '@utility-lib/index';

const homePageSelectors = {
  homepageUrl: '/app/user2/home',
  navanHome: '.navan-home',
  hotelUpsellCard: '.hotel-upsell__info__hotels',
  dismissSpecialTrip: '.hotel-upsell__action__cancel span',
  expenseSubtab: '[data-testid="expenseSubtab"]',
  expenseMenuItem: '[qaid="LIQUID_EXPENSES-menu-item"]',
  expenseSubtabActions:
    '[qaid="LIQUID_EXPENSES-menu-item"] > .entry-point-container__card__action',
  groupTravelSubtab: '[data-testid="groupTravelSubtab"]',
  platformDropDown: '[data-qaid="PLATFORM_SWITCHER-button"]',
  rewardsSubtab: '[data-testid="rewardsSubtab"]',
  rewardsSubtabBalance:
    '[data-testid="rewardsSubtab"] > .entry-point-container__card__amount',
  searchExpandedForm: '.search-form-container--show',
  searchFlightToggle: 'button[aria-label="Flights"]',
  searchFlightFromField: 'ta-airport-search-v2 input[aria-label="From"]',
  searchMinimizedForm: '.search-form-container-minimized--show',
  searchMinimizedText: '.search-form-container-minimized__fake-form__text',
  searchBusinessToggle: 'button[aria-label="Business"]',
  searchBusinessTheme: '.home-illustration__mask-container__mask-main--flat-business',
  searchPersonalToggle: 'button[aria-label="Personal"]',
  searchPersonalTheme: '.home-illustration__mask-container__mask-main--flat-personal',
  searchRecentEntry: '.ta-recent-search-item',
  searchClearHistory: '.ta-recent-search-title__clear',
  specialTripImage: '.special-trip-card__trip__img',
  upcomingEventDraft: '.upcoming-event-card__info__draft',
  upcomingEventInvite: '.upcoming-invitation-card',
  upcomingTripCard: '.upcoming-trip-card',
  upcomingTripFlightIcon: 'ta-icon[icon="booking-type-flight"]',
  upcomingTripHotelIcon: 'ta-icon[icon="booking-type-hotel"]',
  userNameNavigation: '.ta-user-menu__name--user-name',
  hotelUpselInfo: (index: number) => `.hotel-upsell__info__hotels > :nth-child(${index})`
};

export class HomePage {
  static visitHomePage(): void {
    cy.allure().logStep('Visit home page');
    cy.visit(homePageSelectors.homepageUrl);
  }

  static verifyHomePage(): void {
    cy.allure().logStep('Verify home page');
    cy.get(homePageSelectors.navanHome).should('be.visible');
    cy.url().then((url) => {
      expect(url).to.include(homePageSelectors.homepageUrl);
    });
  }

  static verifyTravelOnly(): void {
    cy.visit(homePageSelectors.homepageUrl);
    cy.allure().logStep('Visit travel-only home page');
    // Checks the home page if the Navan Expense card is present
    cy.get(homePageSelectors.expenseSubtab).should('not.exist');
    // Checks the plaform dropdown if Expense links are present
    cy.get(homePageSelectors.platformDropDown).click();
    cy.get(homePageSelectors.expenseMenuItem).should('not.exist');
  }

  static verifyMinimizedSearch(): void {
    cy.visit(homePageSelectors.homepageUrl);
    cy.allure().logStep('Verify minimized search form on home page');
    cy.get(homePageSelectors.searchMinimizedForm).should('be.visible');
  }

  static expandSearchForm(): void {
    cy.allure().logStep('Open and verify expanded search form on home page');
    cy.get(homePageSelectors.searchMinimizedText).click();
    cy.get(homePageSelectors.searchExpandedForm).should('exist');
  }

  static toggleBusinessPersonalSearch(): void {
    cy.allure().logStep(
      'Confirm inital theme is business, and verify personal/business theme transition'
    );
    cy.get(homePageSelectors.searchBusinessTheme).should('be.visible');
    cy.get(homePageSelectors.searchPersonalToggle).click();
    cy.get(homePageSelectors.searchPersonalTheme).should('be.visible');
    cy.get(homePageSelectors.searchBusinessToggle).click();
    cy.get(homePageSelectors.searchBusinessTheme).should('be.visible');
  }

  static verifySearchHistory(): void {
    cy.allure().logStep('Confirm booking appears in search history');
    cy.visit(homePageSelectors.homepageUrl);
    cy.get(homePageSelectors.searchMinimizedText).click();
    cy.get(homePageSelectors.searchFlightToggle).click();
    cy.get(homePageSelectors.searchFlightFromField).click();
    cy.get(homePageSelectors.searchRecentEntry).should('be.visible');
  }

  static clearSearchHistory(): void {
    cy.allure().logStep('Confirm search history is cleared');
    cy.get(homePageSelectors.searchFlightFromField).click();
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
    cy.get(homePageSelectors.searchClearHistory).should('be.visible').click();
    cy.get(homePageSelectors.searchFlightFromField).click();
    cy.get(homePageSelectors.searchRecentEntry).should('not.exist');
  }

  static verifySpecialTripSuggestions(): void {
    cy.allure().logStep(
      'Confirm special trip card displays relevant booking suggestions'
    );
    cy.get(homePageSelectors.hotelUpsellCard).should('be.visible');
  }

  static bookHotelSuggestion(index: number): void {
    cy.allure().logStep(`Booking suggestion ${index}`);
    cy.get(this.hotelSuggestion(index)).click();
    HotelSearchResults.selectHotel(0);
    HotelSearchResults.selectRoomOption();
    HotelCheckout.waitToBeLoaded(false);
    HotelCheckout.acceptHotelBookingPolicy();
    HotelCheckout.setPhoneNumber();
    HotelCheckout.checkIfProofOfVaccineRequired();
    HotelCheckout.acceptAcknowledgement();
    HotelCheckout.bookNow();
    HotelCheckout.expectHotelBookedSuccessfully('Hotel confirmed!');
  }

  static dismissSpecialTripCard(): void {
    cy.allure().logStep('Dismiss special trip card by tapping Not Now');
    cy.get(homePageSelectors.dismissSpecialTrip).click();
  }

  static verifyNoSpecialTripCard(): void {
    cy.allure().logStep('Confirm special trip card no longer present');
    cy.get(homePageSelectors.specialTripImage).should('not.exist');
  }

  static verifyUpcomingTripCardBookings(): void {
    cy.allure().logStep('Confirm upcoming trip card displays two booking types');
    cy.get(homePageSelectors.upcomingTripCard).should('exist');
    cy.get(homePageSelectors.upcomingTripFlightIcon).should('exist');
    cy.get(homePageSelectors.upcomingTripHotelIcon).should('exist');
  }

  static verifyUpcomingEventDraftCard(): void {
    cy.allure().logStep('Confirm upcoming event draft card is present');
    cy.get(homePageSelectors.upcomingEventDraft).should('exist');
  }

  static verifyUpcomingEventInviteCard(): void {
    cy.allure().logStep('Confirm upcoming event invite card is present');
    cy.get(homePageSelectors.upcomingEventInvite).should('exist');
  }

  static openUpcomingEventDraftCard(): void {
    cy.allure().logStep('Open upcoming event draft card');
    cy.get(homePageSelectors.upcomingEventDraft).click();
  }

  static hotelSuggestion(index: number): string {
    return homePageSelectors.hotelUpselInfo(index);
  }

  static inviteSelfToEvent() {
    cy.get(homePageSelectors.userNameNavigation)
      .invoke('text')
      .then((text) => {
        EventDetails.openAddParticipantsModal();
        EventDetails.typeAndAddOneParticipant(text);
        EventDetails.sendInvite();
        EventDetails.visitHomePage();
      });
  }

  static verifyRewardsSubtab() {
    cy.wait('@userRewards')
      .its('response.body')
      .then((body) => {
        const points = Object.values(body.balanceDollar).toString();
        cy.get(homePageSelectors.rewardsSubtabBalance)
          .invoke('text')
          .then((text) => {
            const rewards = text?.toString().replace(/\D/g, '');
            expect(rewards).to.equal(points);
          });
      });
  }

  static verifyExpenseSubtab() {
    cy.wait('@expenseTodos')
      .its('response.body')
      .then((body: Record<string, number>) => {
        const totalNumber = parseInt(
          Object.values(body)
            .reduce((a, b) => a + b, 0)
            .toString()
        );
        cy.get(homePageSelectors.expenseSubtabActions)
          .invoke('text')
          .then((text) => {
            const actions = text?.toString().replace(/\D/g, '');
            expect(actions).to.equal(totalNumber);
          });
      });
  }
}
