import { TripTileType, Utility, bookingVerticalType, Timeouts } from '@utility-lib/index';
import { HotelInvoiceValidation } from '@commerce-lib/hotels/invoice_validation';
import { Invoice } from '@commerce-lib/invoice/invoice';
import { Hotels } from '@hotel-lib/search';
import { HotelSearchResults } from '@hotel-lib/search_results';
import { HotelCheckout } from '@hotel-lib/checkout';
import { FlightItinerary } from '@flight-lib/itinerary';
const adminCreds = Cypress.env('newUser').NEW_USER_PASSWORD;

const hotelItinerarySelector = {
  itineraryBody: '.itinerary__content-body__item',
  hotelName: '.ta-trip-event-hotel-details__title',
  checkInDate:
    'div[class$="ta-trip-event-hotel-details__labels"]:contains("Check-in")+div',
  checkOutDate:
    'div[class$="ta-trip-event-hotel-details__labels"]:contains("Check-out")+div',
  bookingSection: '.ta-trip-event-hotel-booking',
  manageItinerary: 'button[qaid="goToItinerary"]',
  addNewTrip: 'ta-add-to-trip-dropdown',
  selectBookingType:
    '[class="add-to-trip-dropdown-popover ng-star-inserted"] [role="button"]',
  selectNewHotel: '.add-to-trip-dropdown-popover__text',
  itineraryListDate: '[qaid="itineraryListDate"]',
  roomTypeDetails:
    '[class^="ta-trip-event-hotel-room-details__link ta-button ta-button--link-theme"]',
  hotelDetailHeader: '.ta-modal-header',
  roomOverview: '.room-details',
  cancelHotel: '[qaid="eventActionCancelHotel"]',
  downLoadInvoice: '[qaid="itineraryListHotelName"]',
  selectHotelItineraryPage: '[qaid="itineraryListHotelName"]',
  creditCardCheckIn: '[class^="trip-hotel__payment-title"]',
  showCanceledHotel:
    '[class^="itinerary__content-body__show-canceled-bookings"] .mat-checkbox-layout',
  showCanceledHotelCheckbox: '[class^="booking-status-tag"]',
  tripTile: '.itinerary__trip-types',
  viewAllGuestsButton: 'ta-trip-event-hotel-guests button',
  guestRowInGuestModal: 'ta-view-all-guests-modal .view-all-guests__guest-row',
  tripTypeInItinerary: '[qaId="tripsTypeTagPesonal"], [qaId="tripsTypeTagBleisure"]',
  upSellModalClose: 'button.booking-upsell-modal__close',
  hotelLocation: '[class^="ta-trip-event-hotel-details__column"] a'
};

export class HotelItinerary {
  static waitToBeLoaded(): void {
    cy.allure().logStep(
      'wait for hotel itinerary page APIs to complete and page to be loaded'
    );
    cy.wait('@waitForTripTimeline');
  }
  static storeItineraryURl(): void {
    cy.allure().logStep(
      'wait for hotel itinerary page APIs to complete and page to be loaded'
    );
    cy.wait('@invoice').then((interception) => {
      cy.task('putDataInCache', {
        key: 'bookingUuid',
        data: interception.request.url.split('/')[7]
      });
    });
    cy.reload();
    cy.url().then((url) => {
      const getUrl = url;
      cy.log('<<< Hotel Itinerary URL is >>>: ' + getUrl);
      cy.task('putDataInCache', {
        key: 'ItineraryURL',
        data: getUrl
      });
    });
  }

  static verifyHotelItineraryPage(): void {
    cy.get(hotelItinerarySelector.hotelName).should('be.visible');
    cy.get(hotelItinerarySelector.checkInDate).should('be.visible');
    cy.get(hotelItinerarySelector.checkOutDate).should('be.visible');
    cy.get(hotelItinerarySelector.bookingSection).then((ele) => {
      cy.wrap(ele).scrollIntoView();
      cy.wrap(ele).should('be.visible');
    });
  }

