'use client';

import { cn } from '@/lib/utils';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';

/*
 * No hay @radix-ui/react-switch instalado (ver reporte de la tarea). Se
 * construye a mano siguiendo el patrón ARIA de "switch" del propio Radix:
 * `role="switch"`, `aria-checked`, y Enter/Espacio togglean igual que un
 * checkbox. El track y el thumb usan los mismos tokens de color y las mismas
 * transiciones que el resto de los controles, así que visualmente es
 * indistinguible de un switch de Radix.
 */

const switchTrackVariants = cva(
  'peer inline-flex h-7 w-12 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors duration-150 ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-40',
  {
    variants: {
      checked: {
        true: 'bg-primary',
        false: 'bg-muted',
      },
    },
    defaultVariants: {
      checked: false,
    },
  }
);

export interface SwitchProps
  extends Omit<
      React.ButtonHTMLAttributes<HTMLButtonElement>,
      'onChange' | 'defaultValue'
    >,
    VariantProps<typeof switchTrackVariants> {
  checked?: boolean;
  defaultChecked?: boolean;
  onCheckedChange?: (checked: boolean) => void;
}

/*
 * El hit-area del botón mide 44px de alto (min-h-11) aunque el track visible
 * mida 28px, para respetar el mínimo táctil sin agrandar el control.
 */
const Switch = React.forwardRef<HTMLButtonElement, SwitchProps>(
  (
    {
      className,
      checked,
      defaultChecked,
      onCheckedChange,
      disabled,
      onClick,
      onKeyDown,
      ...props
    },
    ref
  ) => {
    const isControlled = checked !== undefined;
    const [internalChecked, setInternalChecked] = React.useState(
      defaultChecked ?? false
    );
    const isChecked = isControlled ? checked : internalChecked;

    const toggle = () => {
      if (disabled) return;
      const next = !isChecked;
      if (!isControlled) setInternalChecked(next);
      onCheckedChange?.(next);
    };

    return (
      <button
        ref={ref}
        type="button"
        role="switch"
        aria-checked={isChecked}
        disabled={disabled}
        className={cn(
          'inline-flex min-h-11 items-center justify-center',
          className
        )}
        onClick={(event) => {
          onClick?.(event);
          if (!event.defaultPrevented) toggle();
        }}
        onKeyDown={(event) => {
          onKeyDown?.(event);
          if (event.defaultPrevented) return;
          if (event.key === 'Enter' || event.key === ' ') {
            event.preventDefault();
            toggle();
          }
        }}
        {...props}
      >
        <span
          className={switchTrackVariants({ checked: isChecked })}
        >
          <span
            className={cn(
              'block h-5 w-5 translate-x-0.5 rounded-full bg-surface shadow-sm transition-transform duration-150 ease-out',
              isChecked && 'translate-x-5'
            )}
          />
        </span>
      </button>
    );
  }
);
Switch.displayName = 'Switch';

export { Switch };
