import { Button } from '@/components/ui/button'
import { Combobox, type ComboboxOption } from '@/components/ui/combobox'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'
import {
  type CreateScheduledTaskRequest,
  type RecurrenceType,
  type TaskType,
  getRecurrenceTypeLabel,
  getTaskTypeLabel,
} from '@/lib/api/services/schedulers'
import { soundsService } from '@/lib/api/services/sounds'
import { playlistsService } from '@/lib/api/services/playlists'
import { getSupportedTimezones } from '@/utils/locale'
import { useLocale } from '@/hooks/use-locale'
import { CalendarPlus, Loader2, Music, PlayCircle } from 'lucide-react'
import { useState, useEffect } from 'react'

interface CreateTaskDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  loading: boolean
  onSubmit: (data: CreateScheduledTaskRequest) => void
  onCancel: () => void
}

const TASK_TYPES: TaskType[] = ['play_sound', 'play_playlist']
const RECURRENCE_TYPES: RecurrenceType[] = ['none', 'minutely', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'cron']

export function CreateTaskDialog({
  open,
  onOpenChange,
  loading,
  onSubmit,
  onCancel,
}: CreateTaskDialogProps) {
  const { timezone } = useLocale()
  
  const getDefaultScheduledTime = () => {
    const now = new Date()
    now.setMinutes(now.getMinutes() + 10) // Default to 10 minutes from now
    
    // Format the time in the user's timezone
    const formatter = new Intl.DateTimeFormat('en-US', {
      timeZone: timezone,
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      hour12: false,
    })
    
    const parts = formatter.formatToParts(now)
    const partsObj = parts.reduce((acc, part) => {
      acc[part.type] = part.value
      return acc
    }, {} as Record<string, string>)
    
    // Return in datetime-local format (YYYY-MM-DDTHH:MM)
    return `${partsObj.year}-${partsObj.month}-${partsObj.day}T${partsObj.hour}:${partsObj.minute}`
  }
  
  const [formData, setFormData] = useState<CreateScheduledTaskRequest>({
    name: '',
    task_type: 'play_sound',
    scheduled_at: getDefaultScheduledTime(),
    timezone: timezone,
    parameters: {},
    recurrence_type: 'none',
    cron_expression: null,
    recurrence_count: null,
    expires_at: null,
  })
  
  const [parametersJson, setParametersJson] = useState('{}')
  const [parametersError, setParametersError] = useState<string | null>(null)
  
  // Task-specific parameters
  const [selectedSoundId, setSelectedSoundId] = useState<string>('')
  const [selectedPlaylistId, setSelectedPlaylistId] = useState<string>('')
  const [playMode, setPlayMode] = useState<string>('continuous')
  const [shuffle, setShuffle] = useState<boolean>(false)
  
  // Data loading
  const [sounds, setSounds] = useState<Array<{id: number, name?: string, filename: string}>>([])
  const [playlists, setPlaylists] = useState<Array<{id: number, name: string}>>([])
  const [loadingSounds, setLoadingSounds] = useState(false)
  const [loadingPlaylists, setLoadingPlaylists] = useState(false)
  

  // Load sounds and playlists when dialog opens
  useEffect(() => {
    if (open) {
      loadSounds()
      loadPlaylists()
    }
  }, [open])

  const loadSounds = async () => {
    setLoadingSounds(true)
    try {
      const soundsData = await soundsService.getSounds({
        types: ['SDB', 'TTS']
      })
      setSounds(soundsData || [])
    } catch (error) {
      console.error('Failed to load sounds:', error)
    } finally {
      setLoadingSounds(false)
    }
  }

  const loadPlaylists = async () => {
    setLoadingPlaylists(true)
    try {
      const playlistsData = await playlistsService.getPlaylists({})
      setPlaylists(playlistsData.playlists || [])
    } catch (error) {
      console.error('Failed to load playlists:', error)
    } finally {
      setLoadingPlaylists(false)
    }
  }

  // Prepare options for comboboxes
  const soundOptions: ComboboxOption[] = sounds.map((sound) => ({
    value: sound.id.toString(),
    label: sound.name || sound.filename,
    icon: <Music className="h-4 w-4" />,
    searchValue: `${sound.id}-${sound.name || sound.filename}`
  }))

  const playlistOptions: ComboboxOption[] = playlists.map((playlist) => ({
    value: playlist.id.toString(),
    label: playlist.name,
    icon: <PlayCircle className="h-4 w-4" />,
    searchValue: `${playlist.id}-${playlist.name}`
  }))

  const timezoneOptions: ComboboxOption[] = [
    { value: 'UTC', label: 'UTC' },
    ...getSupportedTimezones().map((tz) => ({
      value: tz,
      label: tz.replace('_', ' '),
      searchValue: tz.replace('_', ' ')
    }))
  ]

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    
    // Build parameters based on task type
    let parameters: Record<string, unknown> = {}
    
    if (formData.task_type === 'play_sound') {
      if (!selectedSoundId) {
        setParametersError('Please select a sound')
        return
      }
      parameters = { sound_id: parseInt(selectedSoundId) }
    } else if (formData.task_type === 'play_playlist') {
      if (!selectedPlaylistId) {
        setParametersError('Please select a playlist')
        return
      }
      parameters = {
        playlist_id: parseInt(selectedPlaylistId),
        play_mode: playMode,
        shuffle: shuffle,
      }
    } else if (formData.task_type === 'credit_recharge') {
      // For credit recharge, use the JSON textarea for custom parameters
      try {
        parameters = JSON.parse(parametersJson)
      } catch {
        setParametersError('Invalid JSON format')
        return
      }
    }
    
    // Send the datetime as UTC to prevent backend timezone conversion
    let scheduledAt = formData.scheduled_at
    if (scheduledAt.length === 16) {
      scheduledAt += ':00' // Add seconds if missing
    }
    
    // Add Z to indicate this is already UTC time, preventing backend conversion
    const scheduledAtUTC = scheduledAt + 'Z'
    
    onSubmit({
      ...formData,
      parameters,
      scheduled_at: scheduledAtUTC,
    })
  }

  const handleParametersChange = (value: string) => {
    setParametersJson(value)
    setParametersError(null)
    
    // Try to parse JSON to validate
    try {
      JSON.parse(value)
    } catch {
      if (value.trim()) {
        setParametersError('Invalid JSON format')
      }
    }
  }

  const handleCancel = () => {
    // Reset form
    setFormData({
      name: '',
      task_type: 'play_sound',
      scheduled_at: getDefaultScheduledTime(),
      timezone: timezone,
      parameters: {},
      recurrence_type: 'none',
      cron_expression: null,
      recurrence_count: null,
      expires_at: null,
    })
    setParametersJson('{}')
    setParametersError(null)
    setSelectedSoundId('')
    setSelectedPlaylistId('')
    setPlayMode('continuous')
    setShuffle(false)
    onCancel()
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <CalendarPlus className="h-5 w-5" />
            Create Scheduled Task
          </DialogTitle>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="space-y-4">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label htmlFor="name">Task Name</Label>
              <Input
                id="name"
                value={formData.name}
                onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
                placeholder="Enter task name"
                required
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="task_type">Task Type</Label>
              <Select
                value={formData.task_type}
                onValueChange={(value: TaskType) => setFormData(prev => ({ ...prev, task_type: value }))}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {TASK_TYPES.map((type) => (
                    <SelectItem key={type} value={type}>
                      {getTaskTypeLabel(type)}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label htmlFor="scheduled_at">Scheduled At</Label>
              <Input
                id="scheduled_at"
                type="datetime-local"
                value={formData.scheduled_at}
                onChange={(e) => setFormData(prev => ({ ...prev, scheduled_at: e.target.value }))}
                required
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="timezone">Timezone</Label>
              <Combobox
                value={formData.timezone}
                onValueChange={(value) => setFormData(prev => ({ ...prev, timezone: value }))}
                options={timezoneOptions}
                placeholder="Select timezone..."
                searchPlaceholder="Search timezone..."
                emptyMessage="No timezone found."
              />
            </div>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label htmlFor="recurrence_type">Recurrence</Label>
              <Select
                value={formData.recurrence_type}
                onValueChange={(value: RecurrenceType) => setFormData(prev => ({ ...prev, recurrence_type: value }))}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {RECURRENCE_TYPES.map((type) => (
                    <SelectItem key={type} value={type}>
                      {getRecurrenceTypeLabel(type)}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            {formData.recurrence_type === 'cron' && (
              <div className="space-y-2">
                <Label htmlFor="cron_expression">Cron Expression</Label>
                <Input
                  id="cron_expression"
                  value={formData.cron_expression || ''}
                  onChange={(e) => setFormData(prev => ({ ...prev, cron_expression: e.target.value }))}
                  placeholder="0 0 * * *"
                />
              </div>
            )}

            {formData.recurrence_type !== 'none' && formData.recurrence_type !== 'cron' && (
              <div className="space-y-2">
                <Label htmlFor="recurrence_count">Max Executions</Label>
                <Input
                  id="recurrence_count"
                  type="number"
                  value={formData.recurrence_count || ''}
                  onChange={(e) => setFormData(prev => ({ 
                    ...prev, 
                    recurrence_count: e.target.value ? parseInt(e.target.value) : null 
                  }))}
                  placeholder="Leave empty for infinite"
                />
              </div>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="expires_at">Expires At (Optional)</Label>
            <Input
              id="expires_at"
              type="datetime-local"
              value={formData.expires_at || ''}
              onChange={(e) => setFormData(prev => ({ ...prev, expires_at: e.target.value || null }))}
            />
          </div>

          {/* Task-specific parameters based on task type */}
          {formData.task_type === 'play_sound' && (
            <div className="space-y-2">
              <Label htmlFor="sound">Sound to Play</Label>
              <Combobox
                value={selectedSoundId}
                onValueChange={setSelectedSoundId}
                options={soundOptions}
                placeholder="Select a sound"
                searchPlaceholder="Search sounds..."
                emptyMessage="No sound found."
                loading={loadingSounds}
                loadingMessage="Loading sounds..."
              />
              {parametersError && (
                <p className="text-sm text-destructive">{parametersError}</p>
              )}
            </div>
          )}

          {formData.task_type === 'play_playlist' && (
            <div className="space-y-4">
              <div className="space-y-2">
                <Label htmlFor="playlist">Playlist to Play</Label>
                <Combobox
                  value={selectedPlaylistId}
                  onValueChange={setSelectedPlaylistId}
                  options={playlistOptions}
                  placeholder="Select a playlist"
                  searchPlaceholder="Search playlists..."
                  emptyMessage="No playlist found."
                  loading={loadingPlaylists}
                  loadingMessage="Loading playlists..."
                />
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="playMode">Play Mode</Label>
                  <Select
                    value={playMode}
                    onValueChange={setPlayMode}
                  >
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="continuous">Continuous</SelectItem>
                      <SelectItem value="loop">Loop</SelectItem>
                      <SelectItem value="loop_one">Loop One</SelectItem>
                      <SelectItem value="random">Random</SelectItem>
                      <SelectItem value="single">Single</SelectItem>
                    </SelectContent>
                  </Select>
                </div>

                <div className="space-y-2">
                  <Label htmlFor="shuffle">Shuffle</Label>
                  <Select
                    value={shuffle.toString()}
                    onValueChange={(value) => setShuffle(value === 'true')}
                  >
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="false">No</SelectItem>
                      <SelectItem value="true">Yes</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>

              {parametersError && (
                <p className="text-sm text-destructive">{parametersError}</p>
              )}
            </div>
          )}

          {formData.task_type === 'credit_recharge' && (
            <div className="space-y-2">
              <Label htmlFor="parameters">Credit Recharge Parameters</Label>
              <Textarea
                id="parameters"
                value={parametersJson}
                onChange={(e) => handleParametersChange(e.target.value)}
                placeholder='{"user_id": 123} or {} for all users'
                className="font-mono text-sm"
                rows={3}
              />
              {parametersError && (
                <p className="text-sm text-destructive">{parametersError}</p>
              )}
              <p className="text-xs text-muted-foreground">
                Optional: specify {"user_id"} to recharge specific user, or leave empty {} to recharge all users.
              </p>
            </div>
          )}

          <div className="flex justify-end gap-2">
            <Button
              type="button"
              variant="outline"
              onClick={handleCancel}
              disabled={loading}
            >
              Cancel
            </Button>
            <Button type="submit" disabled={loading || !!parametersError}>
              {loading && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
              Create Task
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  )
}