'use client';

import * as React from 'react';

import { Input } from '@/components/ui/input';
import { cn } from '@/lib/utils';

/** Common follow-up cadences reps reach for, in days. */
const PRESETS = [1, 3, 7, 14, 30] as const;

interface ReminderDaysInputProps {
  value: number | null | undefined;
  onChange: (value: number | null) => void;
  id?: string;
  disabled?: boolean;
  /** Custom-input placeholder, defaults to "e.g. 21". */
  placeholder?: string;
  className?: string;
}

/**
 * Days-from-now reminder picker. Quick-pick chips for the four or five
 * cadences reps actually use (1 day, 3, 1 week, 2 weeks, 1 month) plus a
 * custom integer input for everything else. Clearer than a raw number field
 * and surfaces the common cases without the rep having to type.
 *
 * Storage is still a single integer (number of days), so callers can keep
 * their existing form/zod shape unchanged.
 */
export function ReminderDaysInput({
  value,
  onChange,
  id,
  disabled,
  placeholder = 'e.g. 21',
  className,
}: ReminderDaysInputProps) {
  const isPreset = typeof value === 'number' && (PRESETS as readonly number[]).includes(value);
  // Derived from the prop: a non-preset numeric value renders its string
  // form; null/preset values show empty. Local edits flow through onChange
  // and bounce back via `value` so render-phase derivation stays correct.
  const customStr = !isPreset && typeof value === 'number' ? String(value) : '';
  const [draftStr, setDraftStr] = React.useState<string>(customStr);
  // When the user is mid-typing (`draftStr` set), keep their text; otherwise
  // show the derived value. Resets when value changes externally because
  // the derived `customStr` overrides on commit.
  const shownStr = draftStr !== '' ? draftStr : customStr;

  return (
    <div className={cn('space-y-2', className)}>
      <div className="flex flex-wrap items-center gap-1.5">
        {PRESETS.map((days) => (
          <button
            key={days}
            type="button"
            disabled={disabled}
            onClick={() => onChange(days)}
            className={cn(
              'rounded-full border px-3 py-1 text-xs font-medium transition-colors',
              value === days
                ? 'border-primary bg-primary text-primary-foreground'
                : 'border-border bg-background text-foreground hover:bg-accent',
              disabled && 'cursor-not-allowed opacity-60',
            )}
            aria-pressed={value === days}
          >
            {labelFor(days)}
          </button>
        ))}
      </div>
      <Input
        id={id}
        type="number"
        inputMode="numeric"
        min={1}
        step={1}
        placeholder={placeholder}
        disabled={disabled}
        value={shownStr}
        onChange={(e) => {
          const raw = e.target.value;
          setDraftStr(raw);
          if (raw === '') {
            onChange(null);
            return;
          }
          const n = Number.parseInt(raw, 10);
          if (Number.isFinite(n) && n > 0) onChange(n);
        }}
        onBlur={() => setDraftStr('')}
      />
    </div>
  );
}

function labelFor(days: number): string {
  if (days === 1) return '1 day';
  if (days === 7) return '1 week';
  if (days === 14) return '2 weeks';
  if (days === 30) return '1 month';
  return `${days} days`;
}
