'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">
            {/* Desktop: Table header */}
            <div className="hidden lg: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-2 lg: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>
    )
  }

  const actionsMenu = (
    <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>
  )

  const deleteDialog = (
    <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>
  )

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={cn(
        'rounded-lg border bg-card transition-all',
        isDragging && 'shadow-lg ring-2 ring-primary/20 z-50 opacity-90',
        isReordering && !isDragging && 'opacity-50'
      )}
    >
      {/* Desktop: Table row layout */}
      <div className="hidden lg:grid grid-cols-[60px_1fr_120px_140px_80px_100px_50px] gap-3 items-center px-3 py-2.5">
        {/* 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>
          {actionsMenu}
        </div>
      </div>

      {/* Mobile/Tablet: Card layout */}
      <div className="lg:hidden p-4">
        {/* Top row: drag handle, order, name, status badge, actions */}
        <div className="flex items-start gap-3">
          <div className="flex items-center gap-1 pt-0.5">
            <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>
          <div className="flex-1 min-w-0">
            <div className="flex items-start justify-between gap-2">
              <div className="min-w-0">
                <Link
                  href={`/admin/rounds/${round.id}`}
                  className="font-medium hover:underline line-clamp-1"
                >
                  {round.name}
                </Link>
                <p className="text-xs text-muted-foreground capitalize">
                  {round.roundType?.toLowerCase().replace('_', ' ')}
                </p>
              </div>
              <div className="flex items-center gap-1 shrink-0">
                {getStatusBadge()}
                {actionsMenu}
              </div>
            </div>
          </div>
        </div>

        {/* Details row */}
        <div className="mt-3 ml-11 grid grid-cols-2 gap-x-4 gap-y-2 text-sm sm:grid-cols-3">
          <div>
            <p className="text-xs text-muted-foreground">Voting Window</p>
            <div className="mt-0.5">{getVotingWindow()}</div>
          </div>
          <div>
            <p className="text-xs text-muted-foreground">Projects</p>
            <div className="flex items-center gap-1.5 mt-0.5">
              <FileText className="h-3.5 w-3.5 text-muted-foreground" />
              <span className="font-medium">{round._count?.projects || 0}</span>
            </div>
          </div>
          <div>
            <p className="text-xs text-muted-foreground">Reviewers</p>
            <div className="flex items-center gap-1.5 mt-0.5">
              <Users className="h-3.5 w-3.5 text-muted-foreground" />
              <span className="font-medium">{round._count?.assignments || 0}</span>
            </div>
          </div>
        </div>
      </div>

      {deleteDialog}
    </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>
            {/* Desktop skeleton */}
            <div className="hidden lg:block 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>
            {/* Mobile/Tablet skeleton */}
            <div className="lg:hidden space-y-3">
              {[1, 2, 3].map((j) => (
                <div key={j} className="rounded-lg border p-4 space-y-3">
                  <div className="flex items-center gap-3">
                    <Skeleton className="h-7 w-7 rounded-full" />
                    <div className="flex-1 space-y-1">
                      <Skeleton className="h-4 w-40" />
                      <Skeleton className="h-3 w-24" />
                    </div>
                    <Skeleton className="h-6 w-16" />
                  </div>
                  <div className="ml-10 grid grid-cols-2 gap-3 sm:grid-cols-3">
                    <Skeleton className="h-8 w-full" />
                    <Skeleton className="h-8 w-full" />
                    <Skeleton className="h-8 w-full" />
                  </div>
                </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>
  )
}
