import React, { createContext, useReducer, Dispatch, FC } from "react";
import reducer, { State, getInitialState } from "./reducer";
import { Action } from "./actionTypes";

const Provider: FC = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, getInitialState());

  return (
    <StateContext.Provider value={state}>
      <DispatchContext.Provider value={asyncDispatchWrap(dispatch)}>
        {children}
      </DispatchContext.Provider>
    </StateContext.Provider>
  );
};

type AsyncDispatch = (
  action: Action | ((...args: any) => Promise<any>)
) => void;

function asyncDispatchWrap(dispatch: Dispatch<Action>) {
  const asyncDispatch: AsyncDispatch = (action) => {
    if (action instanceof Function) {
      action(dispatch);
      return;
    }
    dispatch(action);
  };

  return asyncDispatch;
}

export const StateContext = createContext<State>({});
export const DispatchContext = createContext<
  (action: Action | ((...args: any) => Promise<any>)) => void
>(asyncDispatchWrap((dispatch) => {}));

export default Provider;
