'use client'

import { use, useState } from 'react'
import { useRouter } from 'next/navigation'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import { Textarea } from '@/components/ui/textarea'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import { toast } from 'sonner'
import {
  ArrowLeft,
  Trophy,
  CheckCircle2,
  Loader2,
  ChevronDown,
  Users,
  Tag,
  Star,
  Gavel,
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { CountryDisplay } from '@/components/shared/country-display'
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from '@/components/ui/collapsible'
import { FileViewer } from '@/components/shared/file-viewer'
import { ProjectLogo } from '@/components/shared/project-logo'

export default function JuryAwardVotingPage({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id: awardId } = use(params)
  const router = useRouter()

  const utils = trpc.useUtils()
  const { data, isLoading, refetch } =
    trpc.specialAward.getMyAwardDetail.useQuery({ awardId })
  const submitVote = trpc.specialAward.submitVote.useMutation({
    onSuccess: () => {
      utils.specialAward.getMyAwardDetail.invalidate({ awardId })
    },
  })
  const confirmWinner = trpc.specialAward.confirmWinner.useMutation({
    onSuccess: () => {
      utils.specialAward.getMyAwardDetail.invalidate({ awardId })
      toast.success('Winner confirmed and award closed')
    },
    onError: (err) => toast.error(err.message),
  })

  const [selectedProjectId, setSelectedProjectId] = useState<string | null>(
    null
  )
  const [rankedIds, setRankedIds] = useState<string[]>([])
  const [justification, setJustification] = useState('')
  const [expandedProjects, setExpandedProjects] = useState<Set<string>>(new Set())

  const toggleExpanded = (projectId: string) => {
    setExpandedProjects((prev) => {
      const next = new Set(prev)
      if (next.has(projectId)) next.delete(projectId)
      else next.add(projectId)
      return next
    })
  }


  // Initialize from existing votes
  if (data && !selectedProjectId && !rankedIds.length && data.myVotes.length > 0) {
    if (data.award.scoringMode === 'PICK_WINNER') {
      setSelectedProjectId(data.myVotes[0]?.projectId || null)
      if (data.myVotes[0]?.justification) {
        setJustification(data.myVotes[0].justification)
      }
    } else if (data.award.scoringMode === 'RANKED') {
      const sorted = [...data.myVotes]
        .sort((a, b) => (a.rank || 0) - (b.rank || 0))
        .map((v) => v.projectId)
      setRankedIds(sorted)
    }
  }

  const handleSubmitPickWinner = async () => {
    if (!selectedProjectId) return
    try {
      await submitVote.mutateAsync({
        awardId,
        votes: [{
          projectId: selectedProjectId,
          justification: justification.trim() || undefined,
        }],
      })
      toast.success('Vote submitted')
      refetch()
    } catch (error) {
      toast.error(
        error instanceof Error ? error.message : 'Failed to submit vote'
      )
    }
  }

  const handleSubmitRanked = async () => {
    if (rankedIds.length === 0) return
    try {
      await submitVote.mutateAsync({
        awardId,
        votes: rankedIds.map((projectId, index) => ({
          projectId,
          rank: index + 1,
        })),
      })
      toast.success('Rankings submitted')
      refetch()
    } catch (error) {
      toast.error(
        error instanceof Error ? error.message : 'Failed to submit rankings'
      )
    }
  }

  const toggleRanked = (projectId: string) => {
    if (rankedIds.includes(projectId)) {
      setRankedIds(rankedIds.filter((id) => id !== projectId))
    } else {
      const maxPicks = data?.award.maxRankedPicks || 5
      if (rankedIds.length < maxPicks) {
        setRankedIds([...rankedIds, projectId])
      }
    }
  }

  if (isLoading) {
    return (
      <div className="space-y-6">
        <Skeleton className="h-9 w-48" />
        <Skeleton className="h-96 w-full" />
      </div>
    )
  }

  if (!data) return null

  const { award, projects, myVotes, isChair, otherVotes, totalJurors } = data
  const hasVoted = myVotes.length > 0
  const isVotingOpen = award.status === 'VOTING_OPEN'
  const isClosed = award.status === 'CLOSED'

  return (
    <div className="space-y-6">
      <div className="flex items-center gap-4">
        <Button variant="ghost" onClick={() => router.back()} className="-ml-4">
          <ArrowLeft className="mr-2 h-4 w-4" />
          Back
        </Button>
      </div>

      <div>
        <h1 className="text-2xl font-semibold tracking-tight flex items-center gap-2">
          <Trophy className="h-6 w-6 text-amber-500" />
          {award.name}
        </h1>
        <div className="flex items-center gap-2 mt-1">
          <Badge
            variant={isVotingOpen ? 'default' : 'secondary'}
          >
            {award.status.replace('_', ' ')}
          </Badge>
          {hasVoted && (
            <Badge variant="outline" className="text-green-600">
              <CheckCircle2 className="mr-1 h-3 w-3" />
              Voted
            </Badge>
          )}
        </div>
        {award.criteriaText && (
          <p className="text-muted-foreground mt-2">{award.criteriaText}</p>
        )}
      </div>

      {!isVotingOpen ? (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12 text-center">
            <Trophy className="h-12 w-12 text-muted-foreground/50" />
            <p className="mt-2 font-medium">Voting is not open</p>
            <p className="text-sm text-muted-foreground">
              Check back when voting opens for this award
            </p>
          </CardContent>
        </Card>
      ) : award.scoringMode === 'PICK_WINNER' ? (
        /* PICK_WINNER Mode */
        <div className="space-y-4">
          <p className="text-sm text-muted-foreground">
            Select one project as the winner. Click the project header to expand details.
          </p>
          <div className="space-y-3">
            {projects.map((project) => (
              <ProjectCard
                key={project.id}
                project={project}
                isSelected={selectedProjectId === project.id}
                isExpanded={expandedProjects.has(project.id)}
                onSelect={() => setSelectedProjectId(project.id)}
                onToggleExpand={() => toggleExpanded(project.id)}
              />
            ))}
          </div>

          {selectedProjectId && (
            <Card>
              <CardHeader className="pb-3">
                <CardTitle className="text-base">Justification (optional)</CardTitle>
                <CardDescription>
                  Visible to the jury chair when they finalize the award.
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Textarea
                  rows={3}
                  maxLength={2000}
                  placeholder="Why this project? (optional)"
                  value={justification}
                  onChange={(e) => setJustification(e.target.value)}
                />
              </CardContent>
            </Card>
          )}

          <div className="flex justify-end">
            <Button
              onClick={handleSubmitPickWinner}
              disabled={!selectedProjectId || submitVote.isPending}
            >
              {submitVote.isPending ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <CheckCircle2 className="mr-2 h-4 w-4" />
              )}
              {hasVoted ? 'Update Vote' : 'Submit Vote'}
            </Button>
          </div>

          {isChair && totalJurors > 1 && (
            <ChairPanel
              award={award}
              projects={projects}
              otherVotes={otherVotes}
              totalJurors={totalJurors}
              hasVoted={hasVoted}
              onConfirm={() => confirmWinner.mutate({ awardId })}
              isPending={confirmWinner.isPending}
            />
          )}
        </div>
      ) : award.scoringMode === 'RANKED' ? (
        /* RANKED Mode */
        <div className="space-y-4">
          <p className="text-sm text-muted-foreground">
            Select and rank your top {award.maxRankedPicks || 5} projects. Click
            to add/remove from your rankings. Expand each project to see full details.
          </p>

          {/* Selected rankings */}
          {rankedIds.length > 0 && (
            <Card>
              <CardHeader className="pb-2">
                <CardTitle className="text-base">Your Rankings ({rankedIds.length}/{award.maxRankedPicks || 5})</CardTitle>
              </CardHeader>
              <CardContent className="space-y-2">
                {rankedIds.map((id, index) => {
                  const project = projects.find((p) => p.id === id)
                  if (!project) return null
                  return (
                    <Collapsible key={id} open={expandedProjects.has(id)}>
                      <div className="flex items-center gap-3 rounded-lg border p-3">
                        <span className="font-bold text-lg w-8 text-center text-brand-blue">
                          {index + 1}
                        </span>
                        <ProjectLogo project={project} logoUrl={project.logoUrl} size="sm" fallback="initials" />
                        <div className="flex-1 min-w-0">
                          <p className="font-medium truncate">{project.title}</p>
                          <p className="text-sm text-muted-foreground">
                            {project.teamName}
                            {project.country && <> &middot; <CountryDisplay country={project.country} /></>}
                          </p>
                        </div>
                        <CollapsibleTrigger asChild>
                          <Button variant="ghost" size="sm" onClick={() => toggleExpanded(id)}>
                            <ChevronDown className={cn('h-4 w-4 transition-transform', expandedProjects.has(id) && 'rotate-180')} />
                          </Button>
                        </CollapsibleTrigger>
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => toggleRanked(id)}
                          className="text-destructive hover:text-destructive"
                        >
                          Remove
                        </Button>
                      </div>
                      <CollapsibleContent>
                        <ProjectDetails project={project} />
                      </CollapsibleContent>
                    </Collapsible>
                  )
                })}
              </CardContent>
            </Card>
          )}

          {/* Available projects */}
          <h3 className="text-sm font-medium text-muted-foreground">Available Projects</h3>
          <div className="space-y-3">
            {projects
              .filter((p) => !rankedIds.includes(p.id))
              .map((project) => (
                <ProjectCard
                  key={project.id}
                  project={project}
                  isExpanded={expandedProjects.has(project.id)}
                  onSelect={() => toggleRanked(project.id)}
                  onToggleExpand={() => toggleExpanded(project.id)}
  
                  selectLabel={rankedIds.length < (award.maxRankedPicks || 5) ? `Add to #${rankedIds.length + 1}` : undefined}
                />
              ))}
          </div>

          <div className="flex justify-end">
            <Button
              onClick={handleSubmitRanked}
              disabled={rankedIds.length === 0 || submitVote.isPending}
            >
              {submitVote.isPending ? (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              ) : (
                <CheckCircle2 className="mr-2 h-4 w-4" />
              )}
              {hasVoted ? 'Update Rankings' : 'Submit Rankings'}
            </Button>
          </div>
        </div>
      ) : (
        /* SCORED Mode — redirect to evaluation */
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12 text-center">
            <Trophy className="h-12 w-12 text-muted-foreground/50" />
            <p className="mt-2 font-medium">Scored Award</p>
            <p className="text-sm text-muted-foreground">
              This award uses the evaluation system. Check your evaluation
              assignments.
            </p>
          </CardContent>
        </Card>
      )}
    </div>
  )
}