  static visitItinerary() {
    cy.visit('app/user2/trips');
    cy.wait('@waitForUserDetails');
    cy.allure().logStep('visit itinerary');
  }

  static viewAndManageItinerary() {
    cy.get(hotelItinerarySelector.manageItinerary, Timeouts.MEDIUM_TIMEOUT_60_SEC)
      .should('be.visible')
      .eq(0)
      .click({ force: true });
    cy.wait('@waitForManageItinerary');
    cy.allure().logStep('view and manage itinerary');
  }

  static addNewTripInCurrentItinerary(
    bookingType: bookingVerticalType,
    existingTrip?: boolean
  ) {
    if (existingTrip) {
      cy.get(hotelItinerarySelector.hotelLocation)
        .eq(0)
        .invoke('text')
        .then((hotelLocation) => {
          cy.task('putDataInCache', {
            key: 'hotelLocation',
            data: hotelLocation
          });
        });
      cy.get('[class^="itinerary-information__title__text"]')
        .invoke('text')
        .then((text) => {
          cy.log('<<< Current Itinerary Title is >>>: ' + text);
          cy.task('putDataInCache', {
            key: 'itineraryTitle',
            data: text
          });
        });
    }

    cy.get(hotelItinerarySelector.addNewTrip).click();
    cy.get(hotelItinerarySelector.selectBookingType).contains(bookingType).click();

    cy.allure().logStep(`add new trip type ${bookingType} in current itinerary`);
  }

  static expectNoItineraryIsPresent(noOfItineraries: number) {
    cy.get(hotelItinerarySelector.itineraryListDate, Timeouts.MAX_TIMEOUT_120_SEC).should(
      'have.length',
      noOfItineraries
    );
    cy.allure().logStep(`expect ${noOfItineraries} itinerary is present`);
  }

  static expectHotelDetailPageIsPresent() {
    cy.get(hotelItinerarySelector.roomTypeDetails).click();
    cy.get(hotelItinerarySelector.roomOverview).should('be.visible');
  }

  static reloadItineraryPage() {
    cy.reload();
  }

  static goToItineraryPage() {
    cy.task('getDataFromCache', 'ItineraryURL').then((goToItineraryURL: any) => {
      cy.visit(goToItineraryURL);
      cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
    });
  }
  static cancelHotel() {
    Utility.cancelTrip('Hotel');
    Utility.selectCancellationReason('Change of plans');
    Utility.confirmCancellation();
    Utility.expectCancelledLabelIsPresent();
  }

  static changeHotel() {
    Utility.changeTrip('Hotel');
  }

  static showCanceledBooking() {
    cy.allure().logStep('show canceled booking');
    cy.get(hotelItinerarySelector.showCanceledHotel).click();
  }

  static selectHotelFromItinerary() {
    cy.allure().logStep('select Hotel From Itinerary');
    cy.get(hotelItinerarySelector.selectHotelItineraryPage).click();
    this.waitToBeLoaded();
  }

  static expectHotelIsCancelled() {
    cy.allure().logStep('expect hotel is cancelled');
    cy.get(hotelItinerarySelector.showCanceledHotelCheckbox).contains('Canceled');
  }

  static verifyTripTile(tripTile: TripTileType) {
    cy.allure().logStep(`verify tripType should be ${tripTile}`);
    cy.get(hotelItinerarySelector.tripTypeInItinerary).contains('Personal');
  }

  static clickOnViewAllGuestsButton() {
    cy.allure().logStep('click on view all guests button');
    cy.get(hotelItinerarySelector.viewAllGuestsButton)
      .contains('View all guests')
      .click();
  }

  static cancelHotelFromItinerary() {
    Utility.cancelTrip('Hotel');
    Utility.selectCancellationReason('Change of plans');
    Utility.confirmHotelCancellation();
    Utility.expectCancelledLabelIsPresent();
  }

