'use client'

import { Suspense, useState } from 'react'
import Link from 'next/link'
import { trpc } from '@/lib/trpc/client'
import { toast } from 'sonner'
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
} from '@dnd-kit/core'
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import {
  Plus,
  MoreHorizontal,
  Eye,
  Edit,
  Users,
  FileText,
  Calendar,
  CheckCircle2,
  Clock,
  Archive,
  Trash2,
  Loader2,
  GripVertical,
  ArrowRight,
} from 'lucide-react'
import { format, isPast, isFuture } from 'date-fns'
import { cn } from '@/lib/utils'

type RoundData = {
  id: string
  name: string
  status: string
  roundType: string
  votingStartAt: string | null
  votingEndAt: string | null
  _count?: {
    projects: number
    assignments: number
  }
}

function RoundsContent() {
  const { data: programs, isLoading } = trpc.program.list.useQuery({
    includeRounds: true,
  })

  if (isLoading) {
    return <RoundsListSkeleton />
  }

  if (!programs || programs.length === 0) {
    return (
      <Card>
        <CardContent className="flex flex-col items-center justify-center py-12 text-center">
          <Calendar className="h-12 w-12 text-muted-foreground/50" />
          <p className="mt-2 font-medium">No Programs Found</p>
          <p className="text-sm text-muted-foreground">
            Create a program first to start managing rounds
          </p>
          <Button asChild className="mt-4">
            <Link href="/admin/programs/new">Create Program</Link>
          </Button>
        </CardContent>
      </Card>
    )
  }

  return (
    <div className="space-y-6">
      {programs.map((program) => (
        <ProgramRounds key={program.id} program={program} />
      ))}
    </div>
  )
}