/* ── Shared project detail components ── */

type ProjectData = {
  id: string
  title: string
  teamName: string | null
  description: string | null
  competitionCategory: string | null
  country: string | null
  tags: string[]
  logoKey?: string | null
  logoUrl?: string | null
  evaluationScore?: { avg: number; count: number } | null
  files: Array<{
    id: string
    fileName: string
    fileType: string
    mimeType: string
    size: number
    bucket: string
    objectKey: string
    version: number
    isLate: boolean
    pageCount?: number | null
    detectedLang?: string | null
    langConfidence?: number | null
    analyzedAt?: Date | string | null
    createdAt: Date
  }>
  teamMembers: Array<{
    id: string
    role: string
    user: { name: string | null; email: string }
  }>
}

type OtherVote = {
  userId: string
  userName: string | null
  projectId: string
  justification: string | null
}

function ProjectDetails({ project }: { project: ProjectData }) {
  return (
    <div className="px-4 pb-4 pt-2 space-y-4 border-t mt-2">
      {project.evaluationScore && (
        <div className="flex items-center gap-2 rounded-md bg-blue-50/50 px-3 py-2">
          <Star className="h-4 w-4 text-blue-600 shrink-0" />
          <div className="text-sm">
            <span className="font-semibold text-blue-700">
              {project.evaluationScore.avg.toFixed(1)} / 10
            </span>
            <span className="text-muted-foreground ml-2">
              from {project.evaluationScore.count}{' '}
              {project.evaluationScore.count === 1 ? 'evaluation' : 'evaluations'}
            </span>
          </div>
        </div>
      )}

      {project.description && (
        <p className="text-sm text-muted-foreground whitespace-pre-line">{project.description}</p>
      )}

      {project.tags.length > 0 && (
        <div className="flex items-center gap-2 flex-wrap">
          <Tag className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
          {project.tags.map((tag) => (
            <Badge key={tag} variant="secondary" className="text-xs">{tag}</Badge>
          ))}
        </div>
      )}

      {project.teamMembers.length > 0 && (
        <div>
          <div className="flex items-center gap-2 mb-1.5">
            <Users className="h-3.5 w-3.5 text-muted-foreground" />
            <span className="text-xs font-medium text-muted-foreground">Team Members</span>
          </div>
          <div className="flex flex-wrap gap-2">
            {project.teamMembers.map((m) => (
              <Badge key={m.id} variant="outline" className="text-xs">
                {m.user.name || m.user.email}
                {m.role !== 'MEMBER' && ` (${m.role.toLowerCase()})`}
              </Badge>
            ))}
          </div>
        </div>
      )}

      {project.files.length > 0 && (
        <div onClick={(e) => e.stopPropagation()}>
          <FileViewer files={project.files as Parameters<typeof FileViewer>[0]['files']} projectId={project.id} />
        </div>
      )}

      {!project.description && project.tags.length === 0 && project.files.length === 0 && project.teamMembers.length === 0 && (
        <p className="text-sm text-muted-foreground italic">No additional details available</p>
      )}
    </div>
  )
}

