'use client';

import * as React from 'react';
import { Calendar as CalendarIcon } from 'lucide-react';
import { format } from 'date-fns';

import { Button, type ButtonProps } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import { Input } from '@/components/ui/input';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { useViewportTier } from '@/hooks/use-is-mobile';
import { cn } from '@/lib/utils';

export interface DatePickerProps {
  /** ISO-date string (YYYY-MM-DD) or empty for unset. */
  value?: string;
  onChange: (next: string) => void;
  placeholder?: string;
  /** Disable the entire control. */
  disabled?: boolean;
  /** Limit selectable range — same shape react-day-picker accepts. */
  fromDate?: Date;
  toDate?: Date;
  /** Optional className on the trigger Button (desktop) / Input (mobile). */
  className?: string;
  /** Tooltip text shown via `title` on the trigger. */
  title?: string;
  /** Trigger Button size on desktop. */
  size?: ButtonProps['size'];
  /** Optional id (forwarded to the trigger/input for `<label htmlFor>`). */
  id?: string;
  /** Forwarded `name` for native form submission paths. */
  name?: string;
  /**
   * Force a particular variant regardless of viewport. Useful in tests
   * or when a desktop popover is desired inside a mobile-only flow.
   */
  forceVariant?: 'desktop' | 'mobile';
}

function parseIso(value: string | undefined): Date | undefined {
  if (!value) return undefined;
  const [y, m, d] = value.split('-').map(Number);
  if (!y || !m || !d) return undefined;
  const parsed = new Date(y, m - 1, d);
  return Number.isNaN(parsed.getTime()) ? undefined : parsed;
}

function toIso(date: Date | undefined): string {
  if (!date) return '';
  // Local YYYY-MM-DD (no timezone shift). `toISOString` would round-trip
  // through UTC and could land on the previous day for users east of GMT.
  return format(date, 'yyyy-MM-dd');
}

/**
 * Cross-platform date picker. Desktop: shadcn Popover + Calendar
 * (caption-dropdown nav so reps can jump months/years for backfill).
 * Mobile: native `<input type="date">` for the OS-level picker —
 * touch-friendly and zero bundle cost.
 *
 * Drop-in replacement for `<Input type="date">` — same `value` /
 * `onChange` contract (YYYY-MM-DD).
 */
export function DatePicker({
  value,
  onChange,
  placeholder,
  disabled,
  fromDate,
  toDate,
  className,
  title,
  size = 'default',
  id,
  name,
  forceVariant,
}: DatePickerProps) {
  // Strict mobile only — tablet (768-1023) has room for the desktop
  // Popover Calendar; only the smallest phone widths fall back to the
  // native datepicker input.
  const tier = useViewportTier();
  const variant = forceVariant ?? (tier === 'mobile' ? 'mobile' : 'desktop');
  const [open, setOpen] = React.useState(false);
  const selected = parseIso(value);

  if (variant === 'mobile') {
    return (
      <Input
        id={id}
        name={name}
        type="date"
        value={value ?? ''}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled}
        className={className}
        title={title}
        min={fromDate ? toIso(fromDate) : undefined}
        max={toDate ? toIso(toDate) : undefined}
      />
    );
  }

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          id={id}
          variant="outline"
          size={size}
          disabled={disabled}
          title={title}
          className={cn(
            'w-full justify-start font-normal',
            !selected && 'text-muted-foreground',
            className,
          )}
        >
          <CalendarIcon aria-hidden />
          {selected ? format(selected, 'PP') : (placeholder ?? 'Pick a date')}
        </Button>
      </PopoverTrigger>
      <PopoverContent align="start" className="w-auto p-0">
        <Calendar
          mode="single"
          selected={selected}
          onSelect={(d) => {
            onChange(toIso(d));
            setOpen(false);
          }}
          captionLayout="dropdown"
          startMonth={fromDate}
          endMonth={toDate}
          autoFocus
        />
      </PopoverContent>
    </Popover>
  );
}
