import React from "react";
import { Outlet } from "react-router-dom";
import { CoupleApi, CouplesList } from "../../api/genealogy/CoupleApi";
import { MemberApi, MembersList } from "../../api/genealogy/MemberApi";
import { AsyncWidget } from "../AsyncWidget";
import { useFamily } from "../BaseFamilyRoute";

interface GenealogyContext {
  members: MembersList;
  couples: CouplesList;
  reloadMembersList: () => Promise<void>;
  reloadCouplesList: () => Promise<void>;
}

const GenealogyContextK = React.createContext<GenealogyContext | null>(null);

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

  const [members, setMembers] = React.useState<null | MembersList>(null);
  const [couples, setCouples] = React.useState<null | CouplesList>(null);

  const loadKey = React.useRef(1);

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

  const load = async () => {
    setMembers(await MemberApi.GetEntireList(family.familyId));
    setCouples(await CoupleApi.GetEntireList(family.familyId));
  };

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

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

  return (
    <AsyncWidget
      ready={members !== null && couples !== null}
      loadKey={`${family.familyId}-${loadKey.current}`}
      load={load}
      errMsg="Échec du chargement des informations de généalogie de la famille !"
      build={() => {
        if (loadPromise.current != null) {
          loadPromise.current?.();
          loadPromise.current = null;
        }

        return (
          <GenealogyContextK.Provider
            value={{
              members: members!,
              couples: couples!,
              reloadMembersList: onReload,
              reloadCouplesList: onReload,
            }}
          >
            <Outlet />
          </GenealogyContextK.Provider>
        );
      }}
    />
  );
}

export function useGenealogy(): GenealogyContext {
  return React.useContext(GenealogyContextK)!;
}