function ProjectCard({
  project,
  isSelected,
  isExpanded,
  onSelect,
  onToggleExpand,
  selectLabel,
}: {
  project: ProjectData
  isSelected?: boolean
  isExpanded: boolean
  onSelect: () => void
  onToggleExpand: () => void
  selectLabel?: string
}) {
  return (
    <Card
      className={cn(
        'transition-all',
        isSelected ? 'ring-2 ring-primary bg-primary/5' : ''
      )}
    >
      <div className="flex items-start gap-3 p-4">
        <ProjectLogo project={project} logoUrl={project.logoUrl} size="sm" fallback="initials" />
        <div className="flex-1 min-w-0">
          <button
            onClick={onToggleExpand}
            className="flex items-center gap-2 text-left w-full group"
          >
            <ChevronDown className={cn(
              'h-4 w-4 text-muted-foreground transition-transform shrink-0',
              isExpanded && 'rotate-180'
            )} />
            <div className="min-w-0">
              <h3 className="font-semibold text-sm group-hover:text-brand-blue transition-colors">
                {project.title}
              </h3>
              <p className="text-xs text-muted-foreground mt-0.5">
                {project.teamName}
                {project.country && <> &middot; <CountryDisplay country={project.country} /></>}
              </p>
            </div>
          </button>
          <div className="flex flex-wrap gap-1 mt-2 ml-6">
            {project.competitionCategory && (
              <Badge variant="outline" className="text-xs">
                {project.competitionCategory.replace('_', ' ')}
              </Badge>
            )}
          </div>
        </div>
        <Button
          size="sm"
          variant={isSelected ? 'default' : 'outline'}
          onClick={(e) => { e.stopPropagation(); onSelect() }}
          className="shrink-0"
        >
          {isSelected ? (
            <><CheckCircle2 className="mr-1 h-3.5 w-3.5" /> Selected</>
          ) : (
            selectLabel || 'Select'
          )}
        </Button>
      </div>
      {isExpanded && <ProjectDetails project={project} />}
    </Card>
  )
}

