import React, {ReactNode, useCallback, useMemo} from 'react';
import {useTranslation} from 'react-i18next';
import {useNavigation} from '@react-navigation/native';
import {Stepper} from '@components';

import FormWrapperStepper from './components/FormWrapperStepper';
import {FormStep, FormValues, SubmitData, UserReviewed} from './interfaces';
import {StepContainer} from './components/FormWrapperStepper/StepContainer';
import FormWrapperScroller from './components/FormWrapperScroller';

interface Props {
  data: FormStep[];
  onSubmit?: (data: SubmitData) => void;
  StepHeaderComponent?: ReactNode;
  StepBodyComponent?: (data: FormStep) => ReactNode;
  withSteps?: boolean;
  disabled?: boolean;
  submitText?: string;
  FormHeader?: ReactNode;
  title?: string;
  /**
   * Callback to get new form values when an input has changed.
   */
  onFormChange?: (data: FormValues) => void;
  buttonIsLoading?: boolean;
  reviewedUser?: UserReviewed;
}

const AUTOMATIC_GOALS_KEY = 'automatic-goals';

// TODO: Move to `_custom` folder
function DynamicForm({
  data,
  onSubmit,
  disabled,
  StepHeaderComponent,
  StepBodyComponent,
  submitText,
  FormHeader,
  title,
  withSteps,
  buttonIsLoading,
  reviewedUser,
}: Props) {
  const {t} = useTranslation();
  const navigation = useNavigation();
  const submitTextValue = useMemo(
    () => submitText || (t('general.send') as string),
    [submitText, t],
  );

  const onGoBack = () => navigation.goBack();

  const routes = useMemo(() => {
    const filteredRoutes = [];
    const otherRoutes: FormStep[] = [];

    data.forEach(formStep => {
      if (formStep.input.type) {
        filteredRoutes.push({key: formStep.name, data: formStep});
      } else {
        otherRoutes.push(formStep);
      }
    });

    if (otherRoutes.length) {
      filteredRoutes.push({key: AUTOMATIC_GOALS_KEY, data: otherRoutes});
    }

    return filteredRoutes;
  }, [data]);

  const renderScene = useCallback(
    () => (
      <StepContainer
        StepHeaderComponent={StepHeaderComponent}
        StepBodyComponent={StepBodyComponent}
        disabled={disabled}
        reviewedUser={reviewedUser}
      />
    ),
    [StepHeaderComponent, StepBodyComponent, disabled, reviewedUser],
  );

  const steps = useMemo(() => {
    return routes.map(route => ({
      id: route.key,
      component: renderScene,
    }));
  }, [routes, renderScene]);

  const commonProps = {
    data,
    StepHeaderComponent,
    StepBodyComponent,
    disabled,
    FormHeader,
    submitText: submitTextValue,
    buttonIsLoading,
    routes,
    onSubmit,
  };

  return withSteps ? (
    <Stepper title={title} onClose={onGoBack} steps={steps}>
      <FormWrapperStepper {...commonProps} />
    </Stepper>
  ) : (
    <FormWrapperScroller {...commonProps} />
  );
}

export * from './interfaces';

export default DynamicForm;
