'use client'

import { use, useState, useEffect, useCallback } from 'react'
import { trpc } from '@/lib/trpc/client'
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 {
  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 {
  Clock,
  CheckCircle,
  AlertCircle,
  Users,
  Wifi,
  WifiOff,
  Vote,
} from 'lucide-react'
import { useLiveVotingSSE } from '@/hooks/use-live-voting-sse'

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

const SCORE_OPTIONS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

const TOKEN_KEY = 'mopc_audience_token_'

function AudienceVotingContent({ sessionId }: { sessionId: string }) {
  const [token, setToken] = useState<string | null>(null)
  const [identifier, setIdentifier] = useState('')
  const [selectedScore, setSelectedScore] = useState<number | null>(null)
  const [countdown, setCountdown] = useState<number | null>(null)
  const [hasVotedForProject, setHasVotedForProject] = useState(false)

  // Check for saved token on mount
  useEffect(() => {
    const saved = localStorage.getItem(TOKEN_KEY + sessionId)
    if (saved) {
      setToken(saved)
    }
  }, [sessionId])

  // Fetch session data
  const { data, isLoading, refetch } = trpc.liveVoting.getAudienceSession.useQuery(
    { sessionId },
    { refetchInterval: 5000 }
  )

  // SSE for real-time updates
  const onSessionStatus = useCallback(() => {
    refetch()
  }, [refetch])

  const onProjectChange = useCallback(() => {
    setSelectedScore(null)
    setHasVotedForProject(false)
    setCountdown(null)
    refetch()
  }, [refetch])

  const { isConnected } = useLiveVotingSSE(sessionId, {
    onSessionStatus,
    onProjectChange,
  })

  // Register mutation
  const register = trpc.liveVoting.registerAudienceVoter.useMutation({
    onSuccess: (result) => {
      setToken(result.token)
      localStorage.setItem(TOKEN_KEY + sessionId, result.token)
      toast.success('Registered! You can now vote.')
    },
    onError: (error) => {
      toast.error(error.message)
    },
  })

  // Vote mutation
  const castVote = trpc.liveVoting.castAudienceVote.useMutation({
    onSuccess: () => {
      toast.success('Vote recorded!')
      setHasVotedForProject(true)
    },
    onError: (error) => {
      toast.error(error.message)
    },
  })

  // Update countdown
  useEffect(() => {
    if (data?.timeRemaining !== null && data?.timeRemaining !== undefined) {
      setCountdown(data.timeRemaining)
    } else {
      setCountdown(null)
    }
  }, [data?.timeRemaining])

  // Countdown timer
  useEffect(() => {
    if (countdown === null || countdown <= 0) return

    const interval = setInterval(() => {
      setCountdown((prev) => {
        if (prev === null || prev <= 0) return 0
        return prev - 1
      })
    }, 1000)

    return () => clearInterval(interval)
  }, [countdown])

  // Reset vote state when project changes
  useEffect(() => {
    setSelectedScore(null)
    setHasVotedForProject(false)
  }, [data?.currentProject?.id])

  const handleRegister = () => {
    register.mutate({
      sessionId,
      identifier: identifier.trim() || undefined,
      identifierType: identifier.includes('@')
        ? 'email'
        : identifier.trim()
          ? 'name'
          : 'anonymous',
    })
  }

  const handleVote = (score: number) => {
    if (!token || !data?.currentProject) return
    setSelectedScore(score)
    castVote.mutate({
      sessionId,
      projectId: data.currentProject.id,
      score,
      token,
    })
  }

  if (isLoading) {
    return <AudienceVotingSkeleton />
  }

  if (!data) {
    return (
      <div className="flex items-center justify-center min-h-[60vh]">
        <Alert variant="destructive" className="max-w-md">
          <AlertCircle className="h-4 w-4" />
          <AlertTitle>Session Not Found</AlertTitle>
          <AlertDescription>
            This voting session does not exist or has ended.
          </AlertDescription>
        </Alert>
      </div>
    )
  }

  if (!data.session.allowAudienceVotes) {
    return (
      <div className="flex items-center justify-center min-h-[60vh]">
        <Card className="max-w-md w-full">
          <CardContent className="py-12 text-center">
            <Users className="h-16 w-16 text-muted-foreground mx-auto mb-4" />
            <h2 className="text-xl font-semibold mb-2">Audience Voting Not Available</h2>
            <p className="text-muted-foreground">
              Audience voting is not enabled for this session.
            </p>
          </CardContent>
        </Card>
      </div>
    )
  }

  // Registration step
  if (!token) {
    return (
      <div className="flex items-center justify-center min-h-[60vh]">
        <Card className="max-w-md w-full">
          <CardHeader className="text-center">
            <div className="flex items-center justify-center gap-2 mb-2">
              <Vote className="h-6 w-6 text-primary" />
              <CardTitle>Audience Voting</CardTitle>
            </div>
            <CardDescription>
              {data.session.round?.competition.program.name} - {data.session.round?.name}
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <p className="text-center text-muted-foreground">
              Register to participate in audience voting
            </p>

            {data.session.audienceRequireId && (
              <div className="space-y-2">
                <Label htmlFor="identifier">Your Email or Name</Label>
                <Input
                  id="identifier"
                  placeholder="email@example.com or your name"
                  value={identifier}
                  onChange={(e) => setIdentifier(e.target.value)}
                />
                <p className="text-xs text-muted-foreground">
                  Required for audience voting verification
                </p>
              </div>
            )}

            {!data.session.audienceRequireId && (
              <div className="space-y-2">
                <Label htmlFor="identifier">Your Name (optional)</Label>
                <Input
                  id="identifier"
                  placeholder="Enter your name (optional)"
                  value={identifier}
                  onChange={(e) => setIdentifier(e.target.value)}
                />
              </div>
            )}

            <Button
              className="w-full"
              onClick={handleRegister}
              disabled={
                register.isPending ||
                (data.session.audienceRequireId && !identifier.trim())
              }
            >
              {register.isPending ? 'Registering...' : 'Join Voting'}
            </Button>
          </CardContent>
        </Card>
      </div>
    )
  }

  // Voting UI
  const isVoting = data.session.status === 'IN_PROGRESS'

  return (
    <div className="max-w-md mx-auto space-y-6">
      <Card>
        <CardHeader className="text-center">
          <div className="flex items-center justify-center gap-2 mb-2">
            <Vote className="h-6 w-6 text-primary" />
            <CardTitle>Audience Voting</CardTitle>
          </div>
          <CardDescription>
            {data.session.round?.competition.program.name} - {data.session.round?.name}
          </CardDescription>
        </CardHeader>

        <CardContent className="space-y-6">
          {isVoting && data.currentProject ? (
            <>
              {/* Current project */}
              <div className="text-center space-y-2">
                <Badge variant="default" className="mb-2">
                  Now Presenting
                </Badge>
                <h2 className="text-xl font-semibold">
                  {data.currentProject.title}
                </h2>
                {data.currentProject.teamName && (
                  <p className="text-muted-foreground">
                    {data.currentProject.teamName}
                  </p>
                )}
              </div>

              {/* Timer */}
              <div className="text-center">
                <div className="text-4xl font-bold text-primary mb-2">
                  {countdown !== null ? `${countdown}s` : '--'}
                </div>
                <Progress
                  value={countdown !== null ? (countdown / 30) * 100 : 0}
                  className="h-2"
                />
                <p className="text-sm text-muted-foreground mt-1">
                  Time remaining to vote
                </p>
              </div>

              {/* Score buttons */}
              <div className="space-y-2">
                <p className="text-sm font-medium text-center">Your Score</p>
                <div className="grid grid-cols-5 gap-2">
                  {SCORE_OPTIONS.map((score) => (
                    <Button
                      key={score}
                      variant={selectedScore === score ? 'default' : 'outline'}
                      size="lg"
                      className="h-14 text-xl font-bold"
                      onClick={() => handleVote(score)}
                      disabled={castVote.isPending || countdown === 0}
                    >
                      {score}
                    </Button>
                  ))}
                </div>
                <p className="text-xs text-muted-foreground text-center">
                  1 = Low, 10 = Excellent
                </p>
              </div>

              {/* Vote status */}
              {hasVotedForProject && (
                <Alert className="bg-green-500/10 border-green-500">
                  <CheckCircle className="h-4 w-4 text-green-500" />
                  <AlertDescription>
                    Your vote has been recorded! You can change it before time runs out.
                  </AlertDescription>
                </Alert>
              )}
            </>
          ) : (
            /* Waiting state */
            <div className="text-center py-12">
              <Clock className="h-16 w-16 text-muted-foreground mx-auto mb-4 animate-pulse" />
              <h2 className="text-xl font-semibold mb-2">
                Waiting for Next Project
              </h2>
              <p className="text-muted-foreground">
                {data.session.status === 'COMPLETED'
                  ? 'The voting session has ended. Thank you for participating!'
                  : 'Voting will begin when the next project is presented.'}
              </p>
              {data.session.status !== 'COMPLETED' && (
                <p className="text-sm text-muted-foreground mt-4">
                  This page will update automatically.
                </p>
              )}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Connection status */}
      <div className="flex items-center justify-center gap-2">
        {isConnected ? (
          <Wifi className="h-3 w-3 text-green-500" />
        ) : (
          <WifiOff className="h-3 w-3 text-red-500" />
        )}
        <p className="text-muted-foreground text-sm">
          {isConnected ? 'Connected' : 'Reconnecting...'}
        </p>
      </div>
    </div>
  )
}

function AudienceVotingSkeleton() {
  return (
    <div className="max-w-md mx-auto">
      <Card>
        <CardHeader className="text-center">
          <Skeleton className="h-6 w-40 mx-auto" />
          <Skeleton className="h-4 w-56 mx-auto mt-2" />
        </CardHeader>
        <CardContent className="space-y-6">
          <Skeleton className="h-20 w-full" />
          <Skeleton className="h-12 w-full" />
          <div className="grid grid-cols-5 gap-2">
            {[...Array(10)].map((_, i) => (
              <Skeleton key={i} className="h-14 w-full" />
            ))}
          </div>
        </CardContent>
      </Card>
    </div>
  )
}

export default function AudienceVotingPage({ params }: PageProps) {
  const { sessionId } = use(params)

  return <AudienceVotingContent sessionId={sessionId} />
}
