import { useCallback } from 'react';
import { useFormContext } from 'react-hook-form';

import HTMLBody from '@composed-components/HTMLBody';
import Alert from '@design-system/Alert';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { appearFromBottom } from '@utils/animations';

import { type DynamicFormComponent, type DynamicFormValues } from '../../types';
import { hasRequiredFieldError } from '../../utils/extraUtils';
import { FormInputWrapper } from '../FormInputs/FormInputWrapper';

import FormInputsCatalogConnected from './connected';
import { type FormInputsCatalogProps, type Section } from './types';

const FormInputsCatalog = ({
  isFrozen,
  error,
  slotProps,
  section,
  sx,
}: FormInputsCatalogProps) => {
  const { formState } = useFormContext<DynamicFormValues>();

  const showRequiredFieldError = hasRequiredFieldError(formState.errors);
  const showError = showRequiredFieldError && formState.isSubmitted && error;

  const renderItem = useCallback(
    (item: DynamicFormComponent, index: number) =>
      section && (
        <FormInputWrapper
          key={item.nameId}
          section={section.nameId}
          component={item}
          isFrozen={isFrozen}
          slotProps={{
            ...slotProps,
            root: {
              ...slotProps?.root,
              sx: {
                animation: `${appearFromBottom} 120ms ease-in-out backwards`,
                animationDelay: `${index * 30}ms`,
              },
            },
            fields: slotProps?.fields,
          }}
        />
      ),
    [isFrozen, section?.nameId],
  );

  if (!section) return null;

  return (
    <Stack
      sx={{ gap: 3, pb: 3, transition: 'opacity 120ms ease-in-out', ...sx }}
      id="form-section"
      component="form"
    >
      {section.content.title && (
        <Stack sx={{ gap: 1 }}>
          {showError && (
            <Alert
              severity="error"
              title={error}
            />
          )}
          <Typography
            variant="globalL"
            fontWeight="fontWeightSemiBold"
          >
            {section.content.title}
          </Typography>
          {section.content.description && (
            <HTMLBody body={section.content.description} />
          )}
        </Stack>
      )}
      {section.content.components?.map(renderItem)}
    </Stack>
  );
};

FormInputsCatalog.Connected = FormInputsCatalogConnected;

export type { FormInputsCatalogProps, Section };

export default FormInputsCatalog;
