import {
  Hotels,
  HotelCheckout,
  HotelSearchResults,
  HotelItinerary
} from '@hotel-lib/index';
import { LocationUtility, Random, TripTileType, Utility } from '@utility-lib/index';
import { createGuestEmail, createName } from '@user-lib/index';
import { HotelInvoiceValidation } from '@commerce-lib/hotels/invoice_validation';

export interface Passenger {
  age: number;
  gender: 'MALE' | 'FEMALE';
  childAccount?: boolean;
}

/**
 * Book hotel E2E
 */
export const bookHotel = (tileType: TripTileType, passengers: Passenger[] = []) => {
  Hotels.visitHotelSearch();
  if (tileType === 'Personal') {
    Utility.selectTripTileType('Personal');
  }
  passengers.forEach((passenger) => {
    if (passenger.childAccount) {
      const givenName = createName(8);
      const familyName = createName(8);
      cy.createGuestByName({
        givenName,
        familyName,
        age: passenger.age,
        gender: passenger.gender,
        travelerType: tileType
      });
      Hotels.selectTravelerByInput(`${givenName} ${familyName}`);
    } else {
      const guestEmail = createGuestEmail();
      cy.createGuestByEmail({
        email: guestEmail,
        age: passenger.age,
        gender: passenger.gender,
        travelerType: tileType
      });
      Hotels.selectTravelerByInput(guestEmail);
    }
  });

  Hotels.setCheckInCheckOutDate();
  Hotels.selectHotelLocation(LocationUtility.getCityUS());
  Hotels.searchHotel();

  HotelSearchResults.selectHotel(0);
  HotelSearchResults.selectRoomOption();

  HotelCheckout.waitToBeLoaded();
  HotelCheckout.expectNumberOfRooms(tileType === 'Business' ? 1 + passengers.length : 1);
  HotelCheckout.expectNumberOfGuests(1 + passengers.length);
  HotelCheckout.checkoutFLow(tileType);
  HotelCheckout.expectHotelBookedSuccessfully('Hotel confirmed!');
};

export const guestHotelBooking = () => {
  Utility.visitSearchPage();
  Hotels.searchHotelGuest();
  HotelSearchResults.selectHotel(0);
  HotelSearchResults.selectRoomOption();
  HotelCheckout.hotelCancellationAndChargePolicy();
  HotelCheckout.acceptHotelBookingPolicy();
  HotelCheckout.setPhoneNumber();
  HotelCheckout.checkIfProofOfVaccineRequired();
  HotelCheckout.acceptAcknowledgement();
  HotelCheckout.bookNow();
  HotelCheckout.expectHotelBookedSuccessfully('Hotel confirmed!');
};

export const bookPersonalHotel = (
  tileType: TripTileType,
  passengers: Passenger[] = []
) => {
  Hotels.visitHotelSearch();
  if (tileType === 'Personal') {
    Utility.selectTripTileType('Personal');
  }
  passengers.forEach((passenger) => {
    if (passenger.childAccount) {
      const givenName = createName(8);
      const familyName = createName(8);
      cy.createGuestByName({
        givenName,
        familyName,
        age: passenger.age,
        gender: passenger.gender,
        travelerType: tileType
      });
      Hotels.selectPersonalTravelerByInput(`${givenName} ${familyName}`);
    } else {
      const guestEmail = createGuestEmail();
      cy.createGuestByEmail({
        email: guestEmail,
        age: passenger.age,
        gender: passenger.gender,
        travelerType: tileType
      });
      Hotels.selectPersonalTravelerByInput(guestEmail);
    }
  });

  Hotels.setCheckInCheckOutDate();
  Hotels.selectHotelLocation(LocationUtility.getCityUS());
  Hotels.searchHotel();

  HotelSearchResults.selectHotel(0);
  HotelSearchResults.selectRoomOption();

  HotelCheckout.waitToBeLoaded();
  HotelCheckout.expectNumberOfRooms(tileType === 'Business' ? 1 + passengers.length : 1);
  HotelCheckout.expectNumberOfGuests(1 + passengers.length);
  HotelCheckout.checkoutFLow(tileType);
  HotelCheckout.expectHotelBookedSuccessfully('Hotel confirmed!');
};
export const hotelBooking = (tileType: TripTileType, completeBooking = true) => {
  Hotels.visitHotelSearch();
  Hotels.setCheckInCheckOutDate();
  Hotels.selectHotelLocation(LocationUtility.getCityUS());
  Hotels.searchHotel();

  HotelSearchResults.selectHotel(0);
  HotelSearchResults.selectRoomOption();

  HotelCheckout.waitToBeLoaded();
  HotelCheckout.expectNumberOfRooms(1);
  HotelCheckout.expectNumberOfGuests(1);
  HotelCheckout.createNewTripInfo();
  HotelCheckout.hotelCancellationAndChargePolicy();
  HotelCheckout.acceptHotelBookingPolicy();
  HotelCheckout.setPhoneNumber();
  HotelCheckout.checkIfProofOfVaccineRequired();
  HotelCheckout.acceptAcknowledgement();
  if (completeBooking) {
    HotelInvoiceValidation.storeBookingData();
    HotelCheckout.bookNow();
    HotelItinerary.upSellModelClose();
  }
};