function ProgramRounds({ program }: { program: any }) {
  const utils = trpc.useUtils()
  const [rounds, setRounds] = useState<RoundData[]>(program.rounds || [])

  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 8,
      },
    }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  )

  const reorder = trpc.round.reorder.useMutation({
    onSuccess: () => {
      utils.program.list.invalidate({ includeRounds: true })
      toast.success('Round order updated')
    },
    onError: (error) => {
      toast.error(error.message || 'Failed to reorder rounds')
      // Reset to original order on error
      setRounds(program.rounds || [])
    },
  })

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event

    if (over && active.id !== over.id) {
      const oldIndex = rounds.findIndex((r) => r.id === active.id)
      const newIndex = rounds.findIndex((r) => r.id === over.id)

      const newRounds = arrayMove(rounds, oldIndex, newIndex)
      setRounds(newRounds)

      // Send the new order to the server
      reorder.mutate({
        programId: program.id,
        roundIds: newRounds.map((r) => r.id),
      })
    }
  }

  // Sync local state when program.rounds changes
  if (JSON.stringify(rounds.map(r => r.id)) !== JSON.stringify((program.rounds || []).map((r: RoundData) => r.id))) {
    setRounds(program.rounds || [])
  }

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <div>
            <CardTitle className="text-lg">{program.year} Edition</CardTitle>
            <CardDescription>
              {program.name} - {program.status}
            </CardDescription>
          </div>
          <Button asChild>
            <Link href={`/admin/rounds/new?program=${program.id}`}>
              <Plus className="mr-2 h-4 w-4" />
              Add Round
            </Link>
          </Button>
        </div>
      </CardHeader>
      <CardContent>
        {rounds.length > 0 ? (
          <div className="space-y-2">
            {/* Header */}
            <div className="grid grid-cols-[60px_1fr_120px_140px_80px_100px_50px] gap-3 px-3 py-2 text-xs font-medium text-muted-foreground uppercase tracking-wide">
              <div>Order</div>
              <div>Round</div>
              <div>Status</div>
              <div>Voting Window</div>
              <div>Projects</div>
              <div>Reviewers</div>
              <div></div>
            </div>

            {/* Sortable List */}
            <DndContext
              sensors={sensors}
              collisionDetection={closestCenter}
              onDragEnd={handleDragEnd}
            >
              <SortableContext
                items={rounds.map((r) => r.id)}
                strategy={verticalListSortingStrategy}
              >
                <div className="space-y-1">
                  {rounds.map((round, index) => (
                    <SortableRoundRow
                      key={round.id}
                      round={round}
                      index={index}
                      totalRounds={rounds.length}
                      isReordering={reorder.isPending}
                    />
                  ))}
                </div>
              </SortableContext>
            </DndContext>

            {/* Flow visualization */}
            {rounds.length > 1 && (
              <div className="mt-6 pt-4 border-t">
                <p className="text-xs text-muted-foreground mb-3 uppercase tracking-wide font-medium">
                  Project Flow
                </p>
                <div className="flex items-center gap-2 flex-wrap">
                  {rounds.map((round, index) => (
                    <div key={round.id} className="flex items-center gap-2">
                      <div className="flex items-center gap-2 bg-muted/50 rounded-lg px-3 py-1.5">
                        <span className="inline-flex items-center justify-center w-5 h-5 rounded-full bg-primary/10 text-primary text-xs font-bold">
                          {index}
                        </span>
                        <span className="text-sm font-medium truncate max-w-[120px]">
                          {round.name}
                        </span>
                        <Badge variant="outline" className="text-[10px] px-1.5 py-0">
                          {round._count?.projects || 0}
                        </Badge>
                      </div>
                      {index < rounds.length - 1 && (
                        <ArrowRight className="h-4 w-4 text-muted-foreground/50" />
                      )}
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        ) : (
          <div className="text-center py-8 text-muted-foreground">
            <Calendar className="mx-auto h-8 w-8 mb-2 opacity-50" />
            <p>No rounds created yet</p>
          </div>
        )}
      </CardContent>
    </Card>
  )
}

function SortableRoundRow({
  round,
  index,
  totalRounds,
  isReordering,
}: {
  round: RoundData
  index: number
  totalRounds: number
  isReordering: boolean
}) {
  const utils = trpc.useUtils()
  const [showDeleteDialog, setShowDeleteDialog] = useState(false)

  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: round.id })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  }

  const updateStatus = trpc.round.updateStatus.useMutation({
    onSuccess: () => {
      utils.program.list.invalidate({ includeRounds: true })
    },
  })

  const deleteRound = trpc.round.delete.useMutation({
    onSuccess: () => {
      toast.success('Round deleted successfully')
      utils.program.list.invalidate({ includeRounds: true })
    },
    onError: (error) => {
      toast.error(error.message || 'Failed to delete round')
    },
  })

  const getStatusBadge = () => {
    const now = new Date()
    const isVotingOpen =
      round.status === 'ACTIVE' &&
      round.votingStartAt &&
      round.votingEndAt &&
      new Date(round.votingStartAt) <= now &&
      new Date(round.votingEndAt) >= now

    if (round.status === 'ACTIVE' && isVotingOpen) {
      return (
        <Badge variant="default" className="bg-green-600">
          <CheckCircle2 className="mr-1 h-3 w-3" />
          Voting Open
        </Badge>
      )
    }

    switch (round.status) {
      case 'DRAFT':
        return <Badge variant="secondary">Draft</Badge>
      case 'ACTIVE':
        return (
          <Badge variant="default">
            <Clock className="mr-1 h-3 w-3" />
            Active
          </Badge>
        )
      case 'CLOSED':
        return <Badge variant="outline">Closed</Badge>
      case 'ARCHIVED':
        return (
          <Badge variant="outline">
            <Archive className="mr-1 h-3 w-3" />
            Archived
          </Badge>
        )
      default:
        return <Badge variant="secondary">{round.status}</Badge>
    }
  }

  const getVotingWindow = () => {
    if (!round.votingStartAt || !round.votingEndAt) {
      return <span className="text-muted-foreground text-sm">Not set</span>
    }

    const start = new Date(round.votingStartAt)
    const end = new Date(round.votingEndAt)

    if (isFuture(start)) {
      return (
        <span className="text-sm">
          Opens {format(start, 'MMM d')}
        </span>
      )
    }

    if (isPast(end)) {
      return (
        <span className="text-sm text-muted-foreground">
          Ended {format(end, 'MMM d')}
        </span>
      )
    }

    return (
      <span className="text-sm">
        Until {format(end, 'MMM d')}
      </span>
    )
  }

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={cn(
        'grid grid-cols-[60px_1fr_120px_140px_80px_100px_50px] gap-3 items-center px-3 py-2.5 rounded-lg border bg-card transition-all',
        isDragging && 'shadow-lg ring-2 ring-primary/20 z-50 opacity-90',
        isReordering && !isDragging && 'opacity-50'
      )}
    >
      {/* Order number with drag handle */}
      <div className="flex items-center gap-1">
        <button
          {...attributes}
          {...listeners}
          className="cursor-grab active:cursor-grabbing p-1 -ml-1 rounded hover:bg-muted transition-colors touch-none"
          disabled={isReordering}
        >
          <GripVertical className="h-4 w-4 text-muted-foreground" />
        </button>
        <span className="inline-flex items-center justify-center w-7 h-7 rounded-full bg-primary/10 text-primary text-sm font-bold">
          {index}
        </span>
      </div>

      {/* Round name */}
      <div>
        <Link
          href={`/admin/rounds/${round.id}`}
          className="font-medium hover:underline"
        >
          {round.name}
        </Link>
        <p className="text-xs text-muted-foreground capitalize">
          {round.roundType?.toLowerCase().replace('_', ' ')}
        </p>
      </div>

      {/* Status */}
      <div>{getStatusBadge()}</div>

      {/* Voting window */}
      <div>{getVotingWindow()}</div>

      {/* Projects */}
      <div className="flex items-center gap-1.5">
        <FileText className="h-4 w-4 text-muted-foreground" />
        <span className="font-medium">{round._count?.projects || 0}</span>
      </div>

      {/* Assignments */}
      <div className="flex items-center gap-1.5">
        <Users className="h-4 w-4 text-muted-foreground" />
        <span className="font-medium">{round._count?.assignments || 0}</span>
      </div>

      {/* Actions */}
      <div>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="ghost" size="icon" className="h-8 w-8" aria-label="Round actions">
              <MoreHorizontal className="h-4 w-4" />
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuItem asChild>
              <Link href={`/admin/rounds/${round.id}`}>
                <Eye className="mr-2 h-4 w-4" />
                View Details
              </Link>
            </DropdownMenuItem>
            <DropdownMenuItem asChild>
              <Link href={`/admin/rounds/${round.id}/edit`}>
                <Edit className="mr-2 h-4 w-4" />
                Edit Round
              </Link>
            </DropdownMenuItem>
            <DropdownMenuItem asChild>
              <Link href={`/admin/rounds/${round.id}/assignments`}>
                <Users className="mr-2 h-4 w-4" />
                Manage Judge Assignments
              </Link>
            </DropdownMenuItem>
            <DropdownMenuSeparator />
            {round.status === 'DRAFT' && (
              <DropdownMenuItem
                onClick={() =>
                  updateStatus.mutate({ id: round.id, status: 'ACTIVE' })
                }
              >
                <CheckCircle2 className="mr-2 h-4 w-4" />
                Activate Round
              </DropdownMenuItem>
            )}
            {round.status === 'ACTIVE' && (
              <DropdownMenuItem
                onClick={() =>
                  updateStatus.mutate({ id: round.id, status: 'CLOSED' })
                }
              >
                <Clock className="mr-2 h-4 w-4" />
                Close Round
              </DropdownMenuItem>
            )}
            {round.status === 'CLOSED' && (
              <DropdownMenuItem
                onClick={() =>
                  updateStatus.mutate({ id: round.id, status: 'ARCHIVED' })
                }
              >
                <Archive className="mr-2 h-4 w-4" />
                Archive Round
              </DropdownMenuItem>
            )}
            <DropdownMenuSeparator />
            <DropdownMenuItem
              className="text-destructive focus:text-destructive"
              onClick={() => setShowDeleteDialog(true)}
            >
              <Trash2 className="mr-2 h-4 w-4" />
              Delete Round
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>

        <AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
          <AlertDialogContent>
            <AlertDialogHeader>
              <AlertDialogTitle>Delete Round</AlertDialogTitle>
              <AlertDialogDescription>
                Are you sure you want to delete &quot;{round.name}&quot;? This will
                remove {round._count?.projects || 0} project assignments,{' '}
                {round._count?.assignments || 0} reviewer assignments, and all evaluations
                in this round. The projects themselves will remain in the program. This action cannot be undone.
              </AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
              <AlertDialogCancel>Cancel</AlertDialogCancel>
              <AlertDialogAction
                onClick={() => deleteRound.mutate({ id: round.id })}
                className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              >
                {deleteRound.isPending ? (
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                ) : null}
                Delete
              </AlertDialogAction>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialog>
      </div>
    </div>
  )
}

