import React, { useContext, useEffect, useState } from 'react';
import Icon from '../../../../shared/components/icon';
import { ExtendedFlightSearchResponseItem } from '../../../types';
import SearchResultsConfigurationContext from '../../../search-results-configuration-context';
import { getTranslations } from '../../../../shared/utils/localization-util';
import IndependentFlightOption from './independent-flight-option';
import { useDispatch } from 'react-redux';
import { setFlyInIsOpen, setSelectedFlight } from '../../../store/search-results-slice';
import { useFlightSearch } from '../flight-search-context';
import { getFlightKey } from '../../../utils/flight-utils';
import { format } from 'date-fns';

interface IndependentFlightSelectionProps {
  searchResults: ExtendedFlightSearchResponseItem[];
}

const IndependentFlightSelection: React.FC<IndependentFlightSelectionProps> = ({ searchResults }) => {
  const dispatch = useDispatch();

  const context = useContext(SearchResultsConfigurationContext);
  const translations = getTranslations(context?.languageCode ?? 'en-GB');

  const { onFlightSearch } = useFlightSearch();

  const [selectedOutwardKey, setSelectedOutwardKey] = useState<string | null>(null);
  const [selectedReturnKey, setSelectedReturnKey] = useState<string | null>(null);

  const uniqueOutwardFlights: ExtendedFlightSearchResponseItem[] = React.useMemo(() => {
    const map = new Map();

    searchResults.forEach((flight) => {
      const key = getFlightKey(flight.outward.segments);

      if (!map.has(key)) {
        map.set(key, flight);
      }
    });

    return Array.from(map.values());
  }, [searchResults]);

  const [uniqueReturnFlights, setUniqueReturnFlights] = useState<ExtendedFlightSearchResponseItem[]>([]);

  useEffect(() => {
    if (!selectedOutwardKey) {
      setUniqueReturnFlights([]);
      setSelectedReturnKey(null);
      return;
    }

    // Filter combinations that match selected outward fare
    const matchingCombinations = searchResults.filter((flight) => getFlightKey(flight.outward.segments) === selectedOutwardKey);
    const returnMap = new Map();

    matchingCombinations.forEach((flight) => {
      const key = getFlightKey(flight.return.segments);

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

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

    setUniqueReturnFlights(returns);
  }, [selectedOutwardKey, searchResults]);

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

    return searchResults.find(
      (flight) => getFlightKey(flight.outward.segments) === selectedOutwardKey && getFlightKey(flight.return.segments) === selectedReturnKey
    );
  }, [searchResults, selectedOutwardKey, selectedReturnKey]);

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

    dispatch(setSelectedFlight(selectedCombinationFlight));
    onFlightSearch(selectedCombinationFlight); // Trigger search to update accommodation options based on selected flight
    dispatch(setFlyInIsOpen(true));
  }, [selectedCombinationFlight, dispatch]);

  const selectedOutward = React.useMemo(() => {
    if (!selectedOutwardKey) return null;

    return searchResults.find((flight) => getFlightKey(flight.outward.segments) === selectedOutwardKey) || null;
  }, [searchResults, selectedOutwardKey]);

  const selectedReturn = React.useMemo(() => {
    if (!selectedReturnKey) return null;

    return searchResults.find((flight) => getFlightKey(flight.return.segments) === selectedReturnKey) || null;
  }, [searchResults, selectedReturnKey]);

  const firstResultDate = uniqueOutwardFlights.length > 0 ? uniqueOutwardFlights[0].outward.segments[0].departureDateTime : null;
  const firstResultReturnDate = uniqueReturnFlights.length > 0 ? uniqueReturnFlights[0].return.segments[0].departureDateTime : null;

  const firstResultDay = firstResultDate ? format(firstResultDate, 'd') : null;
  const firstResultMonth = firstResultDate ? format(firstResultDate, 'MMM') : null;
  const firstResultReturnDay = firstResultReturnDate ? format(firstResultReturnDate, 'd') : null;
  const firstResultReturnMonth = firstResultReturnDate ? format(firstResultReturnDate, 'MMM') : null;

  return (
    <>
      <div className="search__results__label search__results__label--secondary">
        <div className="search__results__label__date">
          <p className="search__results__label__date-date">{firstResultDay}</p>
          <p>{firstResultMonth}</p>
        </div>
        <div className="search__results__label__text">
          <Icon name="ui-flight" height={16} fill="white" />
          <h3>
            {translations.SRP.SELECT} <strong> {translations.SRP.DEPARTURE}</strong>
          </h3>
        </div>
      </div>

      <div className="search__results__cards search__results__cards--extended">
        {selectedOutwardKey && selectedOutward ? (
          <IndependentFlightOption
            key={`flight-${selectedOutwardKey}`}
            item={selectedOutward.outward}
            guid={selectedOutward.guid}
            onSelect={() => setSelectedOutwardKey(null)}
            selectedGuid={selectedOutward.guid}
            isOutward={true}
            price={selectedOutward.price}
          />
        ) : (
          uniqueOutwardFlights.map((result) => (
            <IndependentFlightOption
              key={`flight-${result.guid}`}
              item={result.outward}
              onSelect={() => setSelectedOutwardKey(getFlightKey(result.outward.segments))}
              guid={result.guid}
              isOutward={true}
              price={result.price}
            />
          ))
        )}
      </div>

      <div className="search__results__label search__results__label--secondary">
        <div className="search__results__label__date">
          <p className="search__results__label__date-date">{firstResultReturnDay}</p>
          <p>{firstResultReturnMonth}</p>
        </div>
        <div className="search__results__label__text">
          <Icon name="ui-flight" height={16} fill="white" />
          <h3>
            {translations.SRP.SELECT} <strong> {translations.SRP.RETURN}</strong>
          </h3>
        </div>
      </div>

      <div className="search__results__cards search__results__cards--extended">
        {selectedReturnKey && selectedReturn ? (
          <IndependentFlightOption
            key={`flight-${selectedReturnKey}`}
            item={selectedReturn.return}
            guid={selectedReturn.guid}
            selectedGuid={selectedReturn.guid}
            isOutward={false}
            price={selectedReturn.price}
          />
        ) : (
          uniqueReturnFlights.map((result) => (
            <IndependentFlightOption
              key={`flight-${result.guid}`}
              item={result.return}
              onSelect={() => setSelectedReturnKey(getFlightKey(result.return.segments))}
              guid={result.guid}
              isOutward={false}
              price={result.price}
            />
          ))
        )}
      </div>
    </>
  );
};

export default IndependentFlightSelection;
