import React, { useState, useEffect, useRef, useCallback } from 'react';
import { cn } from '@/lib/utils';
import FormLabel from './FormLabel';
import FormError from './FormError';

/**
 * FormTextarea Component
 * Textarea with resize options, character counter, auto-resize, and validation states
 */

export interface FormTextareaProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'maxLength'> {
  label?: string;
  error?: string | string[];
  helpText?: string;
  required?: boolean;
  showCharCount?: boolean;
  autoResize?: boolean;
  maxHeight?: number;
  minHeight?: number;
  containerClassName?: string;
  textareaClassName?: string;
  maxLength?: number;
}

export const FormTextarea: React.FC<FormTextareaProps> = ({
  label,
  error,
  helpText,
  required = false,
  showCharCount = false,
  autoResize = false,
  maxHeight = 300,
  minHeight = 120,
  containerClassName,
  textareaClassName,
  maxLength,
  disabled = false,
  value = '',
  onChange,
  rows = 4,
  ...props
}) => {
  const [isFocused, setIsFocused] = useState(false);
  const [charCount, setCharCount] = useState(0);
  const textareaRef = useRef<HTMLTextAreaElement>(null);

  const hasError = !!error;
  const showError = hasError;

  // Update character count
  useEffect(() => {
    const currentValue = typeof value === 'string' ? value : String(value || '');
    setCharCount(currentValue.length);
  }, [value]);

  // Auto-resize textarea
  useEffect(() => {
    if (!autoResize || !textareaRef.current) return;

    const textarea = textareaRef.current;
    
    // Reset height to calculate new height
    textarea.style.height = 'auto';
    
    // Calculate new height
    const newHeight = Math.min(
      Math.max(textarea.scrollHeight, minHeight),
      maxHeight
    );
    
    textarea.style.height = `${newHeight}px`;
  }, [value, autoResize, minHeight, maxHeight]);

  const handleFocus = () => setIsFocused(true);
  const handleBlur = () => setIsFocused(false);

  const handleChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
    if (maxLength && e.target.value.length > maxLength) {
      e.target.value = e.target.value.slice(0, maxLength);
    }
    onChange?.(e);
  }, [onChange, maxLength]);

  const inputId = props.id || (label ? label.toLowerCase().replace(/\s+/g, '-') : undefined);

  const baseTextareaClasses = cn(
    'w-full px-3 py-2 border rounded-md transition-all duration-200 resize-y',
    'bg-neutral-light text-text-primary',
    'placeholder:text-text-light',
    'focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary',
    'disabled:opacity-60 disabled:cursor-not-allowed',
    {
      'border-neutral-dark hover:border-neutral-dark': !hasError && !isFocused,
      'border-primary ring-2 ring-primary': isFocused && !hasError,
      'border-danger ring-2 ring-danger/20': hasError,
    },
    autoResize && 'overflow-hidden',
    textareaClassName
  );

  const containerClasses = cn(
    'flex flex-col gap-1.5',
    containerClassName
  );

  const charCountClasses = cn(
    'text-xs text-right mt-1',
    {
      'text-text-secondary': charCount <= (maxLength || 0) * 0.8,
      'text-warning': charCount > (maxLength || 0) * 0.8 && charCount <= (maxLength || 0),
      'text-danger': charCount > (maxLength || 0),
    }
  );

  const showCharCounter = showCharCount || (maxLength && charCount > 0);

  return (
    <div className={containerClasses}>
      {label && (
        <FormLabel htmlFor={inputId} required={required}>
          {label}
        </FormLabel>
      )}

      <div className="relative">
        <textarea
          ref={textareaRef}
          id={inputId}
          className={baseTextareaClasses}
          value={value}
          onChange={handleChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
          disabled={disabled}
          rows={rows}
          aria-invalid={hasError}
          aria-describedby={helpText || showError || showCharCounter ? `${inputId}-error ${inputId}-help ${inputId}-count` : undefined}
          required={required}
          maxLength={maxLength}
          style={autoResize ? { minHeight: `${minHeight}px`, overflow: 'hidden' } : {}}
          {...props}
        />
      </div>

      <div className="flex justify-between items-center gap-2">
        {helpText && (
          <p className="text-xs text-text-secondary flex-1" id={`${inputId}-help`}>
            {helpText}
          </p>
        )}
        
        {showCharCounter && (
          <p className={charCountClasses} id={`${inputId}-count`}>
            {charCount}
            {maxLength ? ` / ${maxLength}` : ''}
          </p>
        )}
      </div>

      {showError && (
        <FormError errors={error} id={`${inputId}-error`} />
      )}
    </div>
  );
};

FormTextarea.displayName = 'FormTextarea';

export default FormTextarea;