import {useContext, useEffect, useMemo, useRef} from 'react';

import { getItem, saveItem } from '@common/StorageHelper.ts';
import { COMMONINFO_KEY } from '@common/constants';
import {
  CommonContext,
  CommonState,
  PartialCommonInfo,
} from '@common/contexts/CommonContext.tsx';

const useCommon = (): {
  state: CommonState;
  actions: {
    save: <T extends keyof PartialCommonInfo>(
      key: T,
      value: PartialCommonInfo[T],
    ) => Promise<void>;
  };
} => {
  const context = useContext(CommonContext);
  if (!context) {
    throw new Error('useCommon must be used in CommonProvider!');
  }

  const contextRef = useRef(context);
  useEffect(() => {
    contextRef.current = context;
  }, [context]);

  const authActions = useMemo(
    () => ({
      save: async <T extends keyof PartialCommonInfo>(
        key: T,
        value: PartialCommonInfo[T],
      ) => {
        const commonValue = await getItem(COMMONINFO_KEY);
        const parsedValue: PartialCommonInfo = commonValue
          ? JSON.parse(commonValue)
          : {};
        const mergedValue = {
          ...parsedValue,
          [key]: value,
        };
        await saveItem(
          COMMONINFO_KEY,
          JSON.stringify({
            ...parsedValue,
            [key]: value,
          }),
        );
        contextRef.current.dispatch({
          type: 'save',
          payload: mergedValue,
        });
      },
    }),
    [],
  );

  return {state: context.state, actions: authActions};
};

export {useCommon};
