import React, {
  useState,
  Children,
  cloneElement,
  isValidElement,
} from 'react'
import { useWizard, UseWizardProps } from './useWizard'
import { Form as FinalForm } from 'react-final-form'
import { Step } from './components/Step'
export interface NavWizardProps extends UseWizardProps { }

export interface FormWizardProps {
  /* Callback when form is submitted */
  onSubmit(
    values: any
  ): Promise<void> | void
  /* Active page by default on render */
  activeStepIndex?: number
  /* Default values */
  initialValues?: any
  /* Error message */
  error?: string
  /* Navigation component */
  nav: React.ReactNode
  /* Wizard pages */
  children: React.ReactNode
}

export const FormWizard = ({
  children,
  onSubmit,
  activeStepIndex = 0,
  initialValues = {},
  error,
  nav
}: FormWizardProps) => {
  const [values, setValues] = useState(initialValues)
  const steps = Children.map(children, (step) => (step ? step : []))
  const {
    currentStepIndex,
    isPrevDisabled,
    isFirstStep,
    isLastStep,
    isLoading,
    handlePrev,
    handleNext
  } = useWizard(activeStepIndex, steps, onSubmit)
  // @ts-ignore
  const activeStep = steps[currentStepIndex]

  const navWithProps = Children.map(nav, (child) => {
    if (isValidElement(child)) {
      return cloneElement(child, {
        currentStepIndex,
        isPrevDisabled,
        isFirstStep,
        isLastStep,
        isLoading,
        handleNext,
        handlePrev
      })
    }

    return child
  })
  // @ts-ignore
  const validate = (values) => {
    if (isValidElement(activeStep)) {
      // @ts-ignore: Property does not exist
      return activeStep.props.validate ? activeStep.props.validate(values) : {}
    }
  }

  const handleSubmit = async (values: any) => {
    setValues(values)
    handleNext(values)
  }

  return (
    <div className="flex w-full flex-col">
      {error && (
        // TODO use Alert component
        <div className="mb-8 rounded-lg border border-negative-border bg-negative-soft-background p-4">
          <div className="flex">
            <div className="ml-3">
              <p className="text-sm font-semibold text-negative-text">
                {error}
              </p>
            </div>
          </div>
        </div>
      )}
      <FinalForm
        initialValues={values}
        validate={validate}
        onSubmit={handleSubmit}
        render={({ handleSubmit }) => (
          <form className="w-full" onSubmit={handleSubmit}>
            {activeStep}
            {nav && navWithProps}
          </form>
        )}
      ></FinalForm>
    </div>
  )
}

FormWizard.Step = Step
