import { memo } from 'react';
import { useController } from 'react-hook-form';

import { getFieldName } from '@composed-components/dynamic-forms/utils/extraUtils';
import CardContainer, {
  type CardContainerProps,
} from '@design-system/CardContainer';
import FileCard from '@design-system/FileCard';
import { Stack } from '@mui/material';
import Typography, { type TypographyProps } from '@mui/material/Typography';
import { sizeToBytes } from '@utils/bytes';

import { type DynamicFormComponent } from '../../types';

import FormInput, { type FormInputSlotProps } from './FormInput';

type FormInputWrapperComponentProps = {
  section: string;
  component: DynamicFormComponent;
  isFrozen?: boolean;
  slotProps?: {
    root?: CardContainerProps;
    title?: TypographyProps;
    fields?: FormInputSlotProps['fields'];
  };
};

const FormInputWrapperComponent = ({
  section,
  component,
  isFrozen,
  slotProps,
}: FormInputWrapperComponentProps) => {
  const fieldName = getFieldName(section, component.nameId);
  const { fieldState } = useController({
    name: fieldName,
  });
  const inputHasError = !!fieldState.error?.message;

  const title = [
    component.content.title,
    component.content.required ? '*' : '',
  ].join(' ');

  return (
    <CardContainer
      fullWidth
      padding={24}
      {...slotProps?.root}
    >
      {/* Title */}
      <Typography
        fontWeight="fontWeightSemiBold"
        sx={{
          mb: 1,
          color: theme =>
            inputHasError
              ? theme.palette.new.text.feedback.error
              : theme.palette.new.text.neutral.default,
        }}
        {...slotProps?.title}
      >
        {title}
      </Typography>

      {/* Attachments */}
      {!!component.attachments?.length && (
        <Stack sx={{ gap: 1, mb: 2 }}>
          {component.attachments?.map(attachment => (
            <FileCard
              key={attachment.key}
              status="default"
              sx={{ width: '100%' }}
              attachment={{
                name: attachment.name,
                url: attachment.url,
                type: attachment.type || '',
                size: attachment.size || '0',
                bytes: sizeToBytes(attachment.size || '0'),
              }}
            />
          ))}
        </Stack>
      )}

      {/* FormInput is the component that renders
      the correct input based on the component type */}
      <FormInput
        name={fieldName}
        component={component}
        isFrozen={isFrozen}
        slotProps={{ fields: slotProps?.fields }}
      />
    </CardContainer>
  );
};

export const FormInputWrapper = memo(
  FormInputWrapperComponent,
  (prevProps, nextProps) => {
    return (
      prevProps.section === nextProps.section &&
      prevProps.component.nameId === nextProps.component.nameId &&
      prevProps.isFrozen === nextProps.isFrozen
    );
  },
);
