'use client'

import { useState } from 'react'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '../ui/dialog'
import { Button } from '../ui/button'
import { Label } from '../ui/label'
import { Calendar } from '../ui/calendar'
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '../ui/popover'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '../ui/select'
import { Loader2, CalendarIcon, Clock } from 'lucide-react'
import { useToast } from '../toast'
import { format, addDays, setHours, setMinutes, isBefore, startOfDay } from 'date-fns'
import { cn } from '../../utils/cn'

interface SummaryItem {
  label: string
  value: string
}

interface ScheduleDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  /** Summary items displayed at the top of the dialog (e.g. subject, recipient count) */
  summaryItems: SummaryItem[]
  /** Called to schedule the message. Receives the ISO date string for the scheduled time. */
  onSchedule: (scheduledAt: string) => Promise<void>
  /** Called to save draft before scheduling when there are unsaved changes */
  onSaveDraft?: () => Promise<void>
  /** Called to prepare recipients (e.g. expand contact tags) before scheduling */
  onPrepareRecipients?: () => Promise<void>
  /** Whether there are unsaved changes that need saving before scheduling */
  hasUnsavedChanges?: boolean
  /** Dialog title. Defaults to "Schedule Send" */
  title?: string
  /** Dialog description. Defaults to "Choose when to send this email" */
  description?: string
  /** Info message shown after confirming schedule time */
  scheduledInfoMessage?: string
}

// Generate time options in 30-minute increments
const generateTimeOptions = () => {
  const options: { value: string; label: string }[] = []
  for (let hour = 0; hour < 24; hour++) {
    for (const minute of [0, 30]) {
      const h = hour.toString().padStart(2, '0')
      const m = minute.toString().padStart(2, '0')
      const period = hour < 12 ? 'AM' : 'PM'
      const displayHour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour
      options.push({
        value: `${h}:${m}`,
        label: `${displayHour}:${m.padStart(2, '0')} ${period}`,
      })
    }
  }
  return options
}

const TIME_OPTIONS = generateTimeOptions()

// Quick schedule options
const QUICK_OPTIONS = [
  { label: 'Tomorrow 9 AM', getValue: () => setHours(setMinutes(addDays(new Date(), 1), 0), 9) },
  { label: 'Tomorrow 2 PM', getValue: () => setHours(setMinutes(addDays(new Date(), 1), 0), 14) },
  { label: 'Monday 9 AM', getValue: () => {
    const today = new Date()
    const daysUntilMonday = (8 - today.getDay()) % 7 || 7
    return setHours(setMinutes(addDays(today, daysUntilMonday), 0), 9)
  }},
  { label: 'Next week', getValue: () => setHours(setMinutes(addDays(new Date(), 7), 0), 9) },
]

