'use client';

import * as React from 'react';
import { Calendar as CalendarIcon, Clock } 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 DateTimePickerProps {
  /** datetime-local string ("YYYY-MM-DDTHH:mm") or empty for unset. */
  value?: string;
  onChange: (next: string) => void;
  placeholder?: string;
  disabled?: boolean;
  fromDate?: Date;
  toDate?: Date;
  className?: string;
  title?: string;
  size?: ButtonProps['size'];
  id?: string;
  name?: string;
  forceVariant?: 'desktop' | 'mobile';
}

function parseDateTime(value: string | undefined): { date?: Date; time: string } {
  if (!value) return { time: '' };
  // `2026-05-21T14:30` is the datetime-local shape Input emits.
  const [datePart, timePart = ''] = value.split('T');
  const date = datePart ? new Date(`${datePart}T00:00:00`) : undefined;
  if (date && Number.isNaN(date.getTime())) return { time: timePart };
  return { date, time: timePart };
}

function joinDateTime(date: Date | undefined, time: string): string {
  if (!date) return '';
  const datePart = format(date, 'yyyy-MM-dd');
  const timePart = time && /^\d{2}:\d{2}/.test(time) ? time.slice(0, 5) : '00:00';
  return `${datePart}T${timePart}`;
}

/**
 * Cross-platform datetime picker. Desktop: shadcn Popover + Calendar +
 * native time input in the footer (the shadcn-canonical pattern).
 * Mobile: native `<input type="datetime-local">` so the OS picker takes
 * over. Drop-in for `<Input type="datetime-local">`.
 */
export function DateTimePicker({
  value,
  onChange,
  placeholder,
  disabled,
  fromDate,
  toDate,
  className,
  title,
  size = 'default',
  id,
  name,
  forceVariant,
}: DateTimePickerProps) {
  // Strict mobile only - tablet has room for the desktop Popover; only
  // the smallest phone widths fall back to the native datetime-local input.
  const tier = useViewportTier();
  const variant = forceVariant ?? (tier === 'mobile' ? 'mobile' : 'desktop');
  const [open, setOpen] = React.useState(false);
  const { date, time } = parseDateTime(value);
  const displayTime = time || '09:00';

  if (variant === 'mobile') {
    return (
      <Input
        id={id}
        name={name}
        type="datetime-local"
        value={value ?? ''}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled}
        className={className}
        title={title}
      />
    );
  }

  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',
            !date && 'text-muted-foreground',
            className,
          )}
        >
          <CalendarIcon aria-hidden />
          {date ? `${format(date, 'PP')} ${displayTime}` : (placeholder ?? 'Pick a date and time')}
        </Button>
      </PopoverTrigger>
      <PopoverContent align="start" className="w-auto p-0">
        <Calendar
          mode="single"
          selected={date}
          onSelect={(d) => onChange(joinDateTime(d, displayTime))}
          captionLayout="dropdown"
          startMonth={fromDate}
          endMonth={toDate}
          autoFocus
        />
        <div className="flex items-center gap-2 border-t p-3">
          <Clock className="h-4 w-4 text-muted-foreground" aria-hidden />
          <Input
            type="time"
            value={displayTime}
            step={60}
            onChange={(e) => onChange(joinDateTime(date, e.target.value))}
            className="h-9 w-32 [&::-webkit-calendar-picker-indicator]:hidden"
          />
        </div>
      </PopoverContent>
    </Popover>
  );
}