function ChairPanel({
  award,
  projects,
  otherVotes,
  totalJurors,
  hasVoted,
  onConfirm,
  isPending,
}: {
  award: { id: string; status: string }
  projects: ProjectData[]
  otherVotes: OtherVote[]
  totalJurors: number
  hasVoted: boolean
  onConfirm: () => void
  isPending: boolean
}) {
  const projectMap = new Map(projects.map((p) => [p.id, p]))
  const tally = new Map<string, number>()
  for (const v of otherVotes) {
    tally.set(v.projectId, (tally.get(v.projectId) ?? 0) + 1)
  }
  const ranked = Array.from(tally.entries())
    .map(([projectId, votes]) => ({
      project: projectMap.get(projectId),
      votes,
    }))
    .filter((r) => r.project)
    .sort((a, b) => b.votes - a.votes)

  const votedCount = new Set(otherVotes.map((v) => v.userId)).size + (hasVoted ? 1 : 0)
  const isClosed = award.status === 'CLOSED'

  return (
    <Card className="border-amber-200">
      <CardHeader>
        <div className="flex items-center gap-2">
          <Gavel className="h-5 w-5 text-amber-600" />
          <CardTitle className="text-base">Chair tools</CardTitle>
        </div>
        <CardDescription>
          {votedCount} of {totalJurors} jurors have voted. As the chair you
          can review their picks and finalize the award.
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        {ranked.length === 0 ? (
          <p className="text-sm text-muted-foreground italic">
            No other juror votes yet.
          </p>
        ) : (
          <div className="space-y-2">
            <p className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
              Tally so far
            </p>
            {ranked.map(({ project, votes }) => (
              <div key={project!.id} className="flex items-center justify-between rounded-md border px-3 py-2">
                <span className="text-sm font-medium truncate">{project!.title}</span>
                <Badge variant="secondary">{votes} {votes === 1 ? 'vote' : 'votes'}</Badge>
              </div>
            ))}
          </div>
        )}

        {otherVotes.length > 0 && (
          <div className="space-y-2">
            <p className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
              Justifications
            </p>
            {otherVotes.map((v) => {
              const project = projectMap.get(v.projectId)
              return (
                <div key={v.userId} className="rounded-md border p-3">
                  <div className="flex items-center justify-between gap-2">
                    <span className="text-sm font-medium">
                      {v.userName || 'Anonymous juror'}
                    </span>
                    <span className="text-xs text-muted-foreground truncate">
                      → {project?.title || 'Unknown project'}
                    </span>
                  </div>
                  {v.justification && (
                    <p className="text-xs text-muted-foreground mt-2 whitespace-pre-line">
                      {v.justification}
                    </p>
                  )}
                </div>
              )
            })}
          </div>
        )}

        {!isClosed && (
          <div className="flex justify-end pt-2">
            <AlertDialog>
              <AlertDialogTrigger asChild>
                <Button disabled={!hasVoted || isPending}>
                  {isPending ? (
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  ) : (
                    <Trophy className="mr-2 h-4 w-4" />
                  )}
                  Confirm winner & close award
                </Button>
              </AlertDialogTrigger>
              <AlertDialogContent>
                <AlertDialogHeader>
                  <AlertDialogTitle>Finalize the award?</AlertDialogTitle>
                  <AlertDialogDescription>
                    The project with the most votes will be set as the
                    winner. If there&apos;s a tie, your own vote breaks it.
                    Voting will close immediately and this can&apos;t be
                    reopened from this page.
                  </AlertDialogDescription>
                </AlertDialogHeader>
                <AlertDialogFooter>
                  <AlertDialogCancel>Cancel</AlertDialogCancel>
                  <AlertDialogAction onClick={onConfirm}>
                    Confirm
                  </AlertDialogAction>
                </AlertDialogFooter>
              </AlertDialogContent>
            </AlertDialog>
          </div>
        )}

        {!hasVoted && (
          <p className="text-xs text-muted-foreground text-right">
            You must submit your own vote before finalizing.
          </p>
        )}
      </CardContent>
    </Card>
  )
}
