import {
  ConciergeFlow,
  TrainCards,
  TrainFareType,
  TrainLoyaltyCard,
  TrainSearch,
  TrainSearchModalUtil,
  TrainSearchResults,
  TrainTripType,
  trainSearchResultSelector
} from '@train-lib/index';

import { CheckoutModal } from './checkout_modal';
import { trainCardSelector } from '@train-lib/loyalty_card';
import { Timeouts } from '@utility-lib/constants';

interface BookingOptions {
  tripType: TrainTripType;
  origin: string;
  destination: string;
  fareType?: TrainFareType;
  isConcierge?: boolean;
  corporateDiscount?: boolean;
  noOfTravelers?: number;
}
interface LoyaltyCardBookingOptions {
  loyaltyCard: string;
  origin: string;
  destination: string;
  loyaltyCardNumber: string;
}

interface TripOptions {
  tripType: TrainTripType;
  fareType?: TrainFareType;
  corporateDiscount?: boolean;
}

export class TrainBookings {
  static createBooking(options: BookingOptions) {
    const {
      tripType,
      origin,
      destination,
      fareType,
      isConcierge = false,
      corporateDiscount = false,
      noOfTravelers
    } = options;

    TrainSearchModalUtil.executeTrainSearch({
      origin,
      destination,
      tripType,
      dbSeat: false
    });
    if (isConcierge) {
      ConciergeFlow.completeConciergeForm(origin, destination, tripType);
    } else {
      this.selectTripAndProcessForCheckout({
        tripType,

        fareType,
        corporateDiscount
      });
      CheckoutModal.checkout({ tripType, noOfTravelers });
    }
  }

  static selectTripAndProcessForCheckout(options: TripOptions) {
    const { tripType, fareType, corporateDiscount } = options;
    TrainSearchResults.expectSearchResultPresent();

    if (tripType === TrainTripType.ONEWAY) {
      if (fareType) {
        TrainSearchResults.selectCorrectFare(fareType);
      }
      if (corporateDiscount) {
        this.expectCompanyPreferredFareIsPresent();
      }
      if (fareType === TrainFareType.Bus_Connection) {
        this.selectBusConnectionFare();
      }

      TrainSearchResults.proceedToCheckoutPage();
    } else if (tripType === TrainTripType.ROUND_TRIP) {
      if (fareType) {
        TrainSearchResults.selectCorrectFare(fareType);
        TrainSearchResults.selectReturn();
        cy.wait(Timeouts.MEDIUM_TIMEOUT_20_SEC.timeout);

        TrainSearchResults.selectCorrectFare(fareType);
        TrainSearchResults.getSegmentDetails();
      }

      if (corporateDiscount) {
        this.expectCompanyPreferredFareIsPresent();
      }

      if (fareType) {
        TrainSearchResults.proceedToCheckoutPage();
      } else {
        TrainSearchResults.selectTrain(1);
      }
    }
  }

  static expectCompanyPreferredFareIsPresent() {
    cy.get('[label="Company preferred"]').should('be.visible');
  }

  static processSearchRequest(origin: string, destination: string) {
    TrainSearchModalUtil.executeTrainSearch({
      origin,
      destination,
      tripType: TrainTripType.ROUND_TRIP
    });
  }
  static executeOnewayBookingWithLoyaltyCard(options: LoyaltyCardBookingOptions) {
    const { loyaltyCard, origin, destination, loyaltyCardNumber } = options;
    TrainSearch.visitTrainSearch('Business');
    TrainLoyaltyCard.addTrainCard();
    if (loyaltyCard === TrainCards.AmtrakRewards) {
      cy.get(trainCardSelector.addNewTrainCard).click();
      TrainLoyaltyCard.selectLoyaltyCard(loyaltyCard);
      TrainLoyaltyCard.addCardNumber(loyaltyCardNumber);
      TrainLoyaltyCard.saveAddedCard();
    } else {
      TrainLoyaltyCard.searchAndSelectLoyaltyCard(loyaltyCard, loyaltyCardNumber);
    }
    TrainLoyaltyCard.expectLoyaltyCardAdded();
    TrainSearch.setOrigin(origin);
    TrainSearch.setDestination(destination);
    TrainSearch.selectFutureTrainDate();
    TrainSearch.selectTripTileType(TrainTripType.ONEWAY);
    TrainSearch.searchTrain();
    TrainSearchResults.expectSearchResultPresent();
    TrainSearchResults.proceedToCheckoutPage();
    CheckoutModal.checkout({ loyaltyCard: true });
  }
  static processSearchResult(options: { tripType: TrainTripType; dbSeat?: boolean; provider?: string; fare?: string }) {
    const { tripType, dbSeat = false, fare } = options;
    TrainSearchResults.expectSearchResultPresent();
    this.selectMultiSegmentFare(dbSeat);
    if (fare) {
      TrainSearchResults.selectCorrectFare(fare);
    }
    if (tripType === TrainTripType.ROUND_TRIP) {
      TrainSearchResults.selectRoundTripFare(fare);
    }
    TrainSearchResults.proceedToCheckoutPage();
  }
  static selectMultiSegmentFare(dbSeat = false) {
    if (dbSeat) {
      cy.log('dbSeat is true');
      cy.get(trainSearchResultSelector.trainChange)
        .contains(/change|changes/i)
        .parentsUntil(trainSearchResultSelector.taCard)
        .eq(0)
        .click();
      cy.get(trainSearchResultSelector.summarySegment).should('contain', /change|changes/i);
    }
  }
  static selectBusConnectionFare() {
    cy.get(trainSearchResultSelector.trainChange).each(($el) => {
      const text = $el.text().trim();
      if (text.includes('change')) {
        cy.wrap($el).click();
        cy.get(trainSearchResultSelector.segmentInfo).should('contain', `Connecting Bus`);
        cy.get(trainSearchResultSelector.closeModal).click();
        cy.wrap($el).parents(trainSearchResultSelector.cardContainer).click();
        cy.get(trainSearchResultSelector.fareSummaryTrainChange).should('contain', 'change');
      }
    });
  }
}
