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

/**
 * TabsProps - Propriétés du composant Tabs
 *
 * @interface TabsProps
 * @extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'>
 */
export interface TabsProps
  extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
  /**
   * Valeur contrôlée de l'onglet actif
   * Si fournie, le composant est contrôlé
   *
   * @example
   * ```tsx
   * <Tabs value={activeTab} onValueChange={setActiveTab}>
   *   ...
   * </Tabs>
   * ```
   */
  value?: string;

  /**
   * Valeur par défaut de l'onglet actif (mode non-contrôlé)
   *
   * @example
   * ```tsx
   * <Tabs defaultValue="tab1">
   *   ...
   * </Tabs>
   * ```
   */
  defaultValue?: string;

  /**
   * Fonction appelée lorsque l'onglet actif change
   *
   * @param {string} value - Valeur de l'onglet sélectionné
   *
   * @example
   * ```tsx
   * <Tabs onValueChange={(value) => console.log('Tab changed:', value)}>
   *   ...
   * </Tabs>
   * ```
   */
  onValueChange?: (value: string) => void;

  /**
   * Enfants du composant (TabsList et TabsContent)
   */
  children: React.ReactNode;
}

/**
 * Tabs - Composant d'onglets avec design system Kodo
 *
 * Composant d'onglets pour organiser le contenu en plusieurs panneaux.
 * Implémentation pure Kodo sans dépendance Radix UI.
 *
 * @example
 * ```tsx
 * // Onglets non-contrôlés
 * <Tabs defaultValue="tab1">
 *   <TabsList>
 *     <TabsTrigger value="tab1">Onglet 1</TabsTrigger>
 *     <TabsTrigger value="tab2">Onglet 2</TabsTrigger>
 *   </TabsList>
 *   <TabsContent value="tab1">Contenu 1</TabsContent>
 *   <TabsContent value="tab2">Contenu 2</TabsContent>
 * </Tabs>
 * ```
 *
 * @example
 * ```tsx
 * // Onglets contrôlés
 * const [activeTab, setActiveTab] = useState('tab1');
 *
 * <Tabs value={activeTab} onValueChange={setActiveTab}>
 *   <TabsList>
 *     <TabsTrigger value="tab1">Onglet 1</TabsTrigger>
 *     <TabsTrigger value="tab2">Onglet 2</TabsTrigger>
 *   </TabsList>
 *   <TabsContent value="tab1">Contenu 1</TabsContent>
 *   <TabsContent value="tab2">Contenu 2</TabsContent>
 * </Tabs>
 * ```
 *
 * @component
 * @param {TabsProps} props - Propriétés du composant
 * @returns {JSX.Element} Conteneur d'onglets avec gestion d'état
 */

const Tabs = React.forwardRef<HTMLDivElement, TabsProps>(
  (
    { className, value, defaultValue, onValueChange, children, ...props },
    ref,
  ) => {
    const [internalValue, setInternalValue] = React.useState(
      defaultValue || '',
    );
    const controlledValue = value !== undefined ? value : internalValue;
    const handleChange = (newValue: string) => {
      if (value === undefined) {
        setInternalValue(newValue);
      }
      onValueChange?.(newValue);
    };

    return (
      <div ref={ref} className={className} {...props}>
        {React.Children.map(children, (child) => {
          if (React.isValidElement(child)) {
            if (child.type === TabsList) {
              return React.cloneElement(child, {
                activeValue: controlledValue,
                onValueChange: handleChange,
              } as any);
            }
            if (child.type === TabsContent) {
              return React.cloneElement(child, {
                activeValue: controlledValue,
              } as any);
            }
          }
          return child;
        })}
      </div>
    );
  },
);
Tabs.displayName = 'Tabs';

/**
 * TabsListProps - Propriétés du composant TabsList
 *
 * @interface TabsListProps
 * @extends React.HTMLAttributes<HTMLDivElement>
 */
export interface TabsListProps extends React.HTMLAttributes<HTMLDivElement> {
  /**
   * Valeur de l'onglet actif (passée automatiquement par Tabs)
   * @internal
   */
  activeValue?: string;

  /**
   * Fonction appelée lors du changement d'onglet (passée automatiquement par Tabs)
   * @internal
   */
  onValueChange?: (value: string) => void;
}

