'use client'

import { Suspense, use, useState, useEffect } from 'react'
import Link from 'next/link'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Skeleton } from '@/components/ui/skeleton'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Progress } from '@/components/ui/progress'
import { toast } from 'sonner'
import {
  ArrowLeft,
  Play,
  Pause,
  Square,
  Clock,
  Users,
  Zap,
  GripVertical,
  AlertCircle,
  ExternalLink,
  RefreshCw,
} from 'lucide-react'
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  type DragEndEvent,
} from '@dnd-kit/core'
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'

interface PageProps {
  params: Promise<{ id: string }>
}

interface Project {
  id: string
  title: string
  teamName: string | null
}

function SortableProject({
  project,
  isActive,
  isVoting,
}: {
  project: Project
  isActive: boolean
  isVoting: boolean
}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: project.id })

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

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`flex items-center gap-3 rounded-lg border p-3 ${
        isDragging ? 'opacity-50 shadow-lg' : ''
      } ${isActive ? 'border-primary bg-primary/5' : ''} ${
        isVoting ? 'ring-2 ring-green-500 animate-pulse' : ''
      }`}
    >
      <button
        className="cursor-grab touch-none text-muted-foreground hover:text-foreground"
        {...attributes}
        {...listeners}
      >
        <GripVertical className="h-4 w-4" />
      </button>
      <div className="flex-1 min-w-0">
        <p className="font-medium truncate">{project.title}</p>
        {project.teamName && (
          <p className="text-sm text-muted-foreground truncate">
            {project.teamName}
          </p>
        )}
      </div>
      {isActive && (
        <Badge variant={isVoting ? 'default' : 'secondary'}>
          {isVoting ? 'Voting' : 'Current'}
        </Badge>
      )}
    </div>
  )
}

