import type { Dispatch, SetStateAction } from 'react';
import { useEffect, useRef, useState } from 'react';
import type { Route } from '@lifi/sdk';
import { ProgressToNextUpdate } from '../../components/ProgressToNextUpdate.js';
import { useRoutes } from '../../hooks/useRoutes.js';
import { useRouteExecutionStoreContext } from '../../stores/routes/RouteExecutionStore.js';
import { useSetExecutableRoute } from '../../stores/routes/useSetExecutableRoute.js';

export interface RouteTrackerProps {
  observableRouteId: string;
  onChange: Dispatch<SetStateAction<string>>;
  onFetching: Dispatch<SetStateAction<boolean>>;
}

export const RouteTracker = ({
  observableRouteId,
  onChange,
  onFetching,
}: RouteTrackerProps) => {
  const routeExecutionStore = useRouteExecutionStoreContext();
  const setExecutableRoute = useSetExecutableRoute();
  const [observableRoute, setObservableRoute] = useState<Route | undefined>(
    undefined,
  );
  const observableRouteIdRef = useRef<string | undefined>(undefined);

  useEffect(() => {
    const route =
      routeExecutionStore.getState().routes[observableRouteId]?.route;
    setObservableRoute(route);
    observableRouteIdRef.current = route?.id;
  }, [observableRouteId, routeExecutionStore]);

  const { routes, isFetching, dataUpdatedAt, refetchTime, refetch } = useRoutes(
    { observableRoute },
  );
  const currentRoute = routes?.[0];

  /**
   * The reviewable route is the route that the user currently sees on the review page.
   * The observable route is the route for which we track bridges and exchanges.
   * This allows us to query the route using the same tool each time we refresh.
   * The observable and reviewable routes can be the same when we first enter the review page.
   */
  useEffect(() => {
    if (
      observableRouteIdRef.current &&
      currentRoute &&
      observableRouteIdRef.current !== currentRoute.id
    ) {
      // Only track the current route, don't maintain multiple observable routes
      observableRouteIdRef.current = currentRoute.id;
      setExecutableRoute(currentRoute, [currentRoute.id]);
      onChange(currentRoute.id);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentRoute?.id, observableRouteId, onChange, setExecutableRoute]);

  useEffect(() => {
    onFetching(isFetching);
  }, [isFetching, onFetching]);

  const handleRefetch = () => {
    refetch();
  };

  return (
    <ProgressToNextUpdate
      updatedAt={dataUpdatedAt || new Date().getTime()}
      timeToUpdate={refetchTime}
      isLoading={isFetching}
      onClick={handleRefetch}
      sx={{ marginRight: -1 }}
      size="medium"
    />
  );
};