  static verifyNumberOfGuests(guestsNumber: number) {
    cy.allure().logStep(`verify number of guest should be: ${guestsNumber}`);
    cy.get(hotelItinerarySelector.guestRowInGuestModal).should(
      'have.length',
      guestsNumber
    );
  }

  static upSellModelClose() {
    cy.allure().logStep('Close the up sell model');
    cy.wait(Timeouts.MEDIUM_TIMEOUT_10_SEC.timeout);
    cy.get(hotelItinerarySelector.upSellModalClose).as('upSellModalClose');
    cy.get('@upSellModalClose').click();
  }

  static verifyTripFeeInInvoice() {
    HotelInvoiceValidation.storeTripData();
    HotelInvoiceValidation.downloadInvoicePDF();
    HotelInvoiceValidation.visitViewInvoicePage();
    HotelInvoiceValidation.checkInvoiceBookingId();
    HotelInvoiceValidation.checkInvoiceHotelName();
    HotelInvoiceValidation.checkInvoiceTotalPrice();
    HotelInvoiceValidation.checkInvoiceTAFee();
  }
  static verifyLocalizationInvoice(language: string) {
    HotelInvoiceValidation.selectLanguage(language);
    HotelInvoiceValidation.storeTripData();
    HotelInvoiceValidation.clickAndDownloadInvoice();
    Invoice.retrieveDownloadInvoiceFile();
    Invoice.retrieveAndConvertPDFInvoiceDetailsToHTML();
    HotelInvoiceValidation.checkHotelInvoiceLocalizationData(language);
    HotelInvoiceValidation.checkInvoiceTripeFeeLocalizationData(language);
    HotelInvoiceValidation.checkInvoiceBookingId();
    HotelInvoiceValidation.checkInvoiceHotelName();
  }

  static storeHotelBookingInformation() {
    HotelInvoiceValidation.storeTripData();
    HotelInvoiceValidation.downloadInvoicePDF();
  }
  static validateHotelBookingDetailsInInvoice() {
    HotelInvoiceValidation.checkInvoiceBookingId();
    // HotelInvoiceValidation.checkInvoiceHotelName();
    // HotelInvoiceValidation.checkInvoiceTotalPrice();
    HotelInvoiceValidation.checkInvoiceTAFee();
  }
  static bookPrePayHotel() {
    Hotels.searchHotels();
    HotelSearchResults.excludeProvidersFromRoomsList(['EXPEDIA']);
    HotelSearchResults.selectPrepayRoom();
    HotelCheckout.waitToBeLoaded();
    HotelCheckout.setTripInfo();
    HotelCheckout.hotelCancellationAndChargePolicy();
    HotelCheckout.acceptHotelBookingPolicy();
    HotelCheckout.setPhoneNumber();
    HotelCheckout.checkIfProofOfVaccineRequired();
    HotelCheckout.acceptAcknowledgement();
    HotelInvoiceValidation.storeBookingData();
    HotelCheckout.expectPrepayHotelRoomDueNowIsNotZero();
    HotelCheckout.bookNow();
    HotelCheckout.expectHotelBookedSuccessfully('Hotel confirmed!');
    HotelItinerary.verifyHotelItineraryPage();
  }
  static verifyUnchangeableInvoice() {
    FlightItinerary.forcePDFSyncAPI();
    Utility.loginAsAdmin(adminCreds);
    HotelItinerary.goToItineraryPage();
    HotelInvoiceValidation.storeTripData();
    HotelInvoiceValidation.clickAndDownloadInvoice();
    Invoice.retrieveDownloadInvoiceFile();
    Invoice.retrieveAndConvertPDFInvoiceDetailsToHTML();
    HotelInvoiceValidation.checkInvoiceBookingId();
    HotelInvoiceValidation.checkInvoiceHotelName();
    HotelInvoiceValidation.checkInvoiceTotalPrice();
    HotelInvoiceValidation.checkInvoiceTAFee();
    HotelInvoiceValidation.checkHotelUnchangeabilityData();
  }
}
