import { useState } from 'react'
import { createFileRoute, useNavigate, Link } from '@tanstack/react-router'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  sessionDetailOptions, sessionMutations, sessionKeys,
  sessionPlanItemsOptions,
  enrollmentDetailOptions,
  instructorDetailOptions, instructorListOptions,
  lessonPlanListOptions,
} from '@/api/lessons'
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 { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { ArrowLeft, CheckSquare, Square } from 'lucide-react'
import { toast } from 'sonner'
import { useAuthStore } from '@/stores/auth.store'
import type { LessonPlan, LessonPlanSection, LessonSession } from '@/types/lesson'

export const Route = createFileRoute('/_authenticated/lessons/sessions/$sessionId')({
  component: SessionDetailPage,
})

const STATUS_ACTIONS: Record<string, { label: string; next: string; variant: 'default' | 'destructive' | 'secondary' | 'outline' }[]> = {
  scheduled: [
    { label: 'Mark Attended', next: 'attended', variant: 'default' },
    { label: 'Mark Missed', next: 'missed', variant: 'destructive' },
    { label: 'Cancel', next: 'cancelled', variant: 'secondary' },
  ],
  attended: [],
  missed: [],
  makeup: [
    { label: 'Mark Attended', next: 'attended', variant: 'default' },
    { label: 'Cancel', next: 'cancelled', variant: 'secondary' },
  ],
  cancelled: [],
}

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>
}

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 SessionDetailPage() {
  const { sessionId } = Route.useParams()
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const hasPermission = useAuthStore((s) => s.hasPermission)
  const canEdit = hasPermission('lessons.edit')

  const { data: session, isLoading } = useQuery(sessionDetailOptions(sessionId))

  const { data: enrollment } = useQuery({
    ...enrollmentDetailOptions(session?.enrollmentId ?? ''),
    enabled: !!session?.enrollmentId,
  })

  useQuery({
    ...instructorDetailOptions(session?.substituteInstructorId ?? enrollment?.instructorId ?? ''),
    enabled: !!(session?.substituteInstructorId ?? enrollment?.instructorId),
  })

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

  const { data: planItems } = useQuery(sessionPlanItemsOptions(sessionId))

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

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

  const notesMutation = useMutation({
    mutationFn: (data: Record<string, unknown>) => sessionMutations.updateNotes(sessionId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: sessionKeys.detail(sessionId) })
      toast.success('Notes saved')
    },
    onError: (err) => toast.error(err.message),
  })

  const subMutation = useMutation({
    mutationFn: (subId: string | null) => sessionMutations.update(sessionId, { substituteInstructorId: subId }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: sessionKeys.detail(sessionId) })
      toast.success('Substitute updated')
    },
    onError: (err) => toast.error(err.message),
  })

  const linkPlanItemsMutation = useMutation({
    mutationFn: (ids: string[]) => sessionMutations.linkPlanItems(sessionId, ids),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: sessionKeys.planItems(sessionId) })
      toast.success('Plan items linked')
    },
    onError: (err) => toast.error(err.message),
  })

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

  const linkedItemIds = new Set(planItems?.map((pi) => pi.lessonPlanItemId) ?? [])

  return (
    <div className="space-y-6 max-w-3xl">
      <div className="flex items-center gap-3">
        <Button variant="ghost" size="sm" onClick={() => navigate({ to: '/lessons/sessions', search: { view: 'list' as const, page: 1, limit: 25, q: undefined, sort: undefined, order: 'desc' as const, status: undefined, instructorId: undefined } })}>
          <ArrowLeft className="h-4 w-4" />
        </Button>
        <div className="flex-1">
          <h1 className="text-xl font-bold">
            {new Date(session.scheduledDate + 'T00:00:00').toLocaleDateString()} · {formatTime(session.scheduledTime)}
          </h1>
          {enrollment && (
            <Link
              to="/lessons/enrollments/$enrollmentId"
              params={{ enrollmentId: enrollment.id }}
              search={{ tab: 'details' }}
              className="text-sm text-primary hover:underline"
            >
              View Enrollment
            </Link>
          )}
        </div>
        {sessionStatusBadge(session.status)}
      </div>

      {/* Status Actions */}
      {canEdit && (STATUS_ACTIONS[session.status]?.length ?? 0) > 0 && (
        <Card>
          <CardContent className="pt-4">
            <div className="flex gap-2">
              {STATUS_ACTIONS[session.status].map((action) => (
                <Button
                  key={action.next}
                  variant={action.variant}
                  size="sm"
                  onClick={() => statusMutation.mutate(action.next)}
                  disabled={statusMutation.isPending}
                >
                  {action.label}
                </Button>
              ))}
            </div>
          </CardContent>
        </Card>
      )}

      {/* Substitute Instructor */}
      {canEdit && (
        <Card>
          <CardHeader><CardTitle className="text-base">Substitute Instructor</CardTitle></CardHeader>
          <CardContent className="flex gap-3 items-center">
            <Select
              value={session.substituteInstructorId ?? 'none'}
              onValueChange={(v) => subMutation.mutate(v === 'none' ? null : v)}
            >
              <SelectTrigger className="flex-1">
                <SelectValue placeholder="No substitute" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="none">No substitute</SelectItem>
                {(instructorsList?.data ?? []).map((i) => (
                  <SelectItem key={i.id} value={i.id}>{i.displayName}</SelectItem>
                ))}
              </SelectContent>
            </Select>
          </CardContent>
        </Card>
      )}

      {/* Post-lesson Notes */}
      <NotesCard session={session} canEdit={canEdit} onSave={notesMutation.mutate} saving={notesMutation.isPending} />

      {/* Plan Items */}
      {activePlan && (
        <PlanItemsCard
          plan={activePlan}
          linkedItemIds={linkedItemIds}
          onLink={(ids) => linkPlanItemsMutation.mutate(ids)}
          linking={linkPlanItemsMutation.isPending}
        />
      )}
    </div>
  )
}

