import { useState, useEffect } from 'react'
import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { useQuery, useMutation } from '@tanstack/react-query'
import { globalMemberListOptions } from '@/api/members'
import { scheduleSlotListOptions, enrollmentMutations, instructorListOptions, lessonTypeListOptions } from '@/api/lessons'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { ArrowLeft, Search, X } from 'lucide-react'
import { toast } from 'sonner'
import type { MemberWithAccount } from '@/api/members'
import type { ScheduleSlot, LessonType, Instructor } from '@/types/lesson'

export const Route = createFileRoute('/_authenticated/lessons/enrollments/new')({
  validateSearch: (search: Record<string, unknown>) => ({
    memberId: (search.memberId as string) || undefined,
    accountId: (search.accountId as string) || undefined,
  }),
  component: NewEnrollmentPage,
})

const DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']

const BILLING_UNITS = [
  { value: 'day', label: 'Day(s)' },
  { value: 'week', label: 'Week(s)' },
  { value: 'month', label: 'Month(s)' },
  { value: 'quarter', label: 'Quarter(s)' },
  { value: 'year', label: 'Year(s)' },
] as const

function formatSlotLabel(slot: ScheduleSlot, instructors: Instructor[], lessonTypes: LessonType[]) {
  const instructor = instructors.find((i) => i.id === slot.instructorId)
  const lessonType = lessonTypes.find((lt) => lt.id === slot.lessonTypeId)
  const [h, m] = slot.startTime.split(':').map(Number)
  const ampm = h >= 12 ? 'PM' : 'AM'
  const hour = h % 12 || 12
  const time = `${hour}:${String(m).padStart(2, '0')} ${ampm}`
  const day = DAYS[slot.dayOfWeek]
  return `${day} ${time} — ${lessonType?.name ?? 'Unknown'} (${instructor?.displayName ?? 'Unknown'})`
}

/** Returns the preset rate for a given cycle from slot (falling back to lesson type) */
function getPresetRate(
  billingInterval: string,
  billingUnit: string,
  slot: ScheduleSlot | undefined,
  lessonType: LessonType | undefined,
): string {
  if (!slot) return ''
  const isPreset = billingInterval === '1'
  if (!isPreset) return ''
  if (billingUnit === 'week') return slot.rateWeekly ?? lessonType?.rateWeekly ?? ''
  if (billingUnit === 'month') return slot.rateMonthly ?? lessonType?.rateMonthly ?? ''
  if (billingUnit === 'quarter') return slot.rateQuarterly ?? lessonType?.rateQuarterly ?? ''
  return ''
}

