import React from 'react';
import { cn } from '@/lib/utils';

/**
 * FormFieldProps - Propriétés du composant FormField
 *
 * @interface FormFieldProps
 */
interface FormFieldProps {
  /**
   * Label du champ de formulaire
   *
   * @example
   * ```tsx
   * <FormField label="Email">
   *   <Input type="email" />
   * </FormField>
   * ```
   */
  label: string;

  /**
   * Message d'erreur à afficher sous le champ
   *
   * @example
   * ```tsx
   * <FormField label="Email" error={errors.email}>
   *   <Input type="email" />
   * </FormField>
   * ```
   */
  error?: string;

  /**
   * Si `true`, affiche un indicateur requis (*)
   *
   * @default false
   */
  required?: boolean;

  /**
   * Champ de formulaire enfant (Input, Textarea, Select, etc.)
   */
  children: React.ReactNode;

  /**
   * Classes CSS personnalisées
   */
  className?: string;

  /**
   * Texte d'aide à afficher sous le champ (si pas d'erreur)
   *
   * @example
   * ```tsx
   * <FormField
   *   label="Mot de passe"
   *   helpText="Minimum 8 caractères"
   * >
   *   <Input type="password" />
   * </FormField>
   * ```
   */
  helpText?: string;
}

/**
 * FormField - Composant de champ de formulaire avec label et validation
 *
 * Composant wrapper pour les champs de formulaire avec support pour :
 * - Label avec indicateur requis
 * - Message d'erreur
 * - Texte d'aide
 *
 * @example
 * ```tsx
 * // Champ simple
 * <FormField label="Nom">
 *   <Input type="text" />
 * </FormField>
 *
 * // Champ requis avec erreur
 * <FormField
 *   label="Email"
 *   required
 *   error={errors.email}
 * >
 *   <Input type="email" />
 * </FormField>
 *
 * // Champ avec texte d'aide
 * <FormField
 *   label="Description"
 *   helpText="Maximum 500 caractères"
 * >
 *   <Textarea />
 * </FormField>
 * ```
 *
 * @component
 * @param {FormFieldProps} props - Propriétés du composant
 * @returns {JSX.Element} Élément div contenant le label, le champ et les messages
 */

export const FormField: React.FC<FormFieldProps> = ({
  label,
  error,
  required = false,
  children,
  className,
  helpText,
}) => {
  return (
    <div className={cn('space-y-2', className)}>
      <label className="text-sm font-medium text-gray-700 dark:text-gray-300">
        {label}
        {required && <span className="text-red-500 ml-1">*</span>}
      </label>
      {children}
      {helpText && !error && (
        <p className="text-xs text-gray-500 dark:text-gray-400">{helpText}</p>
      )}
      {error && (
        <p className="text-xs text-red-500 dark:text-red-400">{error}</p>
      )}
    </div>
  );
};

interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  error?: boolean;
}

export const Input: React.FC<InputProps> = ({
  error = false,
  className,
  ...props
}) => {
  return (
    <input
      className={cn(
        'w-full px-3 py-2 border rounded-md shadow-sm transition-colors',
        'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent',
        'dark:bg-gray-800 dark:border-gray-600 dark:text-white',
        error
          ? 'border-red-500 focus:ring-red-500'
          : 'border-gray-300 dark:border-gray-600',
        className,
      )}
      {...props}
    />
  );
};

interface TextareaProps
  extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
  error?: boolean;
}

export const Textarea: React.FC<TextareaProps> = ({
  error = false,
  className,
  ...props
}) => {
  return (
    <textarea
      className={cn(
        'w-full px-3 py-2 border rounded-md shadow-sm transition-colors resize-none',
        'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent',
        'dark:bg-gray-800 dark:border-gray-600 dark:text-white',
        error
          ? 'border-red-500 focus:ring-red-500'
          : 'border-gray-300 dark:border-gray-600',
        className,
      )}
      {...props}
    />
  );
};

interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
  error?: boolean;
  options: Array<{ value: string; label: string }>;
}

export const Select: React.FC<SelectProps> = ({
  error = false,
  className,
  options,
  ...props
}) => {
  return (
    <select
      className={cn(
        'w-full px-3 py-2 border rounded-md shadow-sm transition-colors',
        'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent',
        'dark:bg-gray-800 dark:border-gray-600 dark:text-white',
        error
          ? 'border-red-500 focus:ring-red-500'
          : 'border-gray-300 dark:border-gray-600',
        className,
      )}
      {...props}
    >
      {options.map((option) => (
        <option key={option.value} value={option.value}>
          {option.label}
        </option>
      ))}
    </select>
  );
};
