import {
  Utility,
  TripTileType,
  Timeouts,
  utilitySelector,
  Random
} from '@utility-lib/index';

export const trainSearchSelector = {
  dropDownButton: '.ta-select',
  setOrigin: '.ta-form-element input',
  setDestination: '.ta-form-element input',
  searchButtonQaId: '[qaid="trainSearchButton"]',
  searchButton: `button[tabutton][class*='ta-button--primary-theme']`,
  searchResultNotFound: '.container__title',
  searchFromInvite: 'ta-search-form-train-invitation button.ta-button--primary-theme',
  invitationTitle: '.ta-invitation__title',
  tripTypeIndicator: '[icon="dropdown-triangle"]',
  journeyType: '[formcontrolname="searchType"] button',
  journeyTypeLocatorTemplate: 'ta-select-option > div[aria-label="%s"]',
  locationLabel: (location: string) => `[aria-label^="${location}"]`,
  tripLabel: (tripType: string) => `[aria-label="${tripType}"]`,
  addTraveler: '[class^="user-group-v2__passengers"]',
  searchTraveler: '[class="ta-search"] [name="inputSearch"]',
  selectTraveler: '[class="ta-user-search-v2__item-name"]',
  user: '[data-testid="userGroupTrainName"]',
  addMoreTravelers: 'input[name="inputSearch"]',
  userEmail: '[class="ta-user-search-v2__item-email"]'
};

const baseUrl = `${Cypress.config('baseUrl')}/app/user2/search/trainsV2/`;
const regex = '[a-zA-Z0-9-]+';
const urlPattern = new RegExp(`${baseUrl}${regex}/results/${regex}`);
interface JourneyTypeLocator {
  locator: string;
  label: string;
}

export enum JourneyType {
  ONE_WAY,
  ROUND_TRIP
}

const JT: { [key in JourneyType]: JourneyTypeLocator } = {
  [JourneyType.ONE_WAY]: { locator: 'One-way', label: 'ONE_WAY' },
  [JourneyType.ROUND_TRIP]: { locator: 'Roundtrip', label: 'Roundtrip' }
};

export class TrainSearch {
  static visitTrainSearch(tripTileType: TripTileType = 'Business') {
    Utility.visitSearchPage();
    if (tripTileType === 'Personal') {
      Utility.selectTripTileType('Personal');
    }
    Utility.selectVertical('train');
    this.verifyTrainSearchOptionIsAvailable();
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
  }

  static verifyTrainSearchOptionIsAvailable() {
    cy.allure().logStep('expect train search tab visible');
    cy.get(trainSearchSelector.setOrigin).should('be.exist');
  }

  static selectJourneyType(journeyType: JourneyType) {
    cy.get(trainSearchSelector.journeyType).then(($button) => {
      if ($button.attr('value')?.localeCompare(JT[journeyType].label) != 0) {
        cy.allure().logStep('Selecting journey' + JT[journeyType].label);
        cy.wrap($button).click();
        cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
        cy.log(
          'Journey Type Locator: ' +
            trainSearchSelector.journeyTypeLocatorTemplate.replace(
              '%s',
              JT[journeyType].locator
            )
        );
        cy.get(
          trainSearchSelector.journeyTypeLocatorTemplate.replace(
            '%s',
            JT[journeyType].locator
          )
        ).click();
        cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
      }
    });
  }

  static setOrigin(location: string) {
    cy.get(trainSearchSelector.setOrigin)
      .eq(0)
      .then((ele) => {
        cy.wrap(ele).clear({ force: true });
        cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
        cy.wrap(ele).type(`${location}`);
      });

    this.location(`${location}`);

    cy.allure().logStep(`select origin - ${location}`);
  }

  static setDestination(location: string) {
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
    cy.get(trainSearchSelector.setDestination)
      .eq(1)
      .then((ele) => {
        cy.wrap(ele).clear({ force: true });
        cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
        cy.wrap(ele).type(`${location}`);
      });
    this.location(`${location}`);
    cy.allure().logStep(`select destination - ${location}`);
  }

  static location(location: string) {
    cy.allure().logStep(`select location - ${location}`);
    cy.wait('@waitForSearchStations');
    cy.get(trainSearchSelector.locationLabel(location))
      .eq(0)
      .trigger('click', { force: true });
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
  }

  static selectFutureTrainDate() {
    Utility.selectFutureDate(1);
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
  }

  static selectTodayDate() {
    cy.get(utilitySelector.calendarButton).eq(0).click();
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
    cy.get('[data-testid="calendarDay"]:not(.ta-calendar-day--disabled)')
      .eq(0)
      .click({ force: true });
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
    cy.get(utilitySelector.closeCalendar).click();
  }

  static selectTripTileType(tripType: string) {
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
    cy.get(trainSearchSelector.tripTypeIndicator).click();
    cy.get(trainSearchSelector.tripLabel(tripType)).click();
    cy.allure().logStep('SetTo - ${tripType}');
  }

  static findSearchButtonAndClick() {
    cy.get(trainSearchSelector.searchButton)
      .wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout)
      .click();
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
  }

  static searchTrain() {
    cy.get(trainSearchSelector.searchButton).click();
    cy.get(trainSearchSelector.searchButton)
      .invoke('text')
      .then((text: any) => {
        const trimmedText = text.trim();
        if (text === trimmedText) {
          cy.url().should('match', urlPattern);
        }
      });
    Utility.expectSearchLoaderDisabled();
    cy.wait(Timeouts.SHORT_TIMEOUT_5_SEC.timeout);
    cy.allure().logStep('search train');
  }

  static verifyTrainSearchInvite(title: string) {
    cy.get(trainSearchSelector.invitationTitle).should('contain', title);
  }

  static addTraveler() {
    cy.get(trainSearchSelector.addTraveler).click();
    cy.task('getDataFromCache', 'companyCreationEmail').then((email: any) => {
      cy.get(trainSearchSelector.searchTraveler).type(email);
    });
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
    cy.get(trainSearchSelector.selectTraveler).click();
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
    cy.get(trainSearchSelector.addTraveler).click();
    cy.allure().logStep('add traveler');
  }

  static createGuestTraveler() {
    const guestEmail = Random.randomString(6) + '@guest.staging.tripactions.xyz';
    cy.createGuestByEmail({ email: guestEmail });
    cy.get(trainSearchSelector.user).click();
    cy.get(trainSearchSelector.addMoreTravelers).type(guestEmail);
    cy.wait('@waitForTravellers');
    cy.get(trainSearchSelector.userEmail).click();
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
  }
}
