import { Timeouts } from '@utility-lib/constants';
import { TrainTripType } from '@train-lib/index';

const seatMapSelector = {
  seatSelector: '[class^="ta-train-seat__seat-number "]',
  contentSelector: '[class="ta-form-wrap__content"]',
  upperSeatLabel: '[aria-label="Upper"]',
  seatWrapperSelector: '.ta-train-seat-wrapper',
  seatNumberSelector: '.ta-train-seat__seat-number',
  confirmSeatSelector: '[class="ta-button__content"]',
  selectedSeat: '[class^="ta-train-seat-map__body__passenger"] span'
};

export class SeatMap {
  static selectSeat(selectSeat: number) {
    cy.get('[class="seat-map-block__selection"]').eq(selectSeat).click();
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
  }

  static selectDeck(selectDeck: number) {
    cy.get(seatMapSelector.contentSelector).eq(selectDeck).click();
    cy.get(seatMapSelector.upperSeatLabel).click();
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
  }

  static processSeatSelection(
    seatSelector: string,
    cacheKey: string,
    multipleTravelers = false
  ) {
    cy.get(seatSelector).then(($seats) => {
      const seatWithColor = $seats.filter((index, seat) => {
        return Cypress.$(seat).css('color') === 'rgb(115, 0, 205)';
      });
      if (seatWithColor.length > 0) {
        cy.wrap(seatWithColor.first()).click();
      } else {
        cy.get(seatMapSelector.contentSelector).then(($contents) => {
          const numberOfContents = $contents.length;
          if (numberOfContents > 0) {
            for (let i = 0; i < numberOfContents; i++) {
              this.selectDeck(i);
            }
          }

          this.getFreeSeatNoAndSelect(cacheKey);
        });
      }
    });

    this.getSeatNoFromCache(multipleTravelers);
    this.confirmSeatSelection();
  }

  static getFreeSeatNoAndSelect(cacheKey: string) {
    cy.get(`${seatMapSelector.seatWrapperSelector} ${seatMapSelector.seatNumberSelector}`)
      .contains(seatMapSelector.seatNumberSelector, /\d+/)
      .invoke('text')
      .then((seatNumber) => {
        cy.task('putDataInCache', {
          key: cacheKey,
          data: seatNumber
        });

        cy.contains(
          `${seatMapSelector.seatWrapperSelector}
         ${seatMapSelector.seatNumberSelector}`,
          seatNumber
        ).click();

        cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
        cy.get('body').then(($body) => {
          const bodyText = $body.text();
          if (bodyText.includes('Unassigned')) {
            cy.get('[class^="ta-train-seat-map__body__passenger"] span ')
              .contains('Unassigned')
              .click();
            this.getFreeSeatNoAndSelect(cacheKey);
          }
        });
      });
  }

  static getSeatNoFromCache(multipleTravelers = false) {
    cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
    const handleSeatElement = ($element: any, index: any) => {
      cy.wrap($element)
        .invoke('text')
        .then((seatNumber) => {
          cy.wait(Timeouts.SHORT_TIMEOUT_2_SEC.timeout);
          cy.log(`selected Seat Number ${index + 1}: ${seatNumber}`);
          cy.contains(seatNumber).should('be.visible');
          cy.task('putDataInCache', {
            key: multipleTravelers ? `seatNumberFound${index + 1}` : 'seatNumberFound',
            data: seatNumber
          });
        });
    };

    if (multipleTravelers) {
      cy.get(seatMapSelector.selectedSeat).each(handleSeatElement);
    } else {
      cy.get(seatMapSelector.selectedSeat).then(([element]) => {
        handleSeatElement(element, 0);
      });
    }
  }

  static confirmSeatSelection() {
    cy.get(seatMapSelector.confirmSeatSelector).contains('Confirm seats').click();
  }

  static chooseSeatFromMap(trainTripType: TrainTripType, multipleTravelers = false) {
    if (trainTripType === TrainTripType.ONEWAY) {
      this.selectSeat(0);
      SeatMap.processSeatSelection(
        seatMapSelector.seatSelector,
        'seatNumberOneWay',
        multipleTravelers
      );
    } else if (trainTripType === TrainTripType.ROUND_TRIP) {
      for (let i = 0; i <= 1; i++) {
        this.selectSeat(i);
        SeatMap.processSeatSelection(
          seatMapSelector.seatSelector,
          `seatNumberRoundTrip_${i + 1}`,
          multipleTravelers
        );
      }
    }
  }
}
