import { Hotels } from '@hotel-lib/search';
import { PersonalHomeScreen } from './personal_homescreen';
import { HotelSearchResults, hotelSearchResultSelector } from '@hotel-lib/search_results';
import { Timeouts, verticalType } from '@utility-lib/constants';
import { HotelCheckout } from '@hotel-lib/checkout';
import { Random } from '@utility-lib/random';
import { createGuestDetails } from '@user-lib/factory/guest_user';
import { UserModal } from '@profile-lib/user-modal';
import { GuestDetails } from '@user-lib/interface/guest-details';
import { HotelItinerary } from '@hotel-lib/itinerary';
import { FlightSearchResults } from '@flight-lib/search_results';
import { flightSearchSelector, FlightTripType } from '@flight-lib/search';
import { utilitySelector } from '@utility-lib/utility';
import { FlightBookingUtility } from '@flight-modal/flight_booking_utility';
import { LocationUtility } from '@utility-lib/location';
import { FlightCheckout } from '@flight-lib/checkout';

const ExploratorySearchSelector = {
  addTravelerPill: '.navan-exploratory-search',
  increaseCount: '[class*="ta-button ta-button--secondary-theme ta-button--small-size"][icon="plus"]',
  adminFlagForPassport: '[data-qa-id="SETTINGS_TOGGLE_PASSPORT_DATA_REQUIRED"]',
  clickButton: '.ta-button__content',
  clickChildAge: '[class="navan-age-select required"] [class="dropdown"]',
  specifyChildAge: '[class="navan-age-select-options ng-star-inserted"] [class="option ng-star-inserted"]',
  roomCount: '[class="navan-exploratory-search__control__counter ng-tns-c1015831036-8"][icon="plus"]',
  selectHotel: '.ta-button__content',
  checkoutTravelerCard: '.ta-checkout-traveler__traveler',
  searchTravelers: '.ta-checkout-traveler__search-user',
  childUnderAgeModal: '.ta-underage-error-modal',
  originAirportInput: '[qaid="flightOriginRoundTrip"]',
  flightEditSearchButton: '[qaid="flightSearchButton"]',
  emailInput: 'input[formcontrolname="email"]',
  inputPhoneNumber: '[class="ta-phone-input__value"] [type = "tel"]',
  loggedInUser: '.ta-user-search-personal-list__item',
  searchTravelerDropdown: '[class="ta-checkout-traveler__search-user ta-checkout-traveler__search-user--dropdown"]'
};
const guestDetails = createGuestDetails(30, 'MALE', 'Personal');

const flightBookingParams = FlightBookingUtility.initFlightBookingParams({
  locations: LocationUtility.getPairOfOriginAndDestinationAirportsUS(),
  flightTripType: FlightTripType.ROUNDTRIP,
  tripTileType: 'Personal',
  flightConfirmText: 'Your flight is booked!',
  checkInType: ' Continue without EarlyBird Check-In® '
});

export class ExploratorySearch {
  static clickAddTravelerPill(): void {
    cy.allure().logStep('click add traveler pill');
    cy.get(ExploratorySearchSelector.addTravelerPill).click({ force: true });
  }

  static increaseAdultCount(): void {
    cy.allure().logStep('increase adult count');
    cy.get(ExploratorySearchSelector.increaseCount).eq(0).click({ force: true });
  }

  static increaseChildCount(): void {
    cy.allure().logStep('increase child count');
    cy.get(ExploratorySearchSelector.increaseCount).eq(1).click({ force: true });
  }

  static specifyChildAge(age: string): void {
    cy.allure().logStep('specify child age');
    cy.get(ExploratorySearchSelector.clickChildAge).click();
    cy.get(ExploratorySearchSelector.specifyChildAge).contains(age).click();
  }

  static increaseRoomCount(): void {
    cy.allure().logStep('increase room count');
    cy.get(ExploratorySearchSelector.increaseCount).eq(2).click({ force: true });
  }

  static clickDone(): void {
    cy.allure().logStep('click done');
    cy.get(ExploratorySearchSelector.clickButton).contains('Done').click();
  }

