import { useState } from 'react';
import { cn } from '@/lib/cn';

/**
 * Integer input that never emits NaN. While focused it keeps a local string draft
 * so you can transiently clear or partially type a value (e.g. retype a min-bounded
 * field) without it snapping to the minimum on every keystroke. The committed value
 * is always a finite, clamped integer.
 */
export function NumberField({
  value,
  onChange,
  min,
  max,
  className,
  'aria-label': ariaLabel,
}: {
  value: number;
  onChange: (n: number) => void;
  min?: number;
  max?: number;
  className?: string;
  'aria-label'?: string;
}) {
  const [draft, setDraft] = useState<string | null>(null);
  const clamp = (n: number) => {
    let v = Math.trunc(n);
    if (min !== undefined) v = Math.max(min, v);
    if (max !== undefined) v = Math.min(max, v);
    return v;
  };
  // While focused (draft !== null) show the raw text; otherwise the controlled value.
  const display = draft !== null ? draft : Number.isFinite(value) ? String(value) : '0';
  return (
    <input
      type="number"
      inputMode="numeric"
      aria-label={ariaLabel}
      value={display}
      min={min}
      max={max}
      onFocus={(e) => setDraft(e.target.value)}
      onChange={(e) => {
        const raw = e.target.value;
        setDraft(raw);
        // Emit a clamped value live (so previews update) only when the text parses;
        // an empty/"-" intermediate leaves the committed value untouched.
        if (raw.trim() !== '' && raw !== '-') {
          const n = Number(raw);
          if (Number.isFinite(n)) onChange(clamp(n));
        }
      }}
      onBlur={(e) => {
        const raw = e.target.value;
        if (raw.trim() !== '' && raw !== '-') {
          const n = Number(raw);
          if (Number.isFinite(n)) onChange(clamp(n));
        }
        setDraft(null); // resume showing the controlled value
      }}
      onKeyDown={(e) => { if (e.key === 'Enter') (e.target as HTMLInputElement).blur(); }}
      className={cn(
        'w-full rounded-md border border-line bg-surface px-2 py-1.5 text-center text-sm text-ink',
        'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/60',
        className,
      )}
    />
  );
}
