import React, {
  useCallback,
  useEffect,
  useLayoutEffect,
  useMemo,
  useState,
} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useNavigation} from '@react-navigation/native';
import {FormProvider, useForm} from 'react-hook-form';
import {BackButton, BottomModalFooter, CloseButton, Spinner} from '@components';
import {useGetDynamicFormAnswer} from '@shared/dynamicForms/hooks';
import {getFieldName, parseAnswer} from '@shared/dynamicForms/utils';

import {styles} from './styles';
import {FormSection} from '../FormSection';

interface Props {
  formAnswerId: number;
  formAnswerToken: string;
  formTag: string;
  showRequireAsterisk?: boolean;
  showFormDescription?: boolean;
}

export function AnsweredForm({
  formAnswerId,
  formAnswerToken,
  formTag,
  showRequireAsterisk = true,
  showFormDescription = true,
}: Props) {
  const {t} = useTranslation();
  const navigation = useNavigation();
  const [sectionIndex, setSectionIndex] = useState(0);
  const [isTransitioning, setIsTransitioning] = useState(false);

  const {formData, isLoadingFormData} = useGetDynamicFormAnswer({
    formAnswerId,
    formAnswerToken,
    formTag,
  });

  const currentSection = useMemo(
    () => formData?.sections[sectionIndex],
    [formData?.sections, sectionIndex],
  );
  const sectionsLength = formData?.sections.length || 0;

  const formattedValues = useMemo(
    () =>
      currentSection?.content.components.reduce(
        (components, component) =>
          component.answer !== null
            ? {
                ...components,
                [getFieldName(currentSection?.nameId, component.nameId)]:
                  parseAnswer(component),
              }
            : components,
        {},
      ),
    [currentSection],
  );

  const formMethods = useForm({
    values: formattedValues,
  });

  const isLastSection = useMemo(
    () => sectionIndex === sectionsLength - 1,
    [sectionIndex, sectionsLength],
  );

  const onNextPress = useCallback(() => {
    if (!sectionsLength) {
      return;
    }
    if (isLastSection) {
      return navigation.goBack();
    }

    setIsTransitioning(true);
    setSectionIndex(prevIndex =>
      prevIndex < sectionsLength - 1 ? prevIndex + 1 : prevIndex,
    );
  }, [sectionsLength, isLastSection, navigation]);

  const onBackPress = useCallback(() => {
    setIsTransitioning(true);
    setSectionIndex(prevIndex => (prevIndex > 0 ? prevIndex - 1 : 0));
  }, [setSectionIndex]);

  useLayoutEffect(() => {
    const headerLeft = () => <BackButton onPress={onBackPress} />;
    const headerRight = () => <CloseButton onPress={navigation.goBack} />;

    navigation.setOptions({
      headerLeft: sectionIndex === 0 ? undefined : headerLeft,
      headerRight,
      title: formData?.form.title,
    });
  }, [sectionIndex, navigation, onBackPress, formData?.form?.title]);

  useEffect(() => {
    if (isTransitioning) {
      const timeout = setTimeout(() => {
        setIsTransitioning(false);
      }, 300);

      return () => {
        clearTimeout(timeout);
      };
    }
  }, [isTransitioning]);

  return isLoadingFormData ? (
    <View style={styles.loadingContainer}>
      <Spinner />
    </View>
  ) : !formData || !currentSection ? null : (
    <FormProvider {...formMethods}>
      {isTransitioning ? (
        <View style={styles.loadingContainer}>
          <Spinner />
        </View>
      ) : (
        <FormSection
          isFirstSection={sectionIndex === 0}
          nextSection={currentSection}
          showError={false}
          showFormDescription={showFormDescription}
          showRequireAsterisk={showRequireAsterisk}
          isFrozen
        />
      )}
      <BottomModalFooter
        footer={{
          primaryButton: {
            text: isLastSection
              ? t('general.back_to_start')
              : t('general.next'),
            onPress: onNextPress,
            disabled: isTransitioning,
          },
        }}
      />
    </FormProvider>
  );
}
