import * as React from 'react';
import { useId } from 'react';
import { Check } from 'lucide-react';
import { cn } from '@/lib/utils';

/**
 * CheckboxProps - Propriétés du composant Checkbox
 *
 * @interface CheckboxProps
 * @extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'>
 */
export interface CheckboxProps
  extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
  /**
   * Label à afficher à côté de la checkbox
   *
   * @example
   * ```tsx
   * <Checkbox label="J'accepte les conditions" />
   * ```
   */
  label?: string;

  /**
   * Fonction appelée lorsque l'état checked change
   * Reçoit la nouvelle valeur booléenne
   *
   * @param {boolean} checked - Nouvel état checked
   *
   * @example
   * ```tsx
   * <Checkbox onCheckedChange={(checked) => console.log(checked)} />
   * ```
   */
  onCheckedChange?: (checked: boolean) => void;
}

/**
 * Checkbox - Composant de case à cocher avec design system Kodo
 *
 * Composant de checkbox avec support pour les labels et les callbacks.
 * Utilise le design system Kodo avec une icône Check animée lors de la sélection.
 *
 * @example
 * ```tsx
 * // Checkbox simple
 * <Checkbox label="Option 1" />
 *
 * // Checkbox contrôlée
 * <Checkbox
 *   checked={isChecked}
 *   onCheckedChange={setIsChecked}
 *   label="Accepter"
 * />
 *
 * // Checkbox désactivée
 * <Checkbox label="Option" disabled />
 * ```
 *
 * @component
 * @param {CheckboxProps} props - Propriétés du composant
 * @returns {JSX.Element} Élément label contenant une checkbox stylisée
 */

export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
  ({ label, className = '', onCheckedChange, id, ...props }, ref) => {
    // CRITIQUE FIX #37: Utiliser useId() pour générer un ID stable pour l'association label/input
    const generatedId = useId();
    const checkboxId = id || generatedId;
    const labelId = `${checkboxId}-label`;

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      if (onCheckedChange) {
        onCheckedChange(e.target.checked);
      }
    };

    // CRITIQUE FIX #37: Si aucun label n'est fourni, s'assurer qu'il y a un aria-label
    // const hasAccessibleLabel = label || props['aria-label'] || props['aria-labelledby'];

    return (
      <label
        htmlFor={checkboxId}
        id={labelId}
        className={cn(
          `inline-flex items-center gap-4 cursor-pointer group`,
          props.disabled ? 'opacity-50 cursor-not-allowed' : '',
          className,
        )}
      >
        <div className="relative">
          <input
            ref={ref}
            id={checkboxId}
            type="checkbox"
            className="peer sr-only"
            onChange={handleChange}
            // CRITIQUE FIX #37: Ajouter aria-label si aucun label n'est fourni
            aria-label={
              !label && !props['aria-label'] && !props['aria-labelledby']
                ? 'Checkbox'
                : undefined
            }
            aria-labelledby={label ? labelId : undefined}
            {...props}
          />
          <div
            className="
            w-5 h-5 rounded border border-border bg-muted
            peer-checked:bg-primary peer-checked:border-border
            peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-background
            transition-all duration-[var(--duration-fast)]
          "
          ></div>
          <Check
            className="w-3.5 h-3.5 text-black absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-0 peer-checked:opacity-100 transition-opacity duration-[var(--duration-fast)] pointer-events-none"
            strokeWidth={3}
          />
        </div>
        {label && (
          <span className="text-sm text-foreground group-hover:text-foreground transition-colors duration-[var(--duration-fast)] select-none">
            {label}
          </span>
        )}
      </label>
    );
  },
);
Checkbox.displayName = 'Checkbox';
