import { createContext, ReactNode, use, useEffect, useMemo, useState, useTransition } from 'react';
import init, * as funcs from './color_functions/color_module';

export type ColorFunctionContextType = {
  colorFn: typeof funcs | null;
  isLoading: boolean;
  error: Error | null;
};
const ColorFunctionContext = createContext<ColorFunctionContextType>({
  colorFn: null,
  isLoading: true,
  error: null,
});

type WasmProviderProps = {
  children?: ReactNode;
};

export function useColorFunction(): ColorFunctionContextType {
  const context = use<ColorFunctionContextType>(ColorFunctionContext);

  return context;
}

export function ColorFunctionProvider({ children }: WasmProviderProps) {
  const [wasmInstance, setWasmInstance] = useState<Wasm.InitOutput | null>(null);
  const [isPending, startTransition] = useTransition();
  const [error, setError] = useState<Error | null>(null);

  const contextValue = useMemo(
    () =>
      ({
        colorFn: wasmInstance,
        isLoading: isPending,
        error,
      } as ColorFunctionContextType),
    [wasmInstance, isPending, error],
  );
  useEffect(() => {
    (function () {
      startTransition(async () => {
        try {
          await init();
          setWasmInstance(funcs);
        } catch (e) {
          console.error('[Load WASM]', e);
          setError(e);
        }
      });
    })();
  }, []);

  return <ColorFunctionContext value={contextValue}>{children}</ColorFunctionContext>;
}
