import React, { useContext, useEffect, useState } from 'react';
import Icon from '../icon';
import { ExtendedFlightSearchResponseItem } from '../../../search-results/types';
import { useFlightSearch } from '../../../search-results/components/flight/flight-search-context';
import { useDispatch, useSelector } from 'react-redux';
import { setSelectedFlightDetails } from '../../../search-results/store/search-results-slice';
import { SearchResultsRootState } from '../../../search-results/store/search-results-store';
import Spinner from '../../../search-results/components/spinner/spinner';
import SearchResultsConfigurationContext from '../../../search-results/search-results-configuration-context';
import { durationTicksInHoursString, getTranslations, timeFromDateTime } from '../../utils/localization-util';
import { getArrivalSegment, getDepartureSegment, getNumberOfStopsLabel } from '../../../search-results/utils/flight-utils';
import { first, isEmpty } from 'lodash';

type FlightsFlyInProps = {
  isOpen: boolean;
  setIsOpen: (open: boolean) => void;
};

const FlightsFlyIn: React.FC<FlightsFlyInProps> = ({ isOpen, setIsOpen }) => {
  const context = useContext(SearchResultsConfigurationContext);
  const language = context?.languageCode ?? 'en-GB';
  const translations = getTranslations(language);

  const dispatch = useDispatch();
  const { flightSearchDetailsLoading, flightDetailsSearchResults, onCancelSearch, numberOfTravellers } = useFlightSearch();
  const { selectedFlight } = useSelector((state: SearchResultsRootState) => state.searchResults);

  const [flights, setFlights] = useState<ExtendedFlightSearchResponseItem[]>([]);
  const [flight, setFlight] = useState<ExtendedFlightSearchResponseItem | undefined>(undefined);

  const [uniqueOutwardFlights, setUniqueOutwardFlights] = useState<ExtendedFlightSearchResponseItem[]>([]);
  const [selectedOutwardFareCode, setSelectedOutwardFareCode] = useState<string | null>(null);
  const [uniqueReturnFlights, setUniqueReturnFlights] = useState<ExtendedFlightSearchResponseItem[]>([]);
  const [selectedReturnFareCode, setSelectedReturnFareCode] = useState<string | null>(null);

  useEffect(() => {
    if (flightDetailsSearchResults.length > 0 && selectedFlight) {
      const routeFlights = flightDetailsSearchResults.filter((r) => r.flightRouteId === selectedFlight.flightRouteId);

      setFlights(routeFlights);
      setFlight(first(routeFlights));

      // Deduplicate by outward fareCode
      const uniqueMap = new Map<string, ExtendedFlightSearchResponseItem>();

      routeFlights.forEach((flight) => {
        const fareCode = flight.outward.segments?.[0]?.metaData?.fareCode;

        if (fareCode && !uniqueMap.has(fareCode)) {
          uniqueMap.set(fareCode, flight);
        }
      });

      const values = Array.from(uniqueMap.values());
      setUniqueOutwardFlights(values);
      const fareCode = first(values)?.outward.segments?.[0]?.metaData?.fareCode;
      setSelectedOutwardFareCode(fareCode ?? null);
    }
  }, [flightDetailsSearchResults, flightSearchDetailsLoading]);

  useEffect(() => {
    if (!selectedOutwardFareCode) {
      setUniqueReturnFlights([]);
      setSelectedReturnFareCode(null);
      return;
    }

    // Filter combinations that match selected outward fare
    const matchingCombinations = flights.filter((flight) => flight.outward.segments?.[0]?.metaData?.fareCode === selectedOutwardFareCode);
    const returnMap = new Map<string, ExtendedFlightSearchResponseItem>();

    // Deduplicate return flights by return fareCode
    matchingCombinations.forEach((flight) => {
      const returnFareCode = flight.return.segments?.[0]?.metaData?.fareCode;

      if (returnFareCode && !returnMap.has(returnFareCode)) {
        returnMap.set(returnFareCode, flight);
      }
    });

    const returns = Array.from(returnMap.values());

    setUniqueReturnFlights(returns);

    // keep current return if still valid based on the selected outward, otherwise select the first available
    const stillValid = returns.some((r) => r.return.segments?.[0]?.metaData?.fareCode === selectedReturnFareCode);

    if (!stillValid) {
      const defaultFareCode = returns[0]?.return.segments?.[0]?.metaData?.fareCode ?? null;
      setSelectedReturnFareCode(defaultFareCode);
    }
  }, [selectedOutwardFareCode, flights]);

  const selectedCombinationFlight = React.useMemo(() => {
    if (!selectedOutwardFareCode || !selectedReturnFareCode) return undefined;

    return flights.find(
      (flight) =>
        flight.outward.segments?.[0]?.metaData?.fareCode === selectedOutwardFareCode &&
        flight.return.segments?.[0]?.metaData?.fareCode === selectedReturnFareCode
    );
  }, [flights, selectedOutwardFareCode, selectedReturnFareCode]);

  useEffect(() => {
    if (!selectedCombinationFlight) return;

    dispatch(setSelectedFlightDetails(selectedCombinationFlight));
  }, [selectedCombinationFlight, dispatch]);

  const getOutwardPriceDiff = (outwardFareCode: string) => {
    if (!selectedReturnFareCode || !selectedCombinationFlight) return 0;

    const combo =
      flights.find(
        (flight) =>
          flight.outward.segments?.[0]?.metaData?.fareCode === outwardFareCode && flight.return.segments?.[0]?.metaData?.fareCode === selectedReturnFareCode
      ) ??
      // it means that outward flight cannot be paired with the selected return fallback to first combo with that outward fare
      flights.find((flight) => flight.outward.segments?.[0]?.metaData?.fareCode === outwardFareCode);

    if (!combo) return 0;

    return Math.round(combo.price - selectedCombinationFlight.price);
  };

  const getReturnPriceDiff = (returnFareCode: string) => {
    if (!selectedOutwardFareCode || !selectedCombinationFlight) return 0;

    const combo =
      flights.find(
        (flight) =>
          flight.outward.segments?.[0]?.metaData?.fareCode === selectedOutwardFareCode && flight.return.segments?.[0]?.metaData?.fareCode === returnFareCode
      ) ??
      // it means that return flight cannot be paired with the selected outward fallback to first combo with that return fare
      flights.find((flight) => flight.return.segments?.[0]?.metaData?.fareCode === returnFareCode);

    if (!combo) return 0;

    return Math.round(combo.price - selectedCombinationFlight.price);
  };

  // TODO: go to booking page?
  const handleConfirm = () => {
    if (isOpen) {
      onCancelSearch();
      setIsOpen(false);
    }
  };

  return (
    <>
      <div className="flyin__content">
        {flightSearchDetailsLoading || isEmpty(flights) ? (
          <Spinner label={translations.SRP.LOADING_FLIGHTS} />
        ) : (
          flight && (
            <div className="flyin__content-text-row">
              <div className="flyin__content-text-icon-row">
                <img
                  src={`https://media.tidesoftware.be/media/shared/Airlines/${getDepartureSegment(flight.outward)?.marketingAirlineCode}.png?height=256`}
                  alt="airline-logo"
                  className="logo"
                  aria-hidden="true"
                />
                <div className="flyin__content-text-col">
                  <span className="flyin__content-text-title-row">
                    <strong>{translations.SRP.DEPARTURE}</strong> {getDepartureSegment(flight?.outward)?.departureAirportCode} -{' '}
                    {getArrivalSegment(flight?.outward)?.arrivalAirportCode}
                  </span>
                  <span className="flyin__content-text">
                    {timeFromDateTime(getDepartureSegment(flight?.outward)?.departureDateTime)} -{' '}
                    {timeFromDateTime(getArrivalSegment(flight?.outward)?.arrivalDateTime)} ({durationTicksInHoursString(flight.outward.durationInTicks)},{' '}
                    {getNumberOfStopsLabel(flight.outward, translations.SRP.DIRECT, translations.SRP.STOPS, translations.SRP.STOP)}), {numberOfTravellers}{' '}
                    travellers
                  </span>
                </div>
              </div>

              <div className="flyin__content-arrow-row">
                <div className="flyin__content-arrow is-disabled" aria-disabled="true">
                  <Icon name="ui-arrow" className="flyin__content-arrow-icon" width={16} height={16} aria-hidden="true" />
                </div>
                <div className="flyin__content-arrow">
                  <Icon name="ui-arrow" className="flyin__content-arrow-icon flyin__content-arrow-icon--forward" width={16} height={16} aria-hidden="true" />
                </div>
              </div>
            </div>
          )
        )}
      </div>
      {!flightSearchDetailsLoading && flight && (
        <>
          <div className="flyin__content-cards-wrapper">
            <div className="flyin__content-cards">
              {uniqueOutwardFlights.map((flightOption, index) => {
                const firstSegment = first(flightOption.outward.segments);
                if (!firstSegment) return null;
                const diff = getOutwardPriceDiff(firstSegment.metaData.fareCode);

                return (
                  <div
                    key={`outward-flight-option-${index}`}
                    className={`flyin__content-card flyin__content-card--flight ${
                      selectedOutwardFareCode === firstSegment.metaData.fareCode ? 'flyin__content-card--selected' : ''
                    }`}>
                    <div className="flyin__content-card-top">
                      <span className="flyin__content-card-top-tag">{firstSegment.metaData.fareMarketingName}</span>
                      {diff !== null && diff != 0 && (
                        <span
                          className={`flyin__content-card-top-price ${
                            diff > 0 ? 'flyin__content-card-top-price--increase' : diff < 0 ? 'flyin__content-card-top-price--decrease' : ''
                          }`}>
                          {diff > 0 ? `+€${diff}` : `-€${Math.abs(diff)}`}
                        </span>
                      )}
                    </div>

                    <div className="flyin__content-card-middle">
                      <div className="flyin__content-card-middle-rows">
                        <div className="flyin__content-card-middle-row">
                          <span className="flyin__content-card-middle-row-left">Number of travellers</span>
                          <span className="flyin__content-card-middle-row-right">{numberOfTravellers}</span>
                        </div>

                        <div className="flyin__content-card-middle-row">
                          <span className="flyin__content-card-middle-row-left">Travel class</span>
                          <span className="flyin__content-card-middle-row-right">{firstSegment.metaData.fareMarketingName}</span>
                        </div>

                        <div className="flyin__content-card-middle-row">
                          <span className="flyin__content-card-middle-row-left">Booking class</span>
                          <span className="flyin__content-card-middle-row-right">{firstSegment.bookingClassCode}</span>
                        </div>

                        <div className="flyin__content-card-middle-row">
                          <span className="flyin__content-card-middle-row-left">Fare basis</span>
                          <span className="flyin__content-card-middle-row-right">{firstSegment.metaData.fareCode}</span>
                        </div>

                        <div className="flyin__content-data">
                          {firstSegment.metaData.luggageCarryOn && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon">
                                <Icon name="ui-bag" width={20} aria-hidden="true" />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Carry-on luggage</div>
                                <div className="flyin__content-data__item-content-description">{firstSegment.metaData.luggageCarryOn.text}</div>
                              </div>
                            </div>
                          )}

                          {firstSegment.metaData.luggageChecked && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon">
                                <Icon name="ui-suitcase" width={20} />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Checked luggage</div>
                                <div className="flyin__content-data__item-content-description">{firstSegment.metaData.luggageChecked.text}</div>
                              </div>
                            </div>
                          )}

                          {firstSegment.metaData.seatSelection && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon">
                                <Icon name="ui-seat" width={20} />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Seat selection</div>
                                <div className="flyin__content-data__item-content-description">{firstSegment.metaData.seatSelection.text}</div>
                              </div>
                            </div>
                          )}

                          {firstSegment.metaData.cancel && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon">
                                <Icon name="ui-refund" width={20} />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Refund</div>
                                <div className="flyin__content-data__item-content-description">{firstSegment.metaData.cancel.text}</div>
                              </div>
                            </div>
                          )}

                          {firstSegment.metaData.other && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon flyin__content-data__item-icon--other">
                                <Icon name="ui-else" width={20} />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Other</div>
                                <ul className="flyin__content-data__item-content-description flyin__content-data__item-content-description--list">
                                  {firstSegment.metaData.other.map((other, index) => (
                                    <li key={`other-${index}`}>{other.text}</li>
                                  ))}
                                </ul>
                              </div>
                            </div>
                          )}
                        </div>
                      </div>
                    </div>
                    <div
                      className="flyin__content-card-button"
                      onClick={() => {
                        const fareCode = flightOption.outward.segments?.[0]?.metaData?.fareCode;
                        setSelectedOutwardFareCode(fareCode ?? null);
                      }}>
                      <div className={`cta ${selectedOutwardFareCode === firstSegment.metaData.fareCode ? 'cta--selected' : ''}`}>
                        {' '}
                        {selectedOutwardFareCode === firstSegment.metaData.fareCode ? 'Selected' : 'Select'}
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>

          <div className="flyin__content">
            <div className="flyin__content-text-row">
              <div className="flyin__content-text-icon-row">
                <img
                  src={`https://media.tidesoftware.be/media/shared/Airlines/${getDepartureSegment(flight.return)?.marketingAirlineCode}.png?height=256`}
                  alt="airline-logo"
                  className="logo"
                  aria-hidden="true"
                />
                <div className="flyin__content-text-col">
                  <span className="flyin__content-text-title-row">
                    <strong>{translations.SRP.RETURN}</strong> {getDepartureSegment(flight?.return)?.departureAirportCode} -{' '}
                    {getArrivalSegment(flight?.return)?.arrivalAirportCode}
                  </span>
                  <span className="flyin__content-text">
                    {timeFromDateTime(getDepartureSegment(flight?.return)?.departureDateTime)} -{' '}
                    {timeFromDateTime(getArrivalSegment(flight?.return)?.arrivalDateTime)} ({durationTicksInHoursString(flight.return.durationInTicks)},{' '}
                    {getNumberOfStopsLabel(flight.return, translations.SRP.DIRECT, translations.SRP.STOPS, translations.SRP.STOP)}), {numberOfTravellers}{' '}
                    travellers
                  </span>
                </div>
              </div>

              <div className="flyin__content-arrow-row">
                <div className="flyin__content-arrow is-disabled" aria-disabled="true">
                  <Icon name="ui-arrow" className="flyin__content-arrow-icon" width={16} height={16} aria-hidden="true" />
                </div>
                <div className="flyin__content-arrow">
                  <Icon name="ui-arrow" className="flyin__content-arrow-icon flyin__content-arrow-icon--forward" width={16} height={16} aria-hidden="true" />
                </div>
              </div>
            </div>
          </div>

          <div className="flyin__content-cards-wrapper">
            <div className="flyin__content-cards">
              {uniqueReturnFlights.map((flightOption, index) => {
                const firstSegment = first(flightOption.return.segments);
                if (!firstSegment) return null;
                const diff = getReturnPriceDiff(firstSegment.metaData.fareCode);
                return (
                  <div
                    key={`return-flight-option-${index}`}
                    className={`flyin__content-card flyin__content-card--flight ${
                      selectedReturnFareCode === firstSegment.metaData.fareCode ? 'flyin__content-card--selected' : ''
                    }`}>
                    <div className="flyin__content-card-top">
                      <span className="flyin__content-card-top-tag">{firstSegment.metaData.fareMarketingName}</span>
                      {diff !== null && diff != 0 && (
                        <span
                          className={`flyin__content-card-top-price ${
                            diff > 0 ? 'flyin__content-card-top-price--increase' : diff < 0 ? 'flyin__content-card-top-price--decrease' : ''
                          }`}>
                          {diff > 0 ? `+€${diff}` : `-€${Math.abs(diff)}`}
                        </span>
                      )}
                    </div>

                    <div className="flyin__content-card-middle">
                      <div className="flyin__content-card-middle-rows">
                        <div className="flyin__content-card-middle-row">
                          <span className="flyin__content-card-middle-row-left">Number of travellers</span>
                          <span className="flyin__content-card-middle-row-right">{numberOfTravellers}</span>
                        </div>

                        <div className="flyin__content-card-middle-row">
                          <span className="flyin__content-card-middle-row-left">Travel class</span>
                          <span className="flyin__content-card-middle-row-right">{firstSegment.metaData.fareMarketingName}</span>
                        </div>

                        <div className="flyin__content-card-middle-row">
                          <span className="flyin__content-card-middle-row-left">Booking class</span>
                          <span className="flyin__content-card-middle-row-right">{firstSegment.bookingClassCode}</span>
                        </div>

                        <div className="flyin__content-card-middle-row">
                          <span className="flyin__content-card-middle-row-left">Fare basis</span>
                          <span className="flyin__content-card-middle-row-right">{firstSegment.metaData.fareCode}</span>
                        </div>

                        <div className="flyin__content-data">
                          {firstSegment.metaData.luggageCarryOn && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon">
                                <Icon name="ui-bag" width={20} aria-hidden="true" />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Carry-on luggage</div>
                                <div className="flyin__content-data__item-content-description">{firstSegment.metaData.luggageCarryOn.text}</div>
                              </div>
                            </div>
                          )}

                          {firstSegment.metaData.luggageChecked && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon">
                                <Icon name="ui-suitcase" width={20} />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Checked luggage</div>
                                <div className="flyin__content-data__item-content-description">{firstSegment.metaData.luggageChecked.text}</div>
                              </div>
                            </div>
                          )}

                          {firstSegment.metaData.seatSelection && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon">
                                <Icon name="ui-seat" width={20} />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Seat selection</div>
                                <div className="flyin__content-data__item-content-description">{firstSegment.metaData.seatSelection.text}</div>
                              </div>
                            </div>
                          )}

                          {firstSegment.metaData.cancel && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon">
                                <Icon name="ui-refund" width={20} />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Refund</div>
                                <div className="flyin__content-data__item-content-description">{firstSegment.metaData.cancel.text}</div>
                              </div>
                            </div>
                          )}

                          {firstSegment.metaData.other && (
                            <div className="flyin__content-data__item">
                              <div className="flyin__content-data__item-icon flyin__content-data__item-icon--other">
                                <Icon name="ui-else" width={20} />
                              </div>
                              <div className="flyin__content-data__item-content">
                                <div className="flyin__content-data__item-content-title">Other</div>
                                <ul className="flyin__content-data__item-content-description flyin__content-data__item-content-description--list">
                                  {firstSegment.metaData.other.map((other, index) => (
                                    <li key={`other-${index}`}>{other.text}</li>
                                  ))}
                                </ul>
                              </div>
                            </div>
                          )}
                        </div>
                      </div>
                    </div>
                    <div
                      className="flyin__content-card-button"
                      onClick={() => {
                        const fareCode = flightOption.return.segments?.[0]?.metaData?.fareCode;
                        setSelectedReturnFareCode(fareCode ?? null);
                      }}>
                      <div className={`cta ${selectedReturnFareCode === firstSegment.metaData.fareCode ? 'cta--selected' : ''}`}>
                        {' '}
                        {selectedReturnFareCode === firstSegment.metaData.fareCode ? 'Selected' : 'Select'}
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </>
      )}
      {!flightSearchDetailsLoading && (
        <div className="flyin__footer">
          <div className="flyin__footer__price">
            {translations.SHARED.TOTAL_PRICE}: €{selectedCombinationFlight?.price?.toFixed(2)}
          </div>
          <div className="flyin__button-wrapper">
            <button className="cta cta--select" onClick={handleConfirm}>
              {translations.PRODUCT.BOOK_NOW}
            </button>
          </div>
        </div>
      )}
    </>
  );
};

export default FlightsFlyIn;
