import React from "react";
import { Outlet } from "react-router-dom";
import {
  AccommodationListApi,
  AccommodationsList,
} from "../../api/accommodations/AccommodationListApi";
import { CreateAccommodationCalendarURLDialogProvider } from "../../hooks/context_providers/accommodations/CreateAccommodationCalendarURLDialogProvider";
import { InstallCalendarDialogProvider } from "../../hooks/context_providers/accommodations/InstallCalendarDialogProvider";
import { UpdateAccommodationDialogProvider } from "../../hooks/context_providers/accommodations/UpdateAccommodationDialogProvider";
import { UpdateReservationDialogProvider } from "../../hooks/context_providers/accommodations/UpdateReservationDialogProvider";
import { AsyncWidget } from "../AsyncWidget";
import { useFamily } from "../BaseFamilyRoute";

interface AccommodationsContext {
  accommodations: AccommodationsList;
  reloadAccommodationsList: () => Promise<void>;
}

const AccommodationsContextK =
  React.createContext<AccommodationsContext | null>(null);

export function BaseAccommodationsRoute(): React.ReactElement {
  const family = useFamily();

  const [accommodations, setAccommodations] =
    React.useState<null | AccommodationsList>(null);

  const loadKey = React.useRef(1);

  const loadPromise = React.useRef<() => void>();

  const load = async () => {
    setAccommodations(
      await AccommodationListApi.GetListOfFamily(family.family)
    );
  };

  const onReload = async () => {
    loadKey.current += 1;
    setAccommodations(null);

    return new Promise<void>((res, _rej) => {
      loadPromise.current = () => res();
    });
  };

  return (
    <AsyncWidget
      ready={accommodations !== null}
      loadKey={`${family.familyId}-${loadKey.current}`}
      load={load}
      errMsg="Échec du chargement des informations sur les logements de la famille !"
      build={() => {
        if (loadPromise.current != null) {
          loadPromise.current?.();
          loadPromise.current = undefined;
        }

        return (
          <AccommodationsContextK.Provider
            value={{
              accommodations: accommodations!,
              reloadAccommodationsList: onReload,
            }}
          >
            <UpdateAccommodationDialogProvider>
              <CreateAccommodationCalendarURLDialogProvider>
                <InstallCalendarDialogProvider>
                  <UpdateReservationDialogProvider>
                    <Outlet />
                  </UpdateReservationDialogProvider>
                </InstallCalendarDialogProvider>
              </CreateAccommodationCalendarURLDialogProvider>
            </UpdateAccommodationDialogProvider>
          </AccommodationsContextK.Provider>
        );
      }}
    />
  );
}

export function useAccommodations(): AccommodationsContext {
  return React.useContext(AccommodationsContextK)!;
}