  static initiatePersonalHotelSearch(): void {
    Hotels.setCheckInCheckOutDate();
    PersonalHomeScreen.setHotelLocation('Seattle, WA, USA');
    Hotels.searchHotel();
  }
  static selectPersonalRoomOption(): void {
    ExploratorySearch.selectHotel(0);
    HotelSearchResults.selectRoomOption();
  }
  static selectHotel(index = 0) {
    cy.get(ExploratorySearchSelector.selectHotel, Timeouts.MEDIUM_TIMEOUT_60_SEC)
      .contains('Select')
      .should('be.visible')
      .then((hotels) => {
        if (index >= hotels.length) {
          throw new Error("Can't select hotel with index " + index);
        }

        HotelSearchResults.openNewHotelTab();
        HotelSearchResults.closePopup();
        cy.wrap(hotels).eq(index).click({ force: true });
      });
    cy.allure().logStep(`select ${index} hotel`);
  }
  static editSearch(): void {
    cy.get(hotelSearchResultSelector.editSearch).click();
  }

  static checkoutTravelerCardVisible(noOfTravelers: number): void {
    cy.allure().logStep('traveler section visible');
    cy.get(ExploratorySearchSelector.checkoutTravelerCard).should('have.length', noOfTravelers);
  }

  static selectTravelerAtHotelCheckout(traveler: string): void {
    cy.allure().logStep('select additional traveler');
    cy.get(ExploratorySearchSelector.clickButton).contains(traveler).click();
  }

  static clickTravelerDropdown(traveler: number): void {
    cy.allure().logStep('select additional traveler');
    cy.get(ExploratorySearchSelector.searchTravelerDropdown).eq(traveler).click();
  }

  static fillEmail(email: string): void {
    cy.allure().logStep(`Fill traveler email: ${email}`);
    cy.get(ExploratorySearchSelector.emailInput).eq(1).type(email);
  }

  static createNewTravelerAtCheckout(guestDetails: GuestDetails): void {
    cy.allure().logStep('create new traveler at checkout');
    cy.get(ExploratorySearchSelector.clickButton).contains('Create new guest traveler').click();
    const { givenName = '', familyName = '', email = '', age = 30 } = guestDetails;
    UserModal.fillTravelerName(givenName, familyName);
    UserModal.fillBirthday(age);
    UserModal.fillEmail(email);
    ExploratorySearch.saveTravelerInformation();
  }

  static saveTravelerInformation(): void {
    cy.get(ExploratorySearchSelector.clickButton).contains('Create guest traveler').click();
  }

  static checkoutHotel(noOfTravelers: number): void {
    HotelCheckout.waitToBeLoaded();
    HotelCheckout.createNewTripInfo();
    HotelCheckout.hotelCancellationAndChargePolicy();
    ExploratorySearch.checkoutTravelerCardVisible(noOfTravelers);
  }

  static bookAndCancelHotel(): void {
    HotelCheckout.setPhoneNumber();
    HotelCheckout.acceptAcknowledgement();
    HotelCheckout.bookNow();
    HotelCheckout.closeBookingSuccessModel();
    HotelItinerary.cancelHotel();
  }

  static runCheckoutFlowWithCreateTraveler(): void {
    ExploratorySearch.clickAddTravelerPill();
    ExploratorySearch.increaseAdultCount();
    ExploratorySearch.increaseChildCount();
    ExploratorySearch.specifyChildAge('2');
    ExploratorySearch.increaseChildCount();
    ExploratorySearch.specifyChildAge('5');
    ExploratorySearch.increaseRoomCount();
    ExploratorySearch.clickDone();
    ExploratorySearch.initiatePersonalHotelSearch();
    ExploratorySearch.selectPersonalRoomOption();
    ExploratorySearch.checkoutHotel(2);
    ExploratorySearch.clickTravelerDropdown(0);
    //ExploratorySearch.selectTravelerAtHotelCheckout(' Select Traveler for room 1 ');
    ExploratorySearch.createNewTravelerAtCheckout(guestDetails);
    HotelCheckout.updateEmailDetails('personal-' + Random.randomString(12) + '@staging-prime.tripactions.xyz');
    ExploratorySearch.clickTravelerDropdown(1);
    //ExploratorySearch.selectTravelerAtHotelCheckout(' Select Traveler for room 2 ');
    ExploratorySearch.createNewTravelerAtCheckout(guestDetails);
  }

