import { createSelector } from '@reduxjs/toolkit';
import { SearchResultsRootState } from './search-results-store';
import { getFlightKey } from '../utils/flight-utils';
import { PackagingFlightResponse } from '@qite/tide-client';

const selectSearchResultsState = (state: SearchResultsRootState) => state.searchResults;

export const selectPackagingAccoResults = createSelector([selectSearchResultsState], (state) => state.packagingAccoResults);
export const selectSelectedPackagingAccoResultCode = createSelector([selectSearchResultsState], (state) => state.selectedPackagingAccoResultCode);
export const selectSelectedPackagingAccoResult = createSelector(
  [selectPackagingAccoResults, selectSelectedPackagingAccoResultCode],
  (packagingAccoResults, selectedPackagingAccoResultCode) => {
    if (!selectedPackagingAccoResultCode) return null;

    return packagingAccoResults.find((accoResult) => accoResult.code === selectedPackagingAccoResultCode) ?? null;
  }
);

export const selectPackagingFlightResults = createSelector([selectSearchResultsState], (state) => state.packagingFlightResults);
export const selectFilteredPackagingFlightResults = createSelector([selectSearchResultsState], (state) => state.filteredPackagingFlightResults);

export const selectSelectedOutwardKey = createSelector([selectSearchResultsState], (state) => state.selectedOutwardKey);

export const selectSelectedReturnKey = createSelector([selectSearchResultsState], (state) => state.selectedReturnKey);

export const selectUniqueOutwardFlights = createSelector([selectFilteredPackagingFlightResults], (packagingFlightResults): PackagingFlightResponse[] => {
  const map = new Map<string, PackagingFlightResponse>();

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

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

  return Array.from(map.values());
});

export const selectUniqueReturnFlights = createSelector(
  [selectFilteredPackagingFlightResults, selectSelectedOutwardKey],
  (packagingFlightResults, selectedOutwardKey): PackagingFlightResponse[] => {
    if (!selectedOutwardKey) return [];

    const matchingCombinations = packagingFlightResults.filter((flight) => getFlightKey(flight.outward.segments) === selectedOutwardKey);

    const map = new Map<string, PackagingFlightResponse>();

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

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

    return Array.from(map.values());
  }
);

export const selectSelectedOutward = createSelector([selectPackagingFlightResults, selectSelectedOutwardKey], (packagingFlightResults, selectedOutwardKey) => {
  if (!selectedOutwardKey) return null;

  return packagingFlightResults.find((flight) => getFlightKey(flight.outward.segments) === selectedOutwardKey) ?? null;
});

export const selectSelectedReturn = createSelector([selectPackagingFlightResults, selectSelectedReturnKey], (packagingFlightResults, selectedReturnKey) => {
  if (!selectedReturnKey) return null;

  return packagingFlightResults.find((flight) => getFlightKey(flight.return.segments) === selectedReturnKey) ?? null;
});

export const selectSelectedCombinationFlight = createSelector(
  [selectPackagingFlightResults, selectSelectedOutwardKey, selectSelectedReturnKey],
  (packagingFlightResults, selectedOutwardKey, selectedReturnKey) => {
    if (!selectedOutwardKey || !selectedReturnKey) return null;

    return (
      packagingFlightResults.find(
        (flight) => getFlightKey(flight.outward.segments) === selectedOutwardKey && getFlightKey(flight.return.segments) === selectedReturnKey
      ) ?? null
    );
  }
);
