import { useEffect, useState } from "react";

import { api } from "../api";
import { Company } from "../types";
import { useViewResource, ViewResourceError } from "./useViewResource";

let cachedCompanies: Company[] | null = null;
let inflight: Promise<Company[]> | null = null;

async function fetchCompanies(): Promise<Company[]> {
  if (cachedCompanies) return cachedCompanies;
  if (inflight) return inflight;

  inflight = api
    .get<Company[]>('/companies')
    .then((r) => {
      cachedCompanies = r.data;
      return r.data;
    })
    .finally(() => {
      inflight = null;
    });

  return inflight;
}

export function invalidateCompaniesCache() {
  cachedCompanies = null;
}

export function useCompanies(): {
  companies: Company[];
  loading: boolean;
  refreshing: boolean;
  error: ViewResourceError | null;
  reload: () => Promise<void>;
} {
  const [cacheBust, setCacheBust] = useState(0);
  const resource = useViewResource(fetchCompanies, {
    initialData: cachedCompanies ?? [],
    errorMessage: 'Unable to load companies right now.',
    deps: [cacheBust],
  });

  useEffect(() => {
    if (!resource.error) {
      cachedCompanies = resource.data;
    }
  }, [resource.data, resource.error]);

  return {
    companies: resource.data,
    loading: resource.loading,
    refreshing: resource.refreshing,
    error: resource.error,
    reload: async () => {
      invalidateCompaniesCache();
      setCacheBust((value) => value + 1);
    },
  };
}