/**
 * TabsList - Conteneur pour les déclencheurs d'onglets
 *
 * Conteneur horizontal pour les boutons d'onglets (TabsTrigger).
 * Doit être utilisé à l'intérieur d'un composant Tabs.
 *
 * @component
 */

const TabsList = React.forwardRef<HTMLDivElement, TabsListProps>(
  ({ className, children, activeValue, onValueChange, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={cn(
          'inline-flex h-10 items-center justify-center rounded-md bg-kodo-graphite p-1 text-gray-400 border border-kodo-steel/30',
          className,
        )}
        {...props}
      >
        {React.Children.map(children, (child) => {
          if (React.isValidElement(child) && child.type === TabsTrigger) {
            return React.cloneElement(child, {
              activeValue,
              onValueChange,
            } as any);
          }
          return child;
        })}
      </div>
    );
  },
);
TabsList.displayName = 'TabsList';

/**
 * TabsTriggerProps - Propriétés du composant TabsTrigger
 *
 * @interface TabsTriggerProps
 * @extends React.ButtonHTMLAttributes<HTMLButtonElement>
 */
export interface TabsTriggerProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  /**
   * Valeur unique de l'onglet (doit correspondre à la valeur d'un TabsContent)
   *
   * @example
   * ```tsx
   * <TabsTrigger value="tab1">Onglet 1</TabsTrigger>
   * ```
   */
  value: string;

  /**
   * Valeur de l'onglet actif (passée automatiquement par TabsList)
   * @internal
   */
  activeValue?: string;

  /**
   * Fonction appelée lors du clic (passée automatiquement par TabsList)
   * @internal
   */
  onValueChange?: (value: string) => void;
}

/**
 * TabsTrigger - Bouton déclencheur d'onglet
 *
 * Bouton cliquable pour activer un onglet spécifique.
 * Doit être utilisé à l'intérieur d'un TabsList.
 *
 * @component
 */

const TabsTrigger = React.forwardRef<HTMLButtonElement, TabsTriggerProps>(
  (
    {
      className,
      value: triggerValue,
      activeValue,
      onValueChange,
      children,
      ...props
    },
    ref,
  ) => {
    const isActive = activeValue === triggerValue;

    return (
      <button
        ref={ref}
        onClick={() => onValueChange?.(triggerValue)}
        className={cn(
          'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-bold uppercase tracking-wider',
          'ring-offset-kodo-void transition-all duration-200',
          'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-kodo-cyan focus-visible:ring-offset-2',
          'disabled:pointer-events-none disabled:opacity-50',
          isActive
            ? 'bg-kodo-cyan text-kodo-void shadow-neon-cyan'
            : 'text-gray-500 hover:text-gray-300',
          className,
        )}
        {...props}
      >
        {children}
      </button>
    );
  },
);
TabsTrigger.displayName = 'TabsTrigger';

/**
 * TabsContentProps - Propriétés du composant TabsContent
 *
 * @interface TabsContentProps
 * @extends React.HTMLAttributes<HTMLDivElement>
 */
export interface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {
  /**
   * Valeur unique du contenu (doit correspondre à la valeur d'un TabsTrigger)
   * Le contenu n'est affiché que si cette valeur correspond à l'onglet actif
   *
   * @example
   * ```tsx
   * <TabsContent value="tab1">
   *   Contenu de l'onglet 1
   * </TabsContent>
   * ```
   */
  value: string;

  /**
   * Valeur de l'onglet actif (passée automatiquement par Tabs)
   * @internal
   */
  activeValue?: string;
}

/**
 * TabsContent - Contenu d'un onglet
 *
 * Conteneur pour le contenu d'un onglet spécifique.
 * N'est rendu que lorsque sa valeur correspond à l'onglet actif.
 * Doit être utilisé à l'intérieur d'un composant Tabs.
 *
 * @component
 */

const TabsContent = React.forwardRef<HTMLDivElement, TabsContentProps>(
  (
    { className, value: contentValue, activeValue, children, ...props },
    ref,
  ) => {
    if (activeValue !== contentValue) {
      return null;
    }

    return (
      <div
        ref={ref}
        className={cn(
          'mt-2 ring-offset-kodo-void focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-kodo-cyan focus-visible:ring-offset-2',
          className,
        )}
        {...props}
      >
        {children}
      </div>
    );
  },
);
TabsContent.displayName = 'TabsContent';

export { Tabs, TabsList, TabsTrigger, TabsContent };