function NewEnrollmentPage() {
  const navigate = useNavigate()

  const [memberSearch, setMemberSearch] = useState('')
  const [showMemberDropdown, setShowMemberDropdown] = useState(false)
  const [selectedMember, setSelectedMember] = useState<MemberWithAccount | null>(null)

  const [selectedSlotId, setSelectedSlotId] = useState('')
  const [startDate, setStartDate] = useState('')
  const [billingInterval, setBillingInterval] = useState('1')
  const [billingUnit, setBillingUnit] = useState('month')
  const [rate, setRate] = useState('')
  const [rateManual, setRateManual] = useState(false)
  const [notes, setNotes] = useState('')

  const { data: membersData } = useQuery(
    globalMemberListOptions({ page: 1, limit: 20, q: memberSearch || undefined, order: 'asc', sort: 'first_name' }),
  )

  const { data: slotsData } = useQuery(scheduleSlotListOptions({ page: 1, limit: 100, order: 'asc' }))
  const { data: instructorsData } = useQuery(instructorListOptions({ page: 1, limit: 100, order: 'asc' }))
  const { data: lessonTypesData } = useQuery(lessonTypeListOptions({ page: 1, limit: 100, order: 'asc' }))

  const slots = slotsData?.data?.filter((s) => s.isActive) ?? []
  const instructors = instructorsData?.data ?? []
  const lessonTypes = lessonTypesData?.data ?? []

  const selectedSlot = slots.find((s) => s.id === selectedSlotId)
  const selectedLessonType = lessonTypes.find((lt) => lt.id === selectedSlot?.lessonTypeId)

  // Auto-fill rate from slot/lesson-type presets when slot or cycle changes, unless user has manually edited
  useEffect(() => {
    if (rateManual) return
    const preset = getPresetRate(billingInterval, billingUnit, selectedSlot, selectedLessonType)
    setRate(preset ? String(preset) : '')
  }, [selectedSlotId, billingInterval, billingUnit, selectedSlot, selectedLessonType, rateManual])

  const mutation = useMutation({
    mutationFn: async (data: Record<string, unknown>) => {
      const enrollment = await enrollmentMutations.create(data)
      try {
        await enrollmentMutations.generateSessions(enrollment.id, 4)
      } catch {
        // non-fatal — sessions can be generated later
      }
      return enrollment
    },
    onSuccess: (enrollment) => {
      toast.success('Enrollment created')
      navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: enrollment.id }, search: { tab: 'details' } })
    },
    onError: (err) => toast.error(err.message),
  })

  function selectMember(member: MemberWithAccount) {
    setSelectedMember(member)
    setShowMemberDropdown(false)
    setMemberSearch('')
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    if (!selectedMember || !selectedSlotId || !startDate) return

    mutation.mutate({
      memberId: selectedMember.id,
      accountId: selectedMember.accountId,
      scheduleSlotId: selectedSlotId,
      instructorId: selectedSlot?.instructorId,
      startDate,
      rate: rate || undefined,
      billingInterval: billingInterval ? Number(billingInterval) : undefined,
      billingUnit: billingUnit || undefined,
      notes: notes || undefined,
    })
  }

  const members = membersData?.data ?? []

  return (
    <div className="space-y-6 max-w-2xl">
      <div className="flex items-center gap-3">
        <Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/enrollments', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'desc' as const, status: undefined, instructorId: undefined } })}>
          <ArrowLeft className="h-4 w-4" />
        </Button>
        <h1 className="text-2xl font-bold">New Enrollment</h1>
      </div>

      <form onSubmit={handleSubmit} className="space-y-6">
        {/* Student */}
        <Card>
          <CardHeader><CardTitle className="text-lg">Student</CardTitle></CardHeader>
          <CardContent>
            {!selectedMember ? (
              <div className="relative">
                <Label>Search Member</Label>
                <div className="relative mt-1">
                  <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
                  <Input
                    placeholder="Type name to search..."
                    value={memberSearch}
                    onChange={(e) => { setMemberSearch(e.target.value); setShowMemberDropdown(true) }}
                    onFocus={() => setShowMemberDropdown(true)}
                    className="pl-9"
                  />
                </div>
                {showMemberDropdown && memberSearch.length > 0 && (
                  <div className="absolute z-50 mt-1 w-full rounded-md border bg-popover shadow-lg max-h-60 overflow-auto">
                    {members.length === 0 ? (
                      <div className="p-3 text-sm text-muted-foreground">No members found</div>
                    ) : (
                      members.map((m) => (
                        <button
                          key={m.id}
                          type="button"
                          className="w-full text-left px-3 py-2 text-sm hover:bg-accent"
                          onClick={() => selectMember(m)}
                        >
                          <span className="font-medium">{m.firstName} {m.lastName}</span>
                          {m.accountName && <span className="text-muted-foreground ml-2">— {m.accountName}</span>}
                        </button>
                      ))
                    )}
                  </div>
                )}
              </div>
            ) : (
              <div className="flex items-center justify-between p-3 rounded-md border bg-muted/30">
                <div>
                  <p className="font-medium">{selectedMember.firstName} {selectedMember.lastName}</p>
                  {selectedMember.accountName && (
                    <p className="text-sm text-muted-foreground">{selectedMember.accountName}</p>
                  )}
                </div>
                <Button type="button" variant="ghost" size="sm" onClick={() => setSelectedMember(null)}>
                  <X className="h-4 w-4" />
                </Button>
              </div>
            )}
          </CardContent>
        </Card>

        {/* Schedule Slot */}
        <Card>
          <CardHeader><CardTitle className="text-lg">Schedule Slot</CardTitle></CardHeader>
          <CardContent>
            <div className="space-y-2">
              <Label>Select Slot *</Label>
              <Select value={selectedSlotId} onValueChange={(v) => { setSelectedSlotId(v); setRateManual(false) }}>
                <SelectTrigger>
                  <SelectValue placeholder="Choose a time slot..." />
                </SelectTrigger>
                <SelectContent>
                  {slots.map((slot) => (
                    <SelectItem key={slot.id} value={slot.id}>
                      {formatSlotLabel(slot, instructors, lessonTypes)}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </CardContent>
        </Card>

        {/* Terms */}
        <Card>
          <CardHeader><CardTitle className="text-lg">Terms</CardTitle></CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="startDate">Start Date *</Label>
              <Input id="startDate" type="date" value={startDate} onChange={(e) => setStartDate(e.target.value)} required className="max-w-xs" />
            </div>
            <div>
              <Label className="block mb-2">Billing Cycle</Label>
              <div className="flex items-center gap-2">
                <Input
                  type="number"
                  min={1}
                  value={billingInterval}
                  onChange={(e) => { setBillingInterval(e.target.value); setRateManual(false) }}
                  className="w-20"
                />
                <Select value={billingUnit} onValueChange={(v) => { setBillingUnit(v); setRateManual(false) }}>
                  <SelectTrigger className="w-36">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {BILLING_UNITS.map((u) => (
                      <SelectItem key={u.value} value={u.value}>{u.label}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>
            <div className="space-y-1">
              <Label htmlFor="rate">Rate</Label>
              <div className="flex items-center gap-2 max-w-xs">
                <span className="text-muted-foreground">$</span>
                <Input
                  id="rate"
                  type="number"
                  step="0.01"
                  min="0"
                  value={rate}
                  onChange={(e) => { setRate(e.target.value); setRateManual(true) }}
                  placeholder="Auto-filled from slot"
                />
              </div>
              {!rateManual && rate && (
                <p className="text-xs text-muted-foreground">Auto-filled from slot rates</p>
              )}
            </div>
            <div className="space-y-2">
              <Label htmlFor="notes">Notes</Label>
              <Textarea id="notes" value={notes} onChange={(e) => setNotes(e.target.value)} rows={2} placeholder="Internal notes..." />
            </div>
          </CardContent>
        </Card>

        <div className="flex gap-2">
          <Button type="submit" disabled={mutation.isPending || !selectedMember || !selectedSlotId || !startDate} size="lg">
            {mutation.isPending ? 'Creating...' : 'Create Enrollment'}
          </Button>
          <Button variant="secondary" type="button" size="lg" onClick={() => navigate({ to: '/lessons/enrollments', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'desc' as const, status: undefined, instructorId: undefined } })}>
            Cancel
          </Button>
        </div>
      </form>
    </div>
  )
}