  static selectVertical(tab: verticalType) {
    cy.allure().logStep(`select search type: ${tab}`);
    cy.get(utilitySelector.dataTestID(tab)).should('be.visible').click();
  }

  static initiatePersonalFlightSearch(): void {
    FlightSearchResults.selectFutureFlightDate();
    PersonalHomeScreen.setFlightOrigin('SFO');
    PersonalHomeScreen.setFlightDestination('LAX');
    FlightSearchResults.searchFlight();
  }

  static initiatePersonalFlightSearchWithInfant(): void {
    FlightSearchResults.selectFutureFlightDate();
    PersonalHomeScreen.setFlightOrigin('SFO');
    PersonalHomeScreen.setFlightDestination('LAX');
    cy.get(flightSearchSelector.flightSearchButton).click();
    cy.get(ExploratorySearchSelector.childUnderAgeModal).should('be.visible');
  }

  static editFlightSearch(): void {
    cy.get(ExploratorySearchSelector.originAirportInput).click();
  }

  static searchFlightEditBar(): void {
    cy.get(ExploratorySearchSelector.flightEditSearchButton).click();
  }

  static selectTravelerAtFlightCheckout(traveler: number): void {
    cy.allure().logStep('select additional traveler');
    //cy.get(ExploratorySearchSelector.clickButton).contains(' Select Traveler ').click();
    cy.get(ExploratorySearchSelector.searchTravelerDropdown).eq(traveler).click();
    cy.get(ExploratorySearchSelector.clickButton).contains('Create new guest traveler').click();
  }

  static runFlightCheckoutFlowWithCreateTraveler(): void {
    ExploratorySearch.clickAddTravelerPill();
    ExploratorySearch.increaseAdultCount();
    ExploratorySearch.clickDone();
    ExploratorySearch.initiatePersonalFlightSearch();
    FlightSearchResults.roundtripSearchResult(flightBookingParams);
    FlightCheckout.waitToPageBeLoaded();
    FlightCheckout.createTripInformation();
    FlightCheckout.checkCancellationPolicy();
    ExploratorySearch.checkoutTravelerCardVisible(2);
    ExploratorySearch.selectTravelerAtFlightCheckout(0);
    ExploratorySearch.createNewTravelerAtFlightCheckout(guestDetails);
  }
  static runFlightCheckoutFlowWithChildren(guestDetails: GuestDetails): void {
    ExploratorySearch.clickAddTravelerPill();
    ExploratorySearch.increaseAdultCount();
    ExploratorySearch.increaseChildCount();
    ExploratorySearch.specifyChildAge('2');
    ExploratorySearch.increaseChildCount();
    ExploratorySearch.specifyChildAge('5');
    ExploratorySearch.increaseRoomCount();
    ExploratorySearch.clickDone();
    ExploratorySearch.initiatePersonalHotelSearch();
    ExploratorySearch.selectPersonalRoomOption();
    ExploratorySearch.checkoutHotel(2);
    ExploratorySearch.selectTravelerAtFlightCheckout(0);
    ExploratorySearch.createNewTravelerAtCheckout(guestDetails);
  }
  static runFlightBookingFlow(): void {
    FlightCheckout.updateContactDetails();
    FlightCheckout.bookAndPay(flightBookingParams);
  }

  static selectLoggedInUser(): void {
    cy.get(ExploratorySearchSelector.searchTravelers, Timeouts.MEDIUM_TIMEOUT_60_SEC).eq(0).click();
    cy.get(ExploratorySearchSelector.loggedInUser).eq(0).click();
  }
  static createNewTravelerAtFlightCheckout(guestDetails: GuestDetails): void {
    cy.allure().logStep('create new traveler at checkout');
    const { givenName = '', familyName = '', email = '', age = 30 } = guestDetails;
    UserModal.fillTravelerName(givenName, familyName);
    UserModal.fillBirthday(age);
    if (guestDetails.age > 17) {
      ExploratorySearch.fillEmail(email);
    }
    ExploratorySearch.saveTravelerInformation();
  }

  static createSecondTravelerAtCheckout(guestDetails2: GuestDetails): void {
    ExploratorySearch.selectTravelerAtFlightCheckout(1);
    ExploratorySearch.createNewTravelerAtFlightCheckout(guestDetails2);
  }
}
