import { PropsWithChildren, createContext, useContext, useMemo } from 'react';

import { GeneralFormControlProps } from '../../types';
import { FileUploadInputErrorCode } from '../constants';
import { FileUploadFileMeta } from '../types';

export interface FileUploadContextValue {
  caption?: string;
  mimeTypes: string[];
  onSelect(files: File[]): void;
  onCancel(id: string): void;
  onInputError?(code: FileUploadInputErrorCode, files: File[]): void;
  fileList: FileUploadFileMeta[];
  disabled: boolean;
  multiple: boolean;
  inputProps: Omit<
    GeneralFormControlProps<unknown>,
    'value' | 'disabled' | 'onChange' | 'onBlur' | 'className' | 'testId'
  >;
}

const FileUploadContext = createContext<FileUploadContextValue | undefined>(undefined);

export function FileUploadContextProvider({
  caption,
  mimeTypes,
  onSelect,
  onCancel,
  onInputError,
  fileList,
  disabled,
  multiple,
  inputProps,
  children,
}: PropsWithChildren<FileUploadContextValue>) {
  const value: FileUploadContextValue = useMemo(
    () => ({
      caption,
      mimeTypes,
      onSelect,
      onCancel,
      onInputError,
      fileList,
      disabled,
      multiple,
      inputProps,
    }),
    [caption, mimeTypes, onSelect, onCancel, onInputError, fileList, disabled, multiple, inputProps],
  );

  return <FileUploadContext.Provider value={value}>{children}</FileUploadContext.Provider>;
}

export function useFileUploadContext(): FileUploadContextValue {
  const value = useContext(FileUploadContext);
  if (!value) {
    throw new Error('useFileUploadContext should be used only inside FileUploadContextProvider');
  }

  return value;
}
