import { forwardRef } from 'react';

import { FormField } from '../../form/FormField/FormField';
import { TextArea, TextAreaProps } from '../../form/TextArea/TextArea';
import { assertEmptyObject } from '../../utils/assertEmptyObject';
import { makeTestId } from '../../utils/makeTestId';
import { CommonFormikProps } from '../common/types';
import { useFormikFieldsProps } from '../hooks/useFormikFieldsProps';

export interface FormikTextAreaProps extends CommonFormikProps<string>, Omit<TextAreaProps, 'id'> {}

export const FormikTextArea = forwardRef<HTMLTextAreaElement, FormikTextAreaProps>(function FormikTextArea(
  props,
  ref,
) {
  const { id, formFieldProps, controlProps } = useFormikFieldsProps<TextAreaProps>(props);

  const {
    className,
    label,
    requirement,
    hintText,
    onHintClick,
    errorMessageId,
    error,
    descriptionMessageId,
    description,
    testId,
    ...restFormFieldProps
  } = formFieldProps;
  assertEmptyObject(restFormFieldProps);

  const {
    value,
    onChange,
    onBlur,
    leftSlot,
    rightSlot,
    placeholder,
    required,
    disabled,
    topSlot,
    bottomSlot,
    maxRows,
    minRows,
    ariaInvalid,
    ariaLabel,
    ariaErrorMessage,
    ariaDescribedBy,
    ariaRequired,
    ...restControlProps
  } = controlProps;
  assertEmptyObject(restControlProps);

  return (
    <FormField
      className={className}
      description={description}
      descriptionMessageId={descriptionMessageId}
      error={error}
      errorMessageId={errorMessageId}
      hintText={hintText}
      id={id}
      label={label}
      onHintClick={onHintClick}
      requirement={requirement}
      testId={testId}
    >
      <TextArea
        ref={ref}
        ariaDescribedBy={ariaDescribedBy}
        ariaErrorMessage={ariaErrorMessage}
        ariaInvalid={ariaInvalid}
        ariaLabel={ariaLabel}
        ariaRequired={ariaRequired}
        bottomSlot={bottomSlot}
        disabled={disabled}
        id={id}
        leftSlot={leftSlot}
        maxRows={maxRows}
        minRows={minRows}
        onBlur={onBlur}
        onChange={onChange}
        placeholder={placeholder}
        required={required}
        rightSlot={rightSlot}
        testId={makeTestId(testId, 'text-area')}
        topSlot={topSlot}
        value={value}
      />
    </FormField>
  );
});
