import React from 'react';
import { cn } from '@/lib/utils';
import { Input as DesignSystemInput } from './input';
import { Textarea as DesignSystemTextarea } from './textarea';
import { Select as DesignSystemSelect } from './select';

/**
 * 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-kodo-text-main dark:text-kodo-text-main">
        {label}
        {required && <span className="text-kodo-red ml-1">*</span>}
      </label>
      {children}
      {helpText && !error && (
        <p className="text-xs text-muted-foreground dark:text-muted-foreground">{helpText}</p>
      )}
      {error && (
        <p className="text-xs text-kodo-red dark:text-kodo-red">{error}</p>
      )}
    </div>
  );
};

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

export const Input: React.FC<InputProps> = ({
  error = false,
  className,
  ...props
}) => {
  return (
    <DesignSystemInput
      className={cn(
        error && 'border-kodo-red focus-visible:border-kodo-red',
        className,
      )}
      {...props}
    />
  );
};

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

export const Textarea: React.FC<TextareaProps> = ({
  error = false,
  className,
  ...props
}) => {
  return (
    <DesignSystemTextarea
      className={cn(
        error && 'border-kodo-red focus-visible:border-kodo-red',
        className,
      )}
      {...props}
    />
  );
};

interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'onChange'> {
  error?: boolean;
  options: Array<{ value: string; label: string }>;
  placeholder?: string;
  onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void;
}

export const Select: React.FC<SelectProps> = ({
  error = false,
  className,
  options,
  value,
  onChange,
  placeholder,
  disabled,
  'aria-label': ariaLabel,
  'aria-labelledby': ariaLabelledBy,
}) => {
  const selectValue = value as string | undefined;
  const handleChange = (newValue: string | string[]) => {
    if (onChange) {
      const event = {
        target: { value: Array.isArray(newValue) ? newValue[0] : newValue },
      } as React.ChangeEvent<HTMLSelectElement>;
      onChange(event);
    }
  };

  return (
    <DesignSystemSelect
      options={options.map((opt) => ({ value: opt.value, label: opt.label }))}
      value={selectValue}
      onChange={handleChange}
      disabled={disabled}
      placeholder={placeholder || 'Select an option...'}
      className={cn(
        error && 'border-kodo-red',
        className,
      )}
      aria-label={ariaLabel}
      aria-labelledby={ariaLabelledBy}
    />
  );
};
