import { useState } from 'react'
import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  enrollmentDetailOptions, enrollmentMutations, enrollmentKeys,
  sessionListOptions,
  lessonPlanListOptions, lessonPlanMutations, lessonPlanKeys,
  lessonPlanTemplateListOptions, lessonPlanTemplateMutations,
  instructorDetailOptions,
  scheduleSlotListOptions,
  lessonTypeListOptions,
} from '@/api/lessons'
import { DataTable, type Column } from '@/components/shared/data-table'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
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 { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { ArrowLeft, RefreshCw } from 'lucide-react'
import { toast } from 'sonner'
import { useAuthStore } from '@/stores/auth.store'
import type { Enrollment, LessonSession, LessonPlan, LessonPlanTemplate } from '@/types/lesson'

export const Route = createFileRoute('/_authenticated/lessons/enrollments/$enrollmentId')({
  validateSearch: (search: Record<string, unknown>) => ({
    tab: (search.tab as string) || 'details',
  }),
  component: EnrollmentDetailPage,
})

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

function formatTime(t: string) {
  const [h, m] = t.split(':').map(Number)
  const ampm = h >= 12 ? 'PM' : 'AM'
  const hour = h % 12 || 12
  return `${hour}:${String(m).padStart(2, '0')} ${ampm}`
}

function statusBadge(status: string) {
  const variants: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {
    active: 'default', paused: 'secondary', cancelled: 'destructive', completed: 'outline',
  }
  return <Badge variant={variants[status] ?? 'outline'}>{status}</Badge>
}

function sessionStatusBadge(status: string) {
  const variants: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {
    scheduled: 'outline', attended: 'default', missed: 'destructive', makeup: 'secondary', cancelled: 'secondary',
  }
  return <Badge variant={variants[status] ?? 'outline'}>{status}</Badge>
}

const sessionColumns: Column<LessonSession>[] = [
  { key: 'scheduled_date', header: 'Date', sortable: true, render: (s) => <>{new Date(s.scheduledDate + 'T00:00:00').toLocaleDateString()}</> },
  { key: 'scheduled_time', header: 'Time', render: (s) => <>{formatTime(s.scheduledTime)}</> },
  { key: 'status', header: 'Status', sortable: true, render: (s) => sessionStatusBadge(s.status) },
  {
    key: 'substitute', header: 'Sub', render: (s) => s.substituteInstructorId
      ? <Badge variant="outline" className="text-xs">Sub</Badge>
      : null,
  },
  { key: 'notes', header: 'Notes', render: (s) => s.notesCompletedAt ? <Badge variant="outline" className="text-xs">Notes</Badge> : null },
]

const TABS = [
  { key: 'details', label: 'Details' },
  { key: 'sessions', label: 'Sessions' },
  { key: 'plan', label: 'Lesson Plan' },
]

function EnrollmentDetailPage() {
  const { enrollmentId } = Route.useParams()
  const search = Route.useSearch()
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const hasPermission = useAuthStore((s) => s.hasPermission)
  const canEdit = hasPermission('lessons.edit')
  const tab = search.tab

  function setTab(t: string) {
    navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId }, search: { tab: t } })
  }

  const { data: enrollment, isLoading } = useQuery(enrollmentDetailOptions(enrollmentId))

  const updateMutation = useMutation({
    mutationFn: (data: Record<string, unknown>) => enrollmentMutations.update(enrollmentId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: enrollmentKeys.detail(enrollmentId) })
      toast.success('Enrollment updated')
    },
    onError: (err) => toast.error(err.message),
  })

  const statusMutation = useMutation({
    mutationFn: (status: string) => enrollmentMutations.updateStatus(enrollmentId, status),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: enrollmentKeys.detail(enrollmentId) })
      toast.success('Status updated')
    },
    onError: (err) => toast.error(err.message),
  })

  const generateMutation = useMutation({
    mutationFn: () => enrollmentMutations.generateSessions(enrollmentId, 4),
    onSuccess: (res) => {
      queryClient.invalidateQueries({ queryKey: ['lesson-sessions'] })
      toast.success(`Generated ${res.generated} sessions`)
    },
    onError: (err) => toast.error(err.message),
  })

  const { data: instructorData } = useQuery({
    ...instructorDetailOptions(enrollment?.instructorId ?? ''),
    enabled: !!enrollment?.instructorId,
  })

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

  if (isLoading) return <div className="text-sm text-muted-foreground">Loading...</div>
  if (!enrollment) return <div className="text-sm text-destructive">Enrollment not found.</div>

  const slot = slotsData?.data?.find((s) => s.id === enrollment.scheduleSlotId)
  const lessonType = lessonTypesData?.data?.find((lt) => lt.id === slot?.lessonTypeId)
  const slotLabel = slot ? `${DAYS[slot.dayOfWeek]} ${formatTime(slot.startTime)}${slot.room ? ` — ${slot.room}` : ''}` : '—'

  return (
    <div className="space-y-6">
      <div className="flex items-center gap-4">
        <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 mr-1" />Back
        </Button>
        <div className="flex-1">
          <h1 className="text-2xl font-bold">Enrollment</h1>
          <p className="text-sm text-muted-foreground">{instructorData?.displayName ?? enrollment.instructorId} · {slotLabel}</p>
        </div>
        {statusBadge(enrollment.status)}
      </div>

      <div className="flex gap-1 border-b">
        {TABS.map((t) => (
          <button
            key={t.key}
            onClick={() => setTab(t.key)}
            className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
              tab === t.key ? 'border-primary text-primary' : 'border-transparent text-muted-foreground hover:text-foreground'
            }`}
          >
            {t.label}
          </button>
        ))}
      </div>

      {tab === 'details' && (
        <DetailsTab
          enrollment={enrollment}
          slotLabel={slotLabel}
          lessonTypeName={lessonType?.name}
          instructorName={instructorData?.displayName}
          canEdit={canEdit}
          onSave={updateMutation.mutate}
          saving={updateMutation.isPending}
          onStatusChange={statusMutation.mutate}
          statusChanging={statusMutation.isPending}
        />
      )}
      {tab === 'sessions' && (
        <SessionsTab
          enrollmentId={enrollmentId}
          onGenerate={generateMutation.mutate}
          generating={generateMutation.isPending}
        />
      )}
      {tab === 'plan' && <LessonPlanTab enrollmentId={enrollmentId} memberId={enrollment.memberId} canEdit={canEdit} />}
    </div>
  )
}

// ─── Details Tab ──────────────────────────────────────────────────────────────

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)' },
]

function DetailsTab({
  enrollment, slotLabel, lessonTypeName, instructorName,
  canEdit, onSave, saving, onStatusChange, statusChanging,
}: {
  enrollment: Enrollment
  slotLabel: string
  lessonTypeName: string | undefined
  instructorName: string | undefined
  canEdit: boolean
  onSave: (data: Record<string, unknown>) => void
  saving: boolean
  onStatusChange: (status: string) => void
  statusChanging: boolean
}) {
  const [rate, setRate] = useState(enrollment.rate ?? '')
  const [billingInterval, setBillingInterval] = useState(String(enrollment.billingInterval ?? 1))
  const [billingUnit, setBillingUnit] = useState(enrollment.billingUnit ?? 'month')
  const [notes, setNotes] = useState(enrollment.notes ?? '')
  const [endDate, setEndDate] = useState(enrollment.endDate ?? '')

  const NEXT_STATUSES: Record<string, string[]> = {
    active: ['paused', 'cancelled', 'completed'],
    paused: ['active', 'cancelled'],
    cancelled: [],
    completed: [],
  }

  const nextStatuses = NEXT_STATUSES[enrollment.status] ?? []

  return (
    <div className="space-y-6 max-w-lg">
      <div className="grid grid-cols-2 gap-4 text-sm">
        <div>
          <p className="text-muted-foreground">Instructor</p>
          <p className="font-medium">{instructorName ?? enrollment.instructorId}</p>
        </div>
        <div>
          <p className="text-muted-foreground">Slot</p>
          <p className="font-medium">{slotLabel}</p>
        </div>
        <div>
          <p className="text-muted-foreground">Lesson Type</p>
          <p className="font-medium">{lessonTypeName ?? '—'}</p>
        </div>
        <div>
          <p className="text-muted-foreground">Start Date</p>
          <p className="font-medium">{new Date(enrollment.startDate + 'T00:00:00').toLocaleDateString()}</p>
        </div>
        <div>
          <p className="text-muted-foreground">Billing Cycle</p>
          <p className="font-medium">{enrollment.billingInterval ? `${enrollment.billingInterval} ${enrollment.billingUnit}(s)` : '—'}</p>
        </div>
        <div>
          <p className="text-muted-foreground">Rate</p>
          <p className="font-medium">{enrollment.rate ? `$${enrollment.rate}` : '—'}</p>
        </div>
        <div>
          <p className="text-muted-foreground">Makeup Credits</p>
          <p className="font-medium">{enrollment.makeupCredits}</p>
        </div>
      </div>

      {canEdit && (
        <>
          <div className="space-y-4">
            <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)}
                  className="w-20"
                />
                <Select value={billingUnit} onValueChange={(v) => setBillingUnit(v as typeof billingUnit)}>
                  <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="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label>Rate</Label>
                <div className="flex items-center gap-1">
                  <span className="text-muted-foreground">$</span>
                  <Input type="number" step="0.01" value={rate} onChange={(e) => setRate(e.target.value)} placeholder="Optional" />
                </div>
              </div>
              <div className="space-y-2">
                <Label>End Date</Label>
                <Input type="date" value={endDate} onChange={(e) => setEndDate(e.target.value)} />
              </div>
            </div>
            <div className="space-y-2">
              <Label>Notes</Label>
              <Textarea value={notes} onChange={(e) => setNotes(e.target.value)} rows={2} />
            </div>
            <Button onClick={() => onSave({
              rate: rate || undefined,
              billingInterval: billingInterval ? Number(billingInterval) : undefined,
              billingUnit: billingUnit || undefined,
              notes: notes || undefined,
              endDate: endDate || undefined,
            })} disabled={saving}>
              {saving ? 'Saving...' : 'Save Changes'}
            </Button>
          </div>

          {nextStatuses.length > 0 && (
            <div className="border-t pt-4 space-y-2">
              <p className="text-sm font-medium">Change Status</p>
              <div className="flex gap-2">
                {nextStatuses.map((s) => (
                  <Button key={s} variant={s === 'cancelled' ? 'destructive' : 'outline'} size="sm" onClick={() => onStatusChange(s)} disabled={statusChanging}>
                    {s.charAt(0).toUpperCase() + s.slice(1)}
                  </Button>
                ))}
              </div>
            </div>
          )}
        </>
      )}
    </div>
  )
}

// ─── Sessions Tab ─────────────────────────────────────────────────────────────

function SessionsTab({ enrollmentId, onGenerate, generating }: { enrollmentId: string; onGenerate: () => void; generating: boolean }) {
  const navigate = useNavigate()
  const { data, isLoading } = useQuery(sessionListOptions({ enrollmentId, page: 1, limit: 100, sort: 'scheduled_date', order: 'asc' }))

  return (
    <div className="space-y-4">
      <div className="flex justify-end">
        <Button variant="outline" size="sm" onClick={onGenerate} disabled={generating}>
          <RefreshCw className={`h-4 w-4 mr-2 ${generating ? 'animate-spin' : ''}`} />
          Generate Sessions
        </Button>
      </div>
      <DataTable
        columns={sessionColumns}
        data={data?.data ?? []}
        loading={isLoading}
        page={1}
        totalPages={1}
        total={data?.data?.length ?? 0}
        onPageChange={() => {}}
        onSort={() => {}}
        onRowClick={(s) => navigate({ to: '/lessons/sessions/$sessionId', params: { sessionId: s.id }, search: {} })}
      />
    </div>
  )
}

// ─── Lesson Plan Tab ──────────────────────────────────────────────────────────

function LessonPlanTab({ enrollmentId, memberId, canEdit }: { enrollmentId: string; memberId: string; canEdit: boolean }) {
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const [templatePickerOpen, setTemplatePickerOpen] = useState(false)
  const [selectedTemplateId, setSelectedTemplateId] = useState('')
  const [customTitle, setCustomTitle] = useState('')

  const { data: plansData } = useQuery(lessonPlanListOptions({ enrollmentId, isActive: true }))
  const activePlan: LessonPlan | undefined = plansData?.data?.[0]

  const { data: templatesData } = useQuery(lessonPlanTemplateListOptions({ page: 1, limit: 100, order: 'asc' }))

  const createPlanMutation = useMutation({
    mutationFn: () => lessonPlanMutations.create({ memberId, enrollmentId, title: `Lesson Plan — ${new Date().toLocaleDateString()}` }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: lessonPlanKeys.all })
      toast.success('Lesson plan created')
    },
    onError: (err) => toast.error(err.message),
  })

  const instantiateMutation = useMutation({
    mutationFn: () => lessonPlanTemplateMutations.createPlan(selectedTemplateId, {
      memberId,
      enrollmentId,
      title: customTitle || undefined,
    }),
    onSuccess: (plan) => {
      queryClient.invalidateQueries({ queryKey: lessonPlanKeys.all })
      toast.success('Plan created from template')
      setTemplatePickerOpen(false)
      navigate({ to: '/lessons/plans/$planId', params: { planId: plan.id }, search: {} })
    },
    onError: (err) => toast.error(err.message),
  })

  const templates: LessonPlanTemplate[] = templatesData?.data ?? []

  return (
    <div className="space-y-4">
      {activePlan ? (
        <div className="space-y-3">
          <div className="flex items-center justify-between">
            <div>
              <p className="font-medium">{activePlan.title}</p>
              <p className="text-sm text-muted-foreground">
                {Math.round(activePlan.progress)}% complete
              </p>
            </div>
            <Button variant="outline" size="sm" onClick={() => navigate({ to: '/lessons/plans/$planId', params: { planId: activePlan.id }, search: {} })}>
              View Plan
            </Button>
          </div>
          <div className="w-full bg-muted rounded-full h-2">
            <div className="bg-primary h-2 rounded-full transition-all" style={{ width: `${activePlan.progress}%` }} />
          </div>
        </div>
      ) : (
        <div className="text-sm text-muted-foreground py-4">No active lesson plan.</div>
      )}

      {canEdit && (
        <div className="flex gap-2 pt-2 border-t">
          <Button variant="outline" size="sm" onClick={() => createPlanMutation.mutate()} disabled={createPlanMutation.isPending}>
            {createPlanMutation.isPending ? 'Creating...' : 'New Blank Plan'}
          </Button>
          <Button variant="outline" size="sm" onClick={() => setTemplatePickerOpen(true)}>
            Use Template
          </Button>
        </div>
      )}

      <Dialog open={templatePickerOpen} onOpenChange={setTemplatePickerOpen}>
        <DialogContent>
          <DialogHeader><DialogTitle>Create Plan from Template</DialogTitle></DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Template *</Label>
              <Select value={selectedTemplateId} onValueChange={setSelectedTemplateId}>
                <SelectTrigger><SelectValue placeholder="Choose a template..." /></SelectTrigger>
                <SelectContent>
                  {templates.map((t) => (
                    <SelectItem key={t.id} value={t.id}>
                      {t.name}{t.instrument ? ` — ${t.instrument}` : ''}{t.skillLevel !== 'all_levels' ? ` (${t.skillLevel})` : ''}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Custom Title</Label>
              <Input value={customTitle} onChange={(e) => setCustomTitle(e.target.value)} placeholder="Leave blank to use template name" />
            </div>
            <Button
              onClick={() => instantiateMutation.mutate()}
              disabled={!selectedTemplateId || instantiateMutation.isPending}
              className="w-full"
            >
              {instantiateMutation.isPending ? 'Creating...' : 'Create Plan'}
            </Button>
          </div>
        </DialogContent>
      </Dialog>
    </div>
  )
}
