import type { TextareaHTMLAttributes } from 'react';
import { forwardRef, useId, useMemo } from 'react';
import './textarea.css';

export type TextareaProps = {
  label?: string;
  error?: boolean;
  errorMessage?: string;
  helperText?: string;
  resize?: 'none' | 'both' | 'horizontal' | 'vertical';
  onValueChange?: (value: string) => void;
} & Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> & {
    onChange?: TextareaHTMLAttributes<HTMLTextAreaElement>['onChange'];
  };

export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(
  {
    label = '',
    placeholder = '',
    disabled = false,
    readOnly,
    error = false,
    errorMessage = '',
    helperText = '',
    required,
    'aria-label': ariaLabelProp,
    'aria-describedby': ariaDescribedByProp,
    rows = 4,
    cols,
    maxLength,
    minLength,
    resize = 'vertical',
    id: idProp,
    value,
    defaultValue,
    onValueChange,
    onChange,
    className,
    ...rest
  },
  ref
) {
  const uid = useId();
  const id = idProp ?? `ccl-textarea-${uid.replace(/:/g, '')}`;
  const labelId = `${id}-label`;
  const hintId = `${id}-hint`;
  const errorId = `${id}-error`;

  const describedBy = useMemo(() => {
    const ids: string[] = [];
    if (ariaDescribedByProp) ids.push(ariaDescribedByProp);
    if (helperText) ids.push(hintId);
    if (error && errorMessage) ids.push(errorId);
    return ids.length ? ids.join(' ') : undefined;
  }, [ariaDescribedByProp, helperText, hintId, error, errorMessage, errorId]);

  return (
    <div className="ccl-textarea-wrapper">
      {label ? (
        <label htmlFor={id} id={labelId} className="ccl-textarea__label">
          {label}
          {required ? (
            <span className="ccl-textarea__required" aria-label="required">
              *
            </span>
          ) : null}
        </label>
      ) : null}

      <textarea
        ref={ref}
        id={id}
        className={['ccl-textarea', className].filter(Boolean).join(' ')}
        placeholder={placeholder}
        disabled={disabled}
        readOnly={readOnly}
        required={required}
        rows={rows}
        cols={cols}
        maxLength={maxLength}
        minLength={minLength}
        aria-invalid={error}
        aria-label={ariaLabelProp}
        aria-describedby={describedBy}
        aria-required={required}
        style={{ resize }}
        value={value}
        defaultValue={defaultValue}
        onChange={(e) => {
          onChange?.(e);
          onValueChange?.(e.target.value);
        }}
        {...rest}
      />

      {helperText ? (
        <span id={hintId} className="ccl-textarea__helper">
          {helperText}
        </span>
      ) : null}

      {error && errorMessage ? (
        <span id={errorId} className="ccl-textarea__error" role="alert">
          {errorMessage}
        </span>
      ) : null}
    </div>
  );
});
