import {
  LocationUtility,
  Timeouts,
  TripTileType,
  utilitySelector,
  Utility
} from '@utility-lib/index';
import { LoginPage } from '@admin-lib/index';
import { HotelInterceptApis, Passenger } from '@hotel-lib/index';
import { policyType } from '@support-policy/index';
import { ReSearchUtility } from '../modal';

import { User_Type } from '@support-onboard/index';

export enum SearchButtonType {
  COMMON,
  EVENT,
  HEADER
}
export const adultAndChildPassengers: Passenger[] = [
  {
    age: 30,
    gender: 'FEMALE'
  },
  {
    age: 12,
    gender: 'FEMALE',
    childAccount: true
  }
];

export const hotelSelector = {
  hotelLocation: '[formcontrolname="location"] input',
  calendarButton: '[class^="ta-date-trigger-v2 ta-date"]',
  nextMonthCalendarButton:
    '[class="popover popover-calendar enter"] [aria-label="next month"]',
  searchHotel: '[qaid="hotelSearchButton"]',
  selectDate: '[class^="ta-calendar-day"]',
  closeCalendar: '.popover-content .ta-button__content',
  dropdown: '[class^="ta-location-search-v2__item"]',
  paymentDropdown: '.filter-details__payment--out',
  prepayCheckBox: '[qaid="Prepay"]',
  payAtHotelCheckBox: '[qaid="Pay at hotel"]',
  traveller: '[qaid="hotelPatrons"]',
  remove: '[class^="ta-user-tag__remove"]',
  travellerInput: '[name="inputSearch"]',
  personalTravellerInput: '.ta-user-search-personal-group',
  personalTravelerItem: '.ta-user-search-personal-list__item',
  userSelectModal: '[class^="user-group-v2__user-selector"]',
  personalUserSelectModal: '.ta-button__background',
  hotelPage: '[aria-label="Hotels"]',
  travellerDropDown: '.ta-user-search-v2__item-email',
  personalTravellerDropDown: '.ta-user-search-personal-list__email',
  roomSelect: '[formcontrolname="numberOfRooms"] button',
  roomSelectOption: '[role="dialog"] ta-select-option div',
  eventHotelSearch: '[class^="search-form-hotel__bottom"] button',
  users: '[formcontrolname = "users"]',
  hotelInvitationButton: '.home-hotel-invitation__bottom-row button',
  searchButton: '[qaId="homeHotelSearchFormSubmitButton"]',
  headerSearchButton:
    'ta-search-form-hotel button[class^="ta-button ta-button--medium-size"]',
  travelerInput: '.user-group-v2.user-group-v2--with-users-rebranded > ta-chevron-toggle',
  personalTravelerInput:
    '[class="user-group-v2 user-group-v2--with-users-rebranded"] .user-group-v2__title',
  searchGuestButton: '.home-hotel-invitation__bottom-row button',
  guestItinerary: '[qaid="itineraryListHotelName"]',
  myHotelPolicyLink: '[data-testid="hotelSearchFormPolicyModalButton"]',
  policyModalHeader: '[data-testid="modal header"]',
  policyModalHotelTab: '[data-testid="HOTEL"]',
  hotelTabPolicyTextArea: '[data-testid="hotelTabWrapper"]',
  policyModalCloseBtn: '[data-testid="modal-header-close-button"]'
};

export class Hotels {
  static visitHotelSearch() {
    Utility.visitSearchPage();

    Utility.selectVertical('hotel');
  }

  static visitHotelSearchPage(tripTileType: TripTileType) {
    Utility.visitSearchPage();
    LoginPage.waitForLoadLoginPage();

    Utility.selectTripTileType(tripTileType);
    Utility.selectVertical('hotel');
  }

  static selectHotelLocation(location: string) {
    this.locationInput(location);
    Utility.selectLocationFromDropdown(location);
  }

  static locationInput(location: string) {
    cy.allure().logStep(`set hotel location: ${location}`);
    cy.clearInputAndType(hotelSelector.hotelLocation, `${location}`);
    cy.wait('@waitForLocation');
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
  }

  static selectOneTraveller(tripType?: string) {
    let travellerInput = hotelSelector.travellerInput;
    let travellerDropDown = hotelSelector.travellerDropDown;
    cy.allure().logStep('set traveller');
    cy.get(hotelSelector.users).click();

    cy.get(hotelSelector.remove).click();
    if (tripType === 'personal') {
      travellerInput = hotelSelector.personalTravellerInput;
      travellerDropDown = hotelSelector.personalTravelerItem;
    }
    cy.task('getDataFromCache', 'userEmail').then((userEmail: any) => {
      cy.get(travellerInput).type(userEmail.substring(0, userEmail.length - 10));
      cy.wait('@waitForTravellers');
      cy.get(travellerDropDown).eq(0).click({ force: true });

      if (tripType === 'personal') {
        cy.get(utilitySelector.closePersonalTravelerInputModal).contains('Done').click();
      }
    });
  }

  static setCheckInCheckOutDate() {
    Utility.selectFutureDate(2);
  }

