// @design-system: primitives/QuantityStepper
// Registered at /design-system#quantitystepper-primitive

'use client';

import { useCallback } from 'react';
import { cn } from '@/lib/cn';
import { Icon } from '@/components/ui/icons/Icon';
import { useT } from '@/lib/i18n/react';

/** Props for the QuantityStepper component */
export interface QuantityStepperProps {
  /** Current value (controlled). */
  value: number;
  /** Minimum allowed value. @default 0 */
  min?: number;
  /** Maximum allowed value. */
  max?: number;
  /** Called when value changes. */
  onChange: (value: number) => void;
  /** Accessible label for the group (e.g. deal title for screen readers). */
  label: string;
  /** When true, disables all interactions. */
  disabled?: boolean;
  /** Additional class names. */
  className?: string;
}

/**
 * QuantityStepper — discrete +/- stepper for cart quantity control.
 *
 * Distinct from NumberInput: no text input, display-only count between two buttons.
 * Supports keyboard ArrowUp/ArrowDown on the count display, disables at bounds.
 *
 * @example
 * ```tsx
 * <QuantityStepper
 *   value={qty}
 *   min={1}
 *   max={deal.maxPerUser}
 *   onChange={setQty}
 *   label={deal.title}
 * />
 * ```
 */
export function QuantityStepper({
  value,
  min = 0,
  max,
  onChange,
  label,
  disabled = false,
  className,
}: QuantityStepperProps) {
  const t = useT('cart');

  const decrement = useCallback(() => {
    if (disabled) return;
    const next = value - 1;
    if (min !== undefined && next < min) return;
    onChange(next);
  }, [disabled, value, min, onChange]);

  const increment = useCallback(() => {
    if (disabled) return;
    const next = value + 1;
    if (max !== undefined && next > max) return;
    onChange(next);
  }, [disabled, value, max, onChange]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLSpanElement>) => {
      if (e.key === 'ArrowUp') {
        e.preventDefault();
        increment();
      } else if (e.key === 'ArrowDown') {
        e.preventDefault();
        decrement();
      }
    },
    [increment, decrement],
  );

  const atMin = min !== undefined && value <= min;
  const atMax = max !== undefined && value >= max;

  return (
    <div
      role="group"
      aria-label={label}
      className={cn('inline-flex items-center gap-1', className)}
    >
      <button
        type="button"
        aria-label={t('qty_decrease')}
        onClick={decrement}
        disabled={disabled || atMin}
        className={cn(
          'flex h-11 w-11 shrink-0 items-center justify-center',
          'border-border-default bg-surface-base rounded-md border',
          'text-text-secondary',
          'hover:bg-surface-hover hover:text-text-primary',
          'active:bg-surface-subtle',
          'disabled:cursor-not-allowed disabled:opacity-50',
          'focus-visible:ring-brand-primary-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1',
          'duration-fast transition-colors',
          '@media (prefers-reduced-motion: reduce) { transition: none }',
        )}
      >
        <Icon name="Minus" size="sm" aria-hidden />
      </button>

      {/* Display-only count, keyboard navigable */}
      <span
        role="spinbutton"
        aria-valuenow={value}
        aria-valuemin={min}
        aria-valuemax={max}
        aria-label={t('qty')}
        tabIndex={disabled ? -1 : 0}
        onKeyDown={handleKeyDown}
        className={cn(
          'text-text-primary min-w-8 select-none text-center text-sm font-medium',
          'focus-visible:ring-brand-primary-500 focus-visible:rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1',
          disabled && 'opacity-50',
        )}
      >
        {value}
      </span>

      <button
        type="button"
        aria-label={t('qty_increase')}
        onClick={increment}
        disabled={disabled || atMax}
        className={cn(
          'flex h-11 w-11 shrink-0 items-center justify-center',
          'border-border-default bg-surface-base rounded-md border',
          'text-text-secondary',
          'hover:bg-surface-hover hover:text-text-primary',
          'active:bg-surface-subtle',
          'disabled:cursor-not-allowed disabled:opacity-50',
          'focus-visible:ring-brand-primary-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1',
          'duration-fast transition-colors',
        )}
      >
        <Icon name="Plus" size="sm" aria-hidden />
      </button>
    </div>
  );
}
