import React from 'react';
import { cn } from '@/lib/utils';
import FormLabel from './FormLabel';
import FormError from './FormError';
import FormInput from './FormInput';
import FormTextarea from './FormTextarea';
import FormSelect from './FormSelect';
import FormCheckbox from './FormCheckbox';
import FormRadio from './FormRadio';

/**
 * FormField Component
 * Wrapper for form fields with label, input, and error
 * Supports different input types and provides consistent form experience
 */

export type FormFieldType = 
  | 'text' 
  | 'email' 
  | 'tel' 
  | 'textarea' 
  | 'select' 
  | 'checkbox' 
  | 'radio' 
  | 'number' 
  | 'password' 
  | 'date' 
  | 'time' 
  | 'url';

export interface FormFieldProps {
  type?: FormFieldType;
  label?: string;
  name: string;
  value?: any;
  error?: string | string[];
  helpText?: string;
  required?: boolean;
  disabled?: boolean;
  placeholder?: string;
  className?: string;
  containerClassName?: string;
  
  // For select, checkbox, radio
  options?: any[];
  
  // For select
  multiple?: boolean;
  showSearch?: boolean;
  
  // For checkbox/radio
  layout?: 'vertical' | 'horizontal';
  
  // For textarea
  rows?: number;
  showCharCount?: boolean;
  autoResize?: boolean;
  maxLength?: number;
  
  // For input
  prefix?: React.ReactNode;
  suffix?: React.ReactNode;
  showClear?: boolean;
  iconPosition?: 'prefix' | 'suffix';
  
  // Callbacks
  onChange?: (value: any) => void;
  onBlur?: () => void;
  onClear?: () => void;
  
  // Additional props
  [key: string]: any;
}

export const FormField: React.FC<FormFieldProps> = ({
  type = 'text',
  label,
  name,
  value,
  error,
  helpText,
  required = false,
  disabled = false,
  placeholder,
  className,
  containerClassName,
  options = [],
  multiple = false,
  showSearch = false,
  layout = 'vertical',
  rows = 4,
  showCharCount = false,
  autoResize = false,
  maxLength,
  prefix,
  suffix,
  showClear = false,
  iconPosition = 'prefix',
  onChange,
  onBlur,
  onClear,
  ...props
}) => {
  const commonProps = {
    name,
    value,
    onChange,
    onBlur,
    disabled,
    required,
    placeholder,
    'aria-label': label,
  };

  const renderInput = () => {
    switch (type) {
      case 'textarea':
        return (
          <FormTextarea
            {...commonProps}
            error={error}
            helpText={helpText}
            rows={rows}
            showCharCount={showCharCount}
            autoResize={autoResize}
            maxLength={maxLength}
            className={className}
          />
        );

      case 'select':
        return (
          <FormSelect
            {...commonProps}
            error={error}
            helpText={helpText}
            options={options}
            multiple={multiple}
            showSearch={showSearch}
            placeholder={placeholder}
            className={className}
          />
        );

      case 'checkbox':
        return (
          <FormCheckbox
            label={label}
            error={error}
            helpText={helpText}
            required={required}
            checked={Array.isArray(value) ? value.length > 0 : !!value}
            options={options}
            value={Array.isArray(value) ? value : []}
            onChange={onChange}
            disabled={disabled}
            containerClassName={className}
          />
        );

      case 'radio':
        return (
          <FormRadio
            label={label}
            error={error}
            helpText={helpText}
            required={required}
            options={options}
            value={value}
            onChange={onChange}
            disabled={disabled}
            layout={layout}
            containerClassName={className}
          />
        );

      default:
        return (
          <FormInput
            {...commonProps}
            type={type}
            error={error}
            helpText={helpText}
            label={label}
            prefix={prefix}
            suffix={suffix}
            showClear={showClear}
            iconPosition={iconPosition}
            onClear={onClear}
            className={className}
          />
        );
    }
  };

  // For checkbox and radio, the label is handled internally
  const showExternalLabel = type !== 'checkbox' && type !== 'radio';

  return (
    <div className={cn('flex flex-col gap-1.5', containerClassName)}>
      {showExternalLabel && label && (
        <FormLabel htmlFor={name} required={required}>
          {label}
        </FormLabel>
      )}
      
      {renderInput()}
      
      {!showExternalLabel && error && (
        <FormError errors={error} />
      )}
    </div>
  );
};

FormField.displayName = 'FormField';

export default FormField;