import React, {
  ForwardedRef,
  forwardRef,
  ReactNode,
  useCallback,
  useMemo,
} from 'react';
import {FlatList, ListRenderItem, ScrollViewProps, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {KeyboardAwareScrollView} from 'react-native-keyboard-controller';
import {
  Alert,
  CardContainer,
  Typography,
  TypographyWithLinks,
} from '@components';
import {
  DynamicFormComponent,
  DynamicFormSection,
  NextSection,
  AsteriskDisclaimerProps,
} from '@shared/dynamicForms';
import {useTheme} from '@shared/theme';

import {FormDescription} from '../FormDescription';
import {FormInput} from '../FormInput';
import {styles} from './styles';

interface Props extends AsteriskDisclaimerProps {
  cover?: ReactNode;
  description?: string;
  isFirstSection: boolean;
  nextSection: NextSection | DynamicFormSection;
  richDescription?: string;
  showError: boolean;
  showFormDescription?: boolean;
  isFrozen?: boolean;
  onlyShowDisclaimerWhenRequired?: boolean;
}

const keyExtractor = (item: DynamicFormComponent) => `${item.nameId}`;

const renderScrollComponent = (props: ScrollViewProps) => (
  <KeyboardAwareScrollView {...props} keyboardShouldPersistTaps="handled" />
);

function FormSectionComponent(
  {
    cover,
    description,
    isFirstSection,
    nextSection,
    richDescription,
    showError,
    showFormDescription = true,
    showRequireAsterisk = true,
    isFrozen = false,
    onlyShowDisclaimerWhenRequired = false,
  }: Props,
  ref: ForwardedRef<FlatList>,
) {
  const {t} = useTranslation();
  const {theme} = useTheme();

  const sectionHasRequiredFields = useMemo(
    () =>
      !onlyShowDisclaimerWhenRequired ||
      nextSection.content.components.some(c => c.content.required),
    [onlyShowDisclaimerWhenRequired, nextSection.content.components],
  );

  const commonContainerStyle = useMemo(
    () => [
      styles.commonContainer,
      {backgroundColor: theme.background.layout.tertiary},
    ],
    [theme.background.layout.tertiary],
  );

  const renderItem: ListRenderItem<DynamicFormComponent> = useCallback(
    ({item}) => (
      <FormInput
        section={nextSection.nameId}
        component={item}
        showRequireAsterisk={showRequireAsterisk}
        isFrozen={isFrozen}
      />
    ),
    [isFrozen, nextSection.nameId, showRequireAsterisk],
  );

  return (
    <FlatList
      ref={ref}
      renderScrollComponent={renderScrollComponent}
      showsVerticalScrollIndicator={false}
      removeClippedSubviews={false}
      extraData={nextSection.nameId}
      ListHeaderComponent={
        <>
          {showFormDescription && isFirstSection && (
            <View style={[commonContainerStyle, styles.header]}>
              {cover}
              {!!description && (
                <CardContainer>
                  <FormDescription
                    body={description}
                    richDescription={richDescription}
                  />
                </CardContainer>
              )}
            </View>
          )}
          {nextSection.content.title && (
            <View style={[commonContainerStyle, styles.sectionHeader]}>
              {showError && (
                <Alert
                  title={t('service_management.required_questions_message')}
                  variant="error"
                />
              )}
              <Typography variant="m" weight="semiBold">
                {nextSection.content.title}
              </Typography>
              {nextSection.content.description && (
                <TypographyWithLinks
                  variant="xs"
                  color={theme.text.neutral.lighter}
                  value={nextSection.content.description}
                />
              )}
              {showRequireAsterisk && !isFrozen && sectionHasRequiredFields && (
                <Typography
                  variant="xs"
                  color={theme.text.neutral.lighter}
                  style={styles.disclaimerText}>
                  {t('service_management.required_field_disclaimer')}
                </Typography>
              )}
            </View>
          )}
        </>
      }
      data={nextSection.content.components}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      style={{backgroundColor: theme.background.layout.default}}
      contentContainerStyle={styles.flatListContent}
    />
  );
}

export const FormSection = forwardRef(FormSectionComponent);