export function ScheduleDialog({
  open,
  onOpenChange,
  summaryItems,
  onSchedule,
  onSaveDraft,
  onPrepareRecipients,
  hasUnsavedChanges = false,
  title = 'Schedule Send',
  description = 'Choose when to send this email',
  scheduledInfoMessage = 'You can cancel or edit this scheduled send from the messages list.',
}: ScheduleDialogProps) {
  const { toast } = useToast()
  const [scheduling, setScheduling] = useState(false)
  const [selectedDate, setSelectedDate] = useState<Date | undefined>(addDays(new Date(), 1))
  const [selectedTime, setSelectedTime] = useState('09:00')

  const getScheduledDateTime = (): Date | null => {
    if (!selectedDate) return null
    const [hours, minutes] = selectedTime.split(':').map(Number)
    return setMinutes(setHours(selectedDate, hours), minutes)
  }

  const isValidScheduleTime = (): boolean => {
    const scheduledTime = getScheduledDateTime()
    if (!scheduledTime) return false
    // Must be at least 5 minutes in the future
    return scheduledTime.getTime() > Date.now() + 5 * 60 * 1000
  }

  const handleQuickSelect = (getValue: () => Date) => {
    const date = getValue()
    setSelectedDate(startOfDay(date))
    const hours = date.getHours().toString().padStart(2, '0')
    const minutes = date.getMinutes().toString().padStart(2, '0')
    setSelectedTime(`${hours}:${minutes}`)
  }

  const handleSchedule = async () => {
    const scheduledDateTime = getScheduledDateTime()
    if (!scheduledDateTime) {
      toast({ description: 'Please select a date and time', variant: 'destructive' })
      return
    }

    if (!isValidScheduleTime()) {
      toast({ description: 'Scheduled time must be at least 5 minutes in the future', variant: 'destructive' })
      return
    }

    setScheduling(true)
    try {
      // Save any pending changes first
      if (hasUnsavedChanges && onSaveDraft) {
        await onSaveDraft()
      }

      // Prepare recipients if needed
      if (onPrepareRecipients) {
        await onPrepareRecipients()
      }

      // Delegate scheduling to the caller
      await onSchedule(scheduledDateTime.toISOString())

      toast({
        description: `Scheduled for ${format(scheduledDateTime, 'PPP')} at ${format(scheduledDateTime, 'p')}`,
      })
      onOpenChange(false)
    } catch (error) {
      console.error('Error scheduling:', error)
      toast({
        description: error instanceof Error ? error.message : 'Failed to schedule',
        variant: 'destructive',
      })
    } finally {
      setScheduling(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[500px]">
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>{description}</DialogDescription>
        </DialogHeader>

        <div className="space-y-6 py-4">
          {/* Summary */}
          <div className="p-4 bg-muted rounded-lg space-y-2">
            {summaryItems.map((item) => (
              <div key={item.label} className="flex justify-between text-sm">
                <span className="text-muted-foreground">{item.label}:</span>
                <span className="font-medium truncate ml-4">{item.value}</span>
              </div>
            ))}
          </div>

          {/* Quick options */}
          <div className="space-y-2">
            <Label className="text-sm text-muted-foreground">Quick schedule</Label>
            <div className="grid grid-cols-2 gap-2">
              {QUICK_OPTIONS.map((option) => (
                <Button
                  key={option.label}
                  variant="outline"
                  size="sm"
                  onClick={() => handleQuickSelect(option.getValue)}
                  className="justify-start"
                >
                  {option.label}
                </Button>
              ))}
            </div>
          </div>

          {/* Date/Time picker */}
          <div className="space-y-4">
            <Label className="text-sm text-muted-foreground">Or pick a specific date and time</Label>

            <div className="flex gap-4">
              {/* Date picker */}
              <div className="flex-1 space-y-2">
                <Label htmlFor="date">Date</Label>
                <Popover>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      className={cn(
                        'w-full justify-start text-left font-normal',
                        !selectedDate && 'text-muted-foreground'
                      )}
                    >
                      <CalendarIcon className="mr-2 h-4 w-4" />
                      {selectedDate ? format(selectedDate, 'PPP') : 'Pick a date'}
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-auto p-0" align="start">
                    <Calendar
                      mode="single"
                      selected={selectedDate}
                      onSelect={setSelectedDate}
                      disabled={(date) => isBefore(date, startOfDay(new Date()))}
                      initialFocus
                    />
                  </PopoverContent>
                </Popover>
              </div>

              {/* Time picker */}
              <div className="w-[140px] space-y-2">
                <Label htmlFor="time">Time</Label>
                <Select value={selectedTime} onValueChange={setSelectedTime}>
                  <SelectTrigger>
                    <Clock className="mr-2 h-4 w-4" />
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent className="max-h-[300px]">
                    {TIME_OPTIONS.map((option) => (
                      <SelectItem key={option.value} value={option.value}>
                        {option.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>
          </div>

          {/* Preview scheduled time */}
          {selectedDate && isValidScheduleTime() && (
            <div className="p-3 bg-blue-50 border border-blue-200 rounded-lg text-blue-800 text-sm">
              <p>
                <strong>Scheduled for:</strong>{' '}
                {format(getScheduledDateTime()!, 'PPPP')} at {format(getScheduledDateTime()!, 'p')}
              </p>
              {scheduledInfoMessage && (
                <p className="text-xs mt-1 text-blue-600">
                  {scheduledInfoMessage}
                </p>
              )}
            </div>
          )}
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={scheduling}>
            Cancel
          </Button>
          <Button onClick={handleSchedule} disabled={scheduling || !isValidScheduleTime()}>
            {scheduling ? (
              <>
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                Scheduling...
              </>
            ) : (
              <>
                <CalendarIcon className="mr-2 h-4 w-4" />
                Schedule Send
              </>
            )}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
