import { useState } from "react";

interface State<D> {
    data: D | null,
    error: Error | null,
    stat: "idel" | "loading" | "error" | "success"
}
const defaultInitState: State<null> = {
    data: null,
    error: null,
    stat: "idel"
}

export const useAsync = <D>(initState?: State<D>) => {
    const [state, setState] = useState<State<D>>({
        ...defaultInitState,
        ...initState
    })

    const setDate = (data: D) => setState({
        data,
        error: null,
        stat: "success"
    })
    const setError = (error: Error) => setState({
        data: null,
        error: error,
        stat: "error"
    })

    const run = (promiss: Promise<D>) => {
        if (!promiss || !promiss.then) {
            throw new Error("sdasd")
        }
        setState({ ...state, stat: "loading" })
        return promiss.then(data => {
            setDate(data)
            return data;
        }).catch((error) => {
            setError(error)
            return error
        })
    }
    return {
        isIdle: state.stat === "idel",
        isLoading: state.stat === "loading",
        isError: state.stat === "error",
        isSuccess: state.stat === "success",
        run,
        setDate,
        setError,
        ...state
    }
};