// ─── Notes Card ───────────────────────────────────────────────────────────────

function NotesCard({ session, canEdit, onSave, saving }: {
  session: LessonSession
  canEdit: boolean
  onSave: (data: Record<string, unknown>) => void
  saving: boolean
}) {
  const [instructorNotes, setInstructorNotes] = useState(session.instructorNotes ?? '')
  const [memberNotes, setMemberNotes] = useState(session.memberNotes ?? '')
  const [homeworkAssigned, setHomeworkAssigned] = useState(session.homeworkAssigned ?? '')
  const [nextLessonGoals, setNextLessonGoals] = useState(session.nextLessonGoals ?? '')
  const [topicsCovered, setTopicsCovered] = useState((session.topicsCovered ?? []).join(', '))

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <CardTitle className="text-base">Post-lesson Notes</CardTitle>
          {session.notesCompletedAt && (
            <span className="text-xs text-muted-foreground">
              Saved {new Date(session.notesCompletedAt).toLocaleString()}
            </span>
          )}
        </div>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="space-y-2">
          <Label>Instructor Notes</Label>
          <Textarea value={instructorNotes} onChange={(e) => setInstructorNotes(e.target.value)} rows={3} disabled={!canEdit} />
        </div>
        <div className="space-y-2">
          <Label>Member Notes (shared with student)</Label>
          <Textarea value={memberNotes} onChange={(e) => setMemberNotes(e.target.value)} rows={2} disabled={!canEdit} />
        </div>
        <div className="grid grid-cols-2 gap-4">
          <div className="space-y-2">
            <Label>Homework Assigned</Label>
            <Input value={homeworkAssigned} onChange={(e) => setHomeworkAssigned(e.target.value)} disabled={!canEdit} />
          </div>
          <div className="space-y-2">
            <Label>Next Lesson Goals</Label>
            <Input value={nextLessonGoals} onChange={(e) => setNextLessonGoals(e.target.value)} disabled={!canEdit} />
          </div>
        </div>
        <div className="space-y-2">
          <Label>Topics Covered</Label>
          <Input
            value={topicsCovered}
            onChange={(e) => setTopicsCovered(e.target.value)}
            placeholder="Comma-separated topics"
            disabled={!canEdit}
          />
        </div>
        {canEdit && (
          <Button
            onClick={() => onSave({
              instructorNotes: instructorNotes || undefined,
              memberNotes: memberNotes || undefined,
              homeworkAssigned: homeworkAssigned || undefined,
              nextLessonGoals: nextLessonGoals || undefined,
              topicsCovered: topicsCovered ? topicsCovered.split(',').map((s: string) => s.trim()).filter(Boolean) : undefined,
            })}
            disabled={saving}
          >
            {saving ? 'Saving...' : 'Save Notes'}
          </Button>
        )}
      </CardContent>
    </Card>
  )
}

// ─── Plan Items Card ──────────────────────────────────────────────────────────

function PlanItemsCard({ plan, linkedItemIds, onLink, linking }: {
  plan: LessonPlan
  linkedItemIds: Set<string>
  onLink: (ids: string[]) => void
  linking: boolean
}) {
  const [selected, setSelected] = useState<Set<string>>(new Set(linkedItemIds))

  function toggle(id: string) {
    if (linkedItemIds.has(id)) return // already committed
    setSelected((prev) => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  const newSelections = [...selected].filter((id) => !linkedItemIds.has(id))

  return (
    <Card>
      <CardHeader><CardTitle className="text-base">Plan Items Worked On</CardTitle></CardHeader>
      <CardContent className="space-y-4">
        {(plan.sections ?? []).map((section: LessonPlanSection) => (
          <div key={section.id}>
            <p className="text-sm font-semibold text-muted-foreground mb-2">{section.title}</p>
            <div className="space-y-1">
              {(section.items ?? []).map((item) => {
                const isLinked = linkedItemIds.has(item.id)
                const isSelected = selected.has(item.id)
                return (
                  <button
                    key={item.id}
                    type="button"
                    className={`flex items-center gap-2 w-full text-left px-2 py-1.5 rounded text-sm transition-colors ${
                      isLinked ? 'opacity-60 cursor-default' : 'hover:bg-accent cursor-pointer'
                    }`}
                    onClick={() => toggle(item.id)}
                    disabled={isLinked}
                  >
                    {isLinked || isSelected
                      ? <CheckSquare className="h-4 w-4 text-primary shrink-0" />
                      : <Square className="h-4 w-4 text-muted-foreground shrink-0" />}
                    <span>{item.title}</span>
                    {isLinked && <span className="text-xs text-muted-foreground ml-auto">linked</span>}
                  </button>
                )
              })}
            </div>
          </div>
        ))}

        {newSelections.length > 0 && (
          <Button onClick={() => onLink(newSelections)} disabled={linking} size="sm">
            {linking ? 'Linking...' : `Link ${newSelections.length} item${newSelections.length !== 1 ? 's' : ''}`}
          </Button>
        )}
      </CardContent>
    </Card>
  )
}
