'use client'

import * as React from 'react'
import { format, setHours, setMinutes } from 'date-fns'
import { CalendarIcon, Clock } from 'lucide-react'

import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { Calendar } from '@/components/ui/calendar'
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'

interface DateTimePickerProps {
  value?: Date | null
  onChange?: (date: Date | null) => void
  placeholder?: string
  disabled?: boolean
  className?: string
  /** If true, only shows date picker without time */
  dateOnly?: boolean
  /** If true, allows clearing the value */
  clearable?: boolean
}

// Generate hour options (00-23)
const hours = Array.from({ length: 24 }, (_, i) => i)

// Generate minute options (00, 15, 30, 45) for easier selection
const minutes = [0, 15, 30, 45]

export function DateTimePicker({
  value,
  onChange,
  placeholder = 'Select date and time',
  disabled = false,
  className,
  dateOnly = false,
  clearable = true,
}: DateTimePickerProps) {
  const [open, setOpen] = React.useState(false)
  const [selectedDate, setSelectedDate] = React.useState<Date | undefined>(
    value ?? undefined
  )

  // Sync internal state with external value
  React.useEffect(() => {
    setSelectedDate(value ?? undefined)
  }, [value])

  const handleDateSelect = (date: Date | undefined) => {
    if (!date) {
      setSelectedDate(undefined)
      onChange?.(null)
      return
    }

    // Preserve time from previous selection or use noon as default
    const newDate = selectedDate
      ? setHours(setMinutes(date, selectedDate.getMinutes()), selectedDate.getHours())
      : setHours(setMinutes(date, 0), 12) // Default to noon

    setSelectedDate(newDate)
    onChange?.(newDate)
  }

  const handleTimeChange = (type: 'hour' | 'minute', valueStr: string) => {
    if (!selectedDate) return

    const numValue = parseInt(valueStr, 10)
    let newDate: Date

    if (type === 'hour') {
      newDate = setHours(selectedDate, numValue)
    } else {
      newDate = setMinutes(selectedDate, numValue)
    }

    setSelectedDate(newDate)
    onChange?.(newDate)
  }

  const handleClear = (e: React.MouseEvent) => {
    e.stopPropagation()
    setSelectedDate(undefined)
    onChange?.(null)
  }

  const formatDisplayDate = (date: Date) => {
    if (dateOnly) {
      return format(date, 'MMM d, yyyy')
    }
    return format(date, 'MMM d, yyyy HH:mm')
  }

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          disabled={disabled}
          className={cn(
            'w-full justify-start text-left font-normal',
            !selectedDate && 'text-muted-foreground',
            className
          )}
        >
          <CalendarIcon className="mr-2 h-4 w-4" />
          {selectedDate ? formatDisplayDate(selectedDate) : placeholder}
          {clearable && selectedDate && (
            <span
              role="button"
              tabIndex={0}
              className="ml-auto text-muted-foreground hover:text-foreground"
              onClick={handleClear}
              onKeyDown={(e) => e.key === 'Enter' && handleClear(e as unknown as React.MouseEvent)}
            >
              ×
            </span>
          )}
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-auto p-0" align="start">
        <div className="flex flex-col">
          <Calendar
            mode="single"
            selected={selectedDate}
            onSelect={handleDateSelect}
            initialFocus
          />

          {!dateOnly && (
            <div className="border-t p-3">
              <div className="flex items-center gap-2">
                <Clock className="h-4 w-4 text-muted-foreground" />
                <span className="text-sm text-muted-foreground">Time:</span>
                <Select
                  value={selectedDate ? String(selectedDate.getHours()) : undefined}
                  onValueChange={(v) => handleTimeChange('hour', v)}
                  disabled={!selectedDate}
                >
                  <SelectTrigger className="w-[70px]">
                    <SelectValue placeholder="HH" />
                  </SelectTrigger>
                  <SelectContent>
                    {hours.map((hour) => (
                      <SelectItem key={hour} value={String(hour)}>
                        {String(hour).padStart(2, '0')}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <span className="text-muted-foreground">:</span>
                <Select
                  value={selectedDate ? String(selectedDate.getMinutes()) : undefined}
                  onValueChange={(v) => handleTimeChange('minute', v)}
                  disabled={!selectedDate}
                >
                  <SelectTrigger className="w-[70px]">
                    <SelectValue placeholder="MM" />
                  </SelectTrigger>
                  <SelectContent>
                    {minutes.map((minute) => (
                      <SelectItem key={minute} value={String(minute)}>
                        {String(minute).padStart(2, '0')}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              {selectedDate && (
                <p className="mt-2 text-xs text-muted-foreground">
                  Selected: {format(selectedDate, 'EEEE, MMMM d, yyyy')} at{' '}
                  {format(selectedDate, 'HH:mm')}
                </p>
              )}
            </div>
          )}
        </div>
      </PopoverContent>
    </Popover>
  )
}