function RoundsListSkeleton() {
  return (
    <div className="space-y-6">
      {[1, 2].map((i) => (
        <Card key={i}>
          <CardHeader>
            <div className="flex items-center justify-between">
              <div className="space-y-1">
                <Skeleton className="h-5 w-48" />
                <Skeleton className="h-4 w-32" />
              </div>
              <Skeleton className="h-10 w-28" />
            </div>
          </CardHeader>
          <CardContent>
            <div className="space-y-3">
              {[1, 2, 3].map((j) => (
                <div key={j} className="flex justify-between items-center py-2">
                  <Skeleton className="h-4 w-40" />
                  <Skeleton className="h-6 w-20" />
                  <Skeleton className="h-4 w-32" />
                  <Skeleton className="h-4 w-12" />
                  <Skeleton className="h-4 w-12" />
                  <Skeleton className="h-8 w-8" />
                </div>
              ))}
            </div>
          </CardContent>
        </Card>
      ))}
    </div>
  )
}

export default function RoundsPage() {
  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight">Rounds</h1>
          <p className="text-muted-foreground">
            Manage selection rounds and voting periods
          </p>
        </div>
      </div>

      {/* Content */}
      <Suspense fallback={<RoundsListSkeleton />}>
        <RoundsContent />
      </Suspense>
    </div>
  )
}
