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

/**
 * FormInput Component
 * Base input component with all HTML5 input types, validation states, icons, and clear button
 */

export interface FormInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'prefix' | 'suffix'> {
  label?: string;
  error?: string | string[];
  helpText?: string;
  required?: boolean;
  prefix?: React.ReactNode;
  suffix?: React.ReactNode;
  showClear?: boolean;
  iconPosition?: 'prefix' | 'suffix';
  containerClassName?: string;
  inputClassName?: string;
  onClear?: () => void;
}

export const FormInput: React.FC<FormInputProps> = ({
  label,
  error,
  helpText,
  required = false,
  prefix,
  suffix,
  showClear = false,
  iconPosition = 'prefix',
  containerClassName,
  inputClassName,
  onClear,
  disabled = false,
  value = '',
  onChange,
  ...props
}) => {
  const [isFocused, setIsFocused] = useState(false);

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

  const handleClear = useCallback(() => {
    if (onChange) {
      const syntheticEvent = {
        target: { value: '', name: props.name, type: props.type },
        currentTarget: { value: '', name: props.name, type: props.type },
      } as React.ChangeEvent<HTMLInputElement>;
      onChange(syntheticEvent);
    }
    if (onClear) {
      onClear();
    }
  }, [onChange, onClear, props.name, props.type]);

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

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

  const baseInputClasses = cn(
    'w-full px-3 py-2 border rounded-md transition-all duration-200',
    '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,
      'pl-10': prefix && iconPosition === 'prefix',
      'pr-10': (suffix && iconPosition === 'suffix') || (showClear && value),
    },
    inputClassName
  );

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

  const iconWrapperClasses = cn(
    'absolute top-1/2 -translate-y-1/2 flex items-center pointer-events-none text-text-secondary',
    {
      'left-3': iconPosition === 'prefix',
      'right-3': iconPosition === 'suffix',
    }
  );

  const clearButtonClasses = cn(
    'absolute top-1/2 -translate-y-1/2 right-2',
    'p-1 rounded-md hover:bg-neutral-dark transition-colors',
    'text-text-secondary hover:text-text-primary',
    'focus:outline-none focus:ring-2 focus:ring-primary'
  );

  const showPrefix = prefix && iconPosition === 'prefix';
  const showSuffix = suffix && iconPosition === 'suffix';
  const showClearButton = showClear && value && !disabled;

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

      <div className="relative">
        {showPrefix && (
          <div className={iconWrapperClasses}>
            {prefix}
          </div>
        )}

        <input
          id={inputId}
          className={baseInputClasses}
          value={value}
          onChange={onChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
          disabled={disabled}
          aria-invalid={hasError}
          aria-describedby={helpText || showError ? `${inputId}-error` : undefined}
          required={required}
          {...props}
        />

        {showSuffix && (
          <div className={cn(iconWrapperClasses, 'right-3 left-auto')}>
            {suffix}
          </div>
        )}

        {showClearButton && (
          <button
            type="button"
            onClick={handleClear}
            className={clearButtonClasses}
            aria-label="Clear input"
            disabled={disabled}
          >
            <svg
              className="w-4 h-4"
              fill="currentColor"
              viewBox="0 0 20 20"
            >
              <path
                fillRule="evenodd"
                d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
                clipRule="evenodd"
              />
            </svg>
          </button>
        )}
      </div>

      {helpText && (
        <p className="text-xs text-text-secondary" id={`${inputId}-help`}>
          {helpText}
        </p>
      )}

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

FormInput.displayName = 'FormInput';

export default FormInput;