function LiveVotingContent({ roundId }: { roundId: string }) {
  const utils = trpc.useUtils()
  const [projectOrder, setProjectOrder] = useState<string[]>([])
  const [countdown, setCountdown] = useState<number | null>(null)
  const [votingDuration, setVotingDuration] = useState(30)

  // Fetch session data
  const { data: sessionData, isLoading, refetch } = trpc.liveVoting.getSession.useQuery(
    { roundId },
    { refetchInterval: 2000 } // Poll every 2 seconds
  )

  // Mutations
  const setOrder = trpc.liveVoting.setProjectOrder.useMutation({
    onSuccess: () => {
      toast.success('Project order updated')
    },
    onError: (error) => {
      toast.error(error.message)
    },
  })

  const startVoting = trpc.liveVoting.startVoting.useMutation({
    onSuccess: () => {
      toast.success('Voting started')
      refetch()
    },
    onError: (error) => {
      toast.error(error.message)
    },
  })

  const stopVoting = trpc.liveVoting.stopVoting.useMutation({
    onSuccess: () => {
      toast.success('Voting stopped')
      refetch()
    },
    onError: (error) => {
      toast.error(error.message)
    },
  })

  const endSession = trpc.liveVoting.endSession.useMutation({
    onSuccess: () => {
      toast.success('Session ended')
      refetch()
    },
    onError: (error) => {
      toast.error(error.message)
    },
  })

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

  // Initialize project order
  useEffect(() => {
    if (sessionData) {
      const storedOrder = (sessionData.projectOrderJson as string[]) || []
      if (storedOrder.length > 0) {
        setProjectOrder(storedOrder)
      } else {
        setProjectOrder(sessionData.round.projects.map((p) => p.id))
      }
    }
  }, [sessionData])

  // Countdown timer
  useEffect(() => {
    if (!sessionData?.votingEndsAt || sessionData.status !== 'IN_PROGRESS') {
      setCountdown(null)
      return
    }

    const updateCountdown = () => {
      const remaining = new Date(sessionData.votingEndsAt!).getTime() - Date.now()
      setCountdown(Math.max(0, Math.floor(remaining / 1000)))
    }

    updateCountdown()
    const interval = setInterval(updateCountdown, 1000)
    return () => clearInterval(interval)
  }, [sessionData?.votingEndsAt, sessionData?.status])

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

    if (over && active.id !== over.id) {
      const oldIndex = projectOrder.indexOf(active.id as string)
      const newIndex = projectOrder.indexOf(over.id as string)
      const newOrder = arrayMove(projectOrder, oldIndex, newIndex)
      setProjectOrder(newOrder)

      if (sessionData) {
        setOrder.mutate({
          sessionId: sessionData.id,
          projectIds: newOrder,
        })
      }
    }
  }

  const handleStartVoting = (projectId: string) => {
    if (!sessionData) return
    startVoting.mutate({
      sessionId: sessionData.id,
      projectId,
      durationSeconds: votingDuration,
    })
  }

  const handleStopVoting = () => {
    if (!sessionData) return
    stopVoting.mutate({ sessionId: sessionData.id })
  }

  const handleEndSession = () => {
    if (!sessionData) return
    endSession.mutate({ sessionId: sessionData.id })
  }

  if (isLoading) {
    return <LiveVotingSkeleton />
  }

  if (!sessionData) {
    return (
      <Alert variant="destructive">
        <AlertCircle className="h-4 w-4" />
        <AlertTitle>Error</AlertTitle>
        <AlertDescription>Failed to load session</AlertDescription>
      </Alert>
    )
  }

  const projects = sessionData.round.projects
  const sortedProjects = projectOrder
    .map((id) => projects.find((p) => p.id === id))
    .filter((p): p is Project => !!p)

  // Add any projects not in the order
  const missingProjects = projects.filter((p) => !projectOrder.includes(p.id))
  const allProjects = [...sortedProjects, ...missingProjects]

  const isVoting = sessionData.status === 'IN_PROGRESS'
  const isCompleted = sessionData.status === 'COMPLETED'

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center gap-4">
        <Button variant="ghost" asChild className="-ml-4">
          <Link href={`/admin/rounds/${roundId}`}>
            <ArrowLeft className="mr-2 h-4 w-4" />
            Back to Round
          </Link>
        </Button>
      </div>

      <div className="flex items-start justify-between">
        <div>
          <div className="flex items-center gap-3">
            <Zap className="h-6 w-6 text-primary" />
            <h1 className="text-2xl font-semibold tracking-tight">Live Voting</h1>
            <Badge
              variant={
                isVoting ? 'default' : isCompleted ? 'secondary' : 'outline'
              }
            >
              {sessionData.status.replace('_', ' ')}
            </Badge>
          </div>
          <p className="text-muted-foreground">
            {sessionData.round.program.name} - {sessionData.round.name}
          </p>
        </div>
        <Button variant="outline" size="sm" onClick={() => refetch()}>
          <RefreshCw className="mr-2 h-4 w-4" />
          Refresh
        </Button>
      </div>

      <div className="grid gap-6 lg:grid-cols-3">
        {/* Main control panel */}
        <div className="lg:col-span-2 space-y-6">
          {/* Voting status */}
          {isVoting && (
            <Card className="border-green-500 bg-green-500/10">
              <CardContent className="py-6">
                <div className="flex items-center justify-between">
                  <div>
                    <p className="text-sm font-medium text-muted-foreground">
                      Currently Voting
                    </p>
                    <p className="text-xl font-semibold">
                      {projects.find((p) => p.id === sessionData.currentProjectId)?.title}
                    </p>
                  </div>
                  <div className="text-right">
                    <div className="text-3xl font-bold text-primary">
                      {countdown !== null ? countdown : '--'}s
                    </div>
                    <p className="text-sm text-muted-foreground">remaining</p>
                  </div>
                </div>
                {countdown !== null && (
                  <Progress
                    value={(countdown / votingDuration) * 100}
                    className="mt-4"
                  />
                )}
                <div className="flex gap-2 mt-4">
                  <Button
                    variant="destructive"
                    onClick={handleStopVoting}
                    disabled={stopVoting.isPending}
                  >
                    <Pause className="mr-2 h-4 w-4" />
                    Stop Voting
                  </Button>
                </div>
              </CardContent>
            </Card>
          )}

          {/* Project order */}
          <Card>
            <CardHeader>
              <CardTitle>Presentation Order</CardTitle>
              <CardDescription>
                Drag to reorder projects. Click &quot;Start Voting&quot; to begin voting
                for a project.
              </CardDescription>
            </CardHeader>
            <CardContent>
              {allProjects.length === 0 ? (
                <p className="text-muted-foreground text-center py-4">
                  No finalist projects found for this round
                </p>
              ) : (
                <DndContext
                  sensors={sensors}
                  collisionDetection={closestCenter}
                  onDragEnd={handleDragEnd}
                >
                  <SortableContext
                    items={allProjects.map((p) => p.id)}
                    strategy={verticalListSortingStrategy}
                  >
                    <div className="space-y-2">
                      {allProjects.map((project) => (
                        <div key={project.id} className="flex items-center gap-2">
                          <SortableProject
                            project={project}
                            isActive={sessionData.currentProjectId === project.id}
                            isVoting={
                              isVoting &&
                              sessionData.currentProjectId === project.id
                            }
                          />
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => handleStartVoting(project.id)}
                            disabled={
                              isVoting ||
                              isCompleted ||
                              startVoting.isPending
                            }
                          >
                            <Play className="h-4 w-4" />
                          </Button>
                        </div>
                      ))}
                    </div>
                  </SortableContext>
                </DndContext>
              )}
            </CardContent>
          </Card>
        </div>

        {/* Sidebar */}
        <div className="space-y-6">
          {/* Controls */}
          <Card>
            <CardHeader>
              <CardTitle>Controls</CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="space-y-2">
                <label className="text-sm font-medium">Voting Duration</label>
                <div className="flex items-center gap-2">
                  <input
                    type="number"
                    min="10"
                    max="300"
                    value={votingDuration}
                    onChange={(e) =>
                      setVotingDuration(parseInt(e.target.value) || 30)
                    }
                    className="w-20 px-2 py-1 border rounded text-center"
                    disabled={isVoting}
                  />
                  <span className="text-sm text-muted-foreground">seconds</span>
                </div>
              </div>

              <div className="pt-4 border-t">
                <Button
                  variant="destructive"
                  className="w-full"
                  onClick={handleEndSession}
                  disabled={isCompleted || endSession.isPending}
                >
                  <Square className="mr-2 h-4 w-4" />
                  End Session
                </Button>
              </div>
            </CardContent>
          </Card>

          {/* Live stats */}
          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <Users className="h-5 w-5" />
                Current Votes
              </CardTitle>
            </CardHeader>
            <CardContent>
              {sessionData.currentVotes.length === 0 ? (
                <p className="text-muted-foreground text-center py-4">
                  No votes yet
                </p>
              ) : (
                <div className="space-y-2">
                  <div className="flex justify-between text-sm">
                    <span className="text-muted-foreground">Total votes</span>
                    <span className="font-medium">
                      {sessionData.currentVotes.length}
                    </span>
                  </div>
                  <div className="flex justify-between text-sm">
                    <span className="text-muted-foreground">Average score</span>
                    <span className="font-medium">
                      {(
                        sessionData.currentVotes.reduce(
                          (sum, v) => sum + v.score,
                          0
                        ) / sessionData.currentVotes.length
                      ).toFixed(1)}
                    </span>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>

          {/* Links */}
          <Card>
            <CardHeader>
              <CardTitle>Voting Links</CardTitle>
              <CardDescription>
                Share these links with participants
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-2">
              <Button variant="outline" className="w-full justify-start" asChild>
                <Link href={`/jury/live/${sessionData.id}`} target="_blank">
                  <ExternalLink className="mr-2 h-4 w-4" />
                  Jury Voting Page
                </Link>
              </Button>
              <Button variant="outline" className="w-full justify-start" asChild>
                <Link
                  href={`/live-scores/${sessionData.id}`}
                  target="_blank"
                >
                  <ExternalLink className="mr-2 h-4 w-4" />
                  Public Score Display
                </Link>
              </Button>
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  )
}

function LiveVotingSkeleton() {
  return (
    <div className="space-y-6">
      <Skeleton className="h-9 w-40" />
      <Skeleton className="h-8 w-64" />
      <div className="grid gap-6 lg:grid-cols-3">
        <div className="lg:col-span-2 space-y-6">
          <Skeleton className="h-48 w-full" />
        </div>
        <div>
          <Skeleton className="h-48 w-full" />
        </div>
      </div>
    </div>
  )
}

export default function LiveVotingPage({ params }: PageProps) {
  const { id } = use(params)

  return (
    <Suspense fallback={<LiveVotingSkeleton />}>
      <LiveVotingContent roundId={id} />
    </Suspense>
  )
}