  static searchHotel(
    searchType = SearchButtonType.COMMON,
    hotelParams = ReSearchUtility.initHotelParams()
  ) {
    cy.allure().logStep('search hotel');

    this.clickOnSearchButton(searchType);
    cy.wait('@waitForHotelSearch');
    Utility.expectSearchLoaderDisabled();

    ReSearchUtility.switchLocationIfHotelSearchResultEmpty(hotelParams);
    cy.url().then((url) => {
      const getUrl = url;
      cy.log('<<< Hotel search URL is >>>: ' + getUrl);
      cy.task('putDataInCache', {
        key: 'HotelSearchURL',
        data: getUrl
      });
    });
  }

  static searchHotels(
    searchType: SearchButtonType = SearchButtonType.COMMON,
    maxRetries = 3
  ) {
    cy.allure().logStep('Search hotel');

    this.visitHotelSearch();
    this.setCheckInCheckOutDate();
    this.selectHotelLocation(LocationUtility.getCityUS());

    this.clickOnSearchButton(searchType);
    cy.wait('@waitForHotelSearch');
    Utility.expectSearchLoaderDisabled();

    this.checkSearchWarning().then((hasWarning: boolean) => {
      if (hasWarning) {
        if (maxRetries > 1) {
          this.searchHotels(searchType, maxRetries - 1);
        } else {
          throw new Error("Can't find hotel.");
        }
      }
    });
  }

  static clickOnSearchButton(typeOfSearch: SearchButtonType) {
    switch (typeOfSearch) {
      case SearchButtonType.COMMON:
        cy.get(hotelSelector.searchButton).click();
        break;
      case SearchButtonType.EVENT:
        cy.get(hotelSelector.hotelInvitationButton).click();
        break;
      case SearchButtonType.HEADER:
        cy.get(hotelSelector.headerSearchButton).click();
        break;
      default:
        cy.get(hotelSelector.searchButton).click();
        break;
    }
  }

  //! to be removed once guest will move to V2 UI
  static searchHotelGuest() {
    cy.allure().logStep('search hotel');
    cy.get(hotelSelector.searchGuestButton).click();
    cy.wait('@waitForHotelSearch');
    Utility.expectSearchLoaderDisabled();
    ReSearchUtility.switchLocationIfHotelSearchResultEmpty(
      ReSearchUtility.initHotelParams()
    );
  }

  static selectTravelerByInput(input: string) {
    cy.allure().logStep('set traveller');

    cy.get(hotelSelector.travelerInput)
      .should('be.visible')
      .then(($input) => {
        cy.wrap($input).scrollIntoView({ duration: 50 });
        cy.wrap($input).click({ force: true });
      });

    cy.get(hotelSelector.travellerInput).type(input);
    cy.wait('@waitForTravellers');
    cy.get(hotelSelector.travellerDropDown).eq(0).click({ force: true });
    cy.get(hotelSelector.userSelectModal).should('be.visible');
    cy.get(utilitySelector.closeTravelerInputModal).click({ force: true });
  }

  static selectPersonalTravelerByInput(input: string) {
    cy.allure().logStep('set traveller');
    cy.get(hotelSelector.personalTravelerInput)
      .should('be.visible')
      .then(($input) => {
        cy.wrap($input).scrollIntoView({ duration: 50 });
        cy.wrap($input).click({ force: true });
      });

    cy.get(hotelSelector.personalTravellerInput).type(input);
    cy.wait('@waitForPersonalTravellers');
    cy.get(hotelSelector.personalTravellerDropDown).eq(0).click({ force: true });
    cy.get(utilitySelector.closePersonalTravelerInputModal).contains('Done').click();
  }

  static createHotelPolicy(policyName: policyType) {
    cy.allure().logStep('create hotel policy');
    cy.createHotelPolicy(`${policyName}`);
  }

  static selectRoom(num: number) {
    cy.get(hotelSelector.roomSelect).click();
    cy.get(hotelSelector.roomSelectOption).eq(num).click();
  }

  static expectHotelSearchPageIsPresent() {
    cy.get(hotelSelector.hotelPage, Timeouts.MAX_TIMEOUT_120_SEC).should('be.exist');
  }

  static expectSearchInputIsPresent(location: string) {
    this.locationInput(location);
    cy.get(hotelSelector.dropdown).should('contain', location).should('be.exist');
  }

  static getCurrentDayForCheckIn() {
    cy.allure().logStep('set current date');
    const todayDate = new Date();
    Utility.selectFutureDate(0, todayDate.getDate());
  }

  static prepareCompanyAndUserCreation(userType: User_Type) {
    HotelInterceptApis.interceptHotelApis();
    LoginPage.createNewCompanyAndLoginWithUserByType({ users: [userType] });
  }
  static guestItineraryPage() {
    cy.get(hotelSelector.guestItinerary).click();
  }

  static verifyHotelPolicyModalIsVisible(text: string) {
    cy.get(hotelSelector.myHotelPolicyLink).click();
    cy.get(hotelSelector.policyModalHeader).contains('Your travel policy');
    cy.get(hotelSelector.policyModalHotelTab).should(
      'have.attr',
      'aria-selected',
      'true'
    );
    cy.get(hotelSelector.hotelTabPolicyTextArea).contains(text);
    cy.get(hotelSelector.policyModalCloseBtn).click();
  }

  static checkSearchWarning() {
    return cy
      .get(utilitySelector.bodySelector)
      .then((body) => body.find(utilitySelector.warningMsg).length > 0);
  }
}
