import { AsyncResult } from "@/hooks";
import React from "react";
import { CircularProgress } from "@material-ui/core";
import { Alert } from "@material-ui/lab";
import { Loading } from "@/components/loading";

type AsyncProps<TValue, TError = any> = {
    async: AsyncResult<TValue>,
    children: (value: TValue) => JSX.Element,
    loading?: () => JSX.Element,
    error?: (error: TError) => JSX.Element,
}

const defaultLoading = () => <Loading />;
const defaultError = (error: any) => <Alert severity="error">{ error.message }</Alert>;

export function Async<TValue, TError = any>(
    { async, children: render, loading = defaultLoading, error = defaultError }: AsyncProps<TValue, TError>
) {
    if (async.isLoading || (!async.error && !async.value)) {
        return loading();
    }

    if (typeof async.error !== "undefined") {
        return error(async.error);
    }

    return render(async.value as TValue);
}
