import type { Config, SubmissionErrors } from 'final-form'
import isError from 'lodash/isError'
import React from 'react'
import { Form as FinalForm, FormProps, FormRenderProps } from 'react-final-form'
import {
  EditingFields,
  FormSubmitHandler,
  handleUnexpectedError,
  IFormActionProps,
} from '..'
import { FormActions } from '../FormActions'
import { FormErrorsText } from '../FormErrorsText'
import { FormContextProvider } from '../lib/FormContext'

interface IFormProps<F>
  extends Omit<FormProps<EditingFields<F>>, 'onSubmit'>,
    IFormActionProps {
  onSubmit: FormSubmitHandler<F>
}

export const Form = <F extends {}>({
  children,
  onSubmit,
                                     hideCancel,
  ...props
}: IFormProps<F>) => {
  const wrappedSubmit: Config<EditingFields<F>>['onSubmit'] = async (
    ...args
  ) => {
    try {
      await onSubmit(...args)
      return undefined
    } catch (e) {
      if (isError(e)) {
        return handleUnexpectedError(e)
      }
      return e as SubmissionErrors
    }
  }
  const render = (renderProps: FormRenderProps<EditingFields<F>>) => (
    // @ts-ignore
    <FormContextProvider {...renderProps} hideCancel={hideCancel}>
      <form onSubmit={renderProps.handleSubmit}>
        <FormErrorsText />
        {children}
        <FormActions />
      </form>
    </FormContextProvider>
  )
  return (
    <FinalForm<EditingFields<F>>
      {...props}
      onSubmit={wrappedSubmit}
      render={render}
    />
  )
}

export default Form
