import { forwardRef } from 'react';
import type { TextareaHTMLAttributes } from 'react';
import { cx } from '../../utils/cx';
import { useFallbackId } from '../../utils/useId';
import { Field } from '../Field/Field';
import type { FieldOwnProps } from '../Field/Field';
import './Textarea.css';

export interface TextareaProps
  extends TextareaHTMLAttributes<HTMLTextAreaElement>,
    FieldOwnProps {
  size?: 'sm' | 'md' | 'lg';
  /** Which resize handles the user gets. Defaults to vertical only. */
  resize?: 'none' | 'vertical' | 'both';
}

/** Multi-line text field. Height comes from `rows`. */
export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(
  {
    size = 'md',
    resize = 'vertical',
    label,
    hint,
    error,
    required,
    fullWidth,
    id,
    className,
    style,
    rows = 4,
    ...rest
  },
  ref,
) {
  const textareaId = useFallbackId(id);
  const messageId = `${textareaId}-message`;
  const invalid = error != null;

  return (
    <Field
      label={label}
      hint={hint}
      error={error}
      required={required}
      fullWidth={fullWidth}
      htmlFor={textareaId}
      messageId={messageId}
      className={className}
      style={style}
    >
      <textarea
        {...rest}
        ref={ref}
        id={textareaId}
        rows={rows}
        required={required}
        aria-invalid={invalid || undefined}
        aria-describedby={hint != null || invalid ? messageId : undefined}
        className={cx(
          'ds-control',
          'ds-textarea',
          `ds-textarea--${size}`,
          `ds-textarea--resize-${resize}`,
          invalid && 'ds-control--invalid',
        )}
      />
    </Field>
  );
});
