import { useState, useEffect } from 'preact/hooks';
import axios from 'axios';
// Types
import { TypeOrNull } from 'sharedTypes';
import { RoadsFavEntity } from 'sharedHelpers/cookies/types';
import { RoadsAPI, RoadsAPIReturn } from './types';

// Axios config
const { REACT_APP_API_HOST, REACT_APP_API_KEY } = process.env;

axios.defaults.baseURL = REACT_APP_API_HOST;
axios.defaults.headers = { 'Ocp-Apim-Subscription-Key': REACT_APP_API_KEY };

interface UseFetchReturn {
  response: TypeOrNull<{ filteredData: RoadsAPIReturn[] }>;
  isFetching: boolean;
  hasError: boolean;
}

const useFetchRoads = (favs: RoadsFavEntity[]): UseFetchReturn => {
  const [response, setResponse] = useState<TypeOrNull<{ filteredData: RoadsAPIReturn[] }>>(null);
  const [isFetching, setIsFetching] = useState<boolean>(true);
  const [hasError, setHasError] = useState<boolean>(false); // Placeholder to set error messaging

  // Function used to fetch from/to train stations
  const fetchData = ({ lat, lon, radius, address }: RoadsFavEntity) => {
    const milesToMeters = (miles: number) => Math.round(miles * 1609.344); // Convert miles into meters (as API GET takes meters, not miles)

    return axios
      .get<TypeOrNull<RoadsAPI>>(
        `/Disruption/v2/Count/road?${lat}&lon=${lon}&rad=${milesToMeters(radius || 1)}`
      )
      .then((resp): RoadsAPIReturn => {
        const responseData = resp.data;

        // Structure object of data to return so that we can use it in our react components (disruption indicator)
        const roadsObj = {
          address: address || 'No location found',
          radius: radius || 0,
          lat: lat || 0,
          lon: lon || 0,
          amountOfDisruptions: responseData?.totals.road || 0,
          disruptionSeverity: responseData?.status.road || 'normal',
        };

        return roadsObj;
      })
      .catch(error => {
        throw new Error(error);
      });
  };

  // START HERE
  useEffect(() => {
    if (!favs) return;

    const resolvePromises = () => {
      // Create a promise that resolves when all train fetches have resolved
      const fetchFavs = favs.map(roadsFav => fetchData(roadsFav));
      Promise.all(fetchFavs)
        .then(data => {
          // Filter out any null or undefined
          const filteredData = data.filter(
            roadsDisruptions => roadsDisruptions !== undefined && roadsDisruptions !== null
          ); // marking as DataEntity array as we have filtered out undefined and null items;
          setResponse({ filteredData } as { filteredData: RoadsAPIReturn[] });
        })
        .catch(error => {
          // eslint-disable-next-line no-console
          console.error({ error });
          setHasError(true);
        })
        .finally(() => setIsFetching(false));
    };

    resolvePromises();
  }, [favs]);

  return { response, isFetching, hasError };
};

export default useFetchRoads;
