'use client'

import { use, useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import Link from 'next/link'
import type { Route } from 'next'
import { trpc } from '@/lib/trpc/client'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Label } from '@/components/ui/label'
import { Skeleton } from '@/components/ui/skeleton'
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { Checkbox } from '@/components/ui/checkbox'
import { ArrowLeft, Save, Send, AlertCircle, ThumbsUp, ThumbsDown } from 'lucide-react'
import { toast } from 'sonner'
import type { EvaluationConfig } from '@/types/competition-configs'

type PageProps = {
  params: Promise<{ roundId: string; projectId: string }>
}

export default function JuryEvaluatePage({ params: paramsPromise }: PageProps) {
  const params = use(paramsPromise)
  const router = useRouter()
  const { roundId, projectId } = params
  const utils = trpc.useUtils()

  const [showCOIDialog, setShowCOIDialog] = useState(true)
  const [coiAccepted, setCoiAccepted] = useState(false)

  // Evaluation form state
  const [criteriaScores, setCriteriaScores] = useState<Record<string, number>>({})
  const [globalScore, setGlobalScore] = useState('')
  const [binaryDecision, setBinaryDecision] = useState<'accept' | 'reject' | ''>('')
  const [feedbackText, setFeedbackText] = useState('')

  // Fetch project
  const { data: project } = trpc.project.get.useQuery(
    { id: projectId },
    { enabled: !!projectId }
  )

  // Fetch round to get config
  const { data: round } = trpc.round.getById.useQuery(
    { id: roundId },
    { enabled: !!roundId }
  )

  // Fetch assignment to get evaluation
  const { data: assignment } = trpc.roundAssignment.getMyAssignments.useQuery(
    { roundId },
    { enabled: !!roundId }
  )

  const myAssignment = assignment?.find((a) => a.projectId === projectId)

  // Fetch existing evaluation if it exists
  const { data: existingEvaluation } = trpc.evaluation.get.useQuery(
    { assignmentId: myAssignment?.id ?? '' },
    { enabled: !!myAssignment?.id }
  )

  // Start evaluation mutation (creates draft)
  const startMutation = trpc.evaluation.start.useMutation()

  // Autosave mutation
  const autosaveMutation = trpc.evaluation.autosave.useMutation({
    onSuccess: () => {
      toast.success('Draft saved', { duration: 1500 })
    },
    onError: (err) => toast.error(err.message),
  })

  // Submit mutation
  const submitMutation = trpc.evaluation.submit.useMutation({
    onSuccess: () => {
      utils.roundAssignment.getMyAssignments.invalidate()
      utils.evaluation.get.invalidate()
      toast.success('Evaluation submitted successfully')
      router.push(`/jury/competitions/${roundId}` as Route)
    },
    onError: (err) => toast.error(err.message),
  })

  // Load existing evaluation data
  useEffect(() => {
    if (existingEvaluation) {
      if (existingEvaluation.criterionScoresJson) {
        const scores: Record<string, number> = {}
        Object.entries(existingEvaluation.criterionScoresJson).forEach(([key, value]) => {
          scores[key] = typeof value === 'number' ? value : 0
        })
        setCriteriaScores(scores)
      }
      if (existingEvaluation.globalScore) {
        setGlobalScore(existingEvaluation.globalScore.toString())
      }
      if (existingEvaluation.binaryDecision !== null) {
        setBinaryDecision(existingEvaluation.binaryDecision ? 'accept' : 'reject')
      }
      if (existingEvaluation.feedbackText) {
        setFeedbackText(existingEvaluation.feedbackText)
      }
    }
  }, [existingEvaluation])

  // Parse evaluation config from round
  const evalConfig: EvaluationConfig | null = round?.configJson as EvaluationConfig | null
  const scoringMode = evalConfig?.scoringMode ?? 'global'
  const requireFeedback = evalConfig?.requireFeedback ?? true
  const feedbackMinLength = evalConfig?.feedbackMinLength ?? 10

  // Get criteria from evaluation form
  const criteria = existingEvaluation?.form?.criteriaJson as Array<{
    id: string
    label: string
    description?: string
    weight?: number
    minScore?: number
    maxScore?: number
  }> | undefined

  const handleSaveDraft = async () => {
    if (!myAssignment) {
      toast.error('Assignment not found')
      return
    }

    // Create evaluation if it doesn't exist
    let evaluationId = existingEvaluation?.id
    if (!evaluationId) {
      const newEval = await startMutation.mutateAsync({ assignmentId: myAssignment.id })
      evaluationId = newEval.id
    }

    // Autosave current state
    autosaveMutation.mutate({
      id: evaluationId,
      criterionScoresJson: scoringMode === 'criteria' ? criteriaScores : undefined,
      globalScore: scoringMode === 'global' && globalScore ? parseInt(globalScore, 10) : null,
      binaryDecision: scoringMode === 'binary' && binaryDecision ? binaryDecision === 'accept' : null,
      feedbackText: feedbackText || null,
    })
  }

  const handleSubmit = async () => {
    if (!myAssignment) {
      toast.error('Assignment not found')
      return
    }

    // Validation based on scoring mode
    if (scoringMode === 'criteria') {
      if (!criteria || criteria.length === 0) {
        toast.error('No criteria found for this evaluation')
        return
      }
      const requiredCriteria = evalConfig?.requireAllCriteriaScored !== false
      if (requiredCriteria) {
        const allScored = criteria.every((c) => criteriaScores[c.id] !== undefined)
        if (!allScored) {
          toast.error('Please score all criteria')
          return
        }
      }
    }

    if (scoringMode === 'global') {
      const score = parseInt(globalScore, 10)
      if (isNaN(score) || score < 1 || score > 10) {
        toast.error('Please enter a valid score between 1 and 10')
        return
      }
    }

    if (scoringMode === 'binary') {
      if (!binaryDecision) {
        toast.error('Please select accept or reject')
        return
      }
    }

    if (requireFeedback) {
      if (!feedbackText.trim() || feedbackText.length < feedbackMinLength) {
        toast.error(`Please provide feedback (minimum ${feedbackMinLength} characters)`)
        return
      }
    }

    // Create evaluation if needed
    let evaluationId = existingEvaluation?.id
    if (!evaluationId) {
      const newEval = await startMutation.mutateAsync({ assignmentId: myAssignment.id })
      evaluationId = newEval.id
    }

    // Submit
    submitMutation.mutate({
      id: evaluationId,
      criterionScoresJson: scoringMode === 'criteria' ? criteriaScores : {},
      globalScore: scoringMode === 'global' ? parseInt(globalScore, 10) : 5,
      binaryDecision: scoringMode === 'binary' ? binaryDecision === 'accept' : true,
      feedbackText: feedbackText || 'No feedback provided',
    })
  }

  // COI Dialog
  if (!coiAccepted && showCOIDialog && evalConfig?.coiRequired !== false) {
    return (
      <Dialog open={showCOIDialog} onOpenChange={setShowCOIDialog}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Conflict of Interest Declaration</DialogTitle>
            <DialogDescription className="space-y-3 pt-2">
              <p>
                Before evaluating this project, you must confirm that you have no conflict of
                interest.
              </p>
              <p>
                A conflict of interest exists if you have a personal, professional, or financial
                relationship with the project team that could influence your judgment.
              </p>
            </DialogDescription>
          </DialogHeader>
          <div className="flex items-start gap-3 py-4">
            <Checkbox
              id="coi"
              checked={coiAccepted}
              onCheckedChange={(checked) => setCoiAccepted(checked as boolean)}
            />
            <Label htmlFor="coi" className="text-sm leading-relaxed cursor-pointer">
              I confirm that I have no conflict of interest with this project and can provide an
              unbiased evaluation.
            </Label>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => router.push(`/jury/competitions/${roundId}` as Route)}
            >
              Cancel
            </Button>
            <Button
              onClick={() => setShowCOIDialog(false)}
              disabled={!coiAccepted}
              className="bg-brand-blue hover:bg-brand-blue-light"
            >
              Continue to Evaluation
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    )
  }

  if (!round || !project) {
    return (
      <div className="space-y-6">
        <Skeleton className="h-10 w-64" />
        <Card>
          <CardContent className="py-12">
            <div className="flex items-center justify-center">
              <Skeleton className="h-64 w-full" />
            </div>
          </CardContent>
        </Card>
      </div>
    )
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center gap-4">
        <Button variant="ghost" size="sm" asChild>
          <Link href={`/jury/competitions/${roundId}/projects/${projectId}` as Route}>
            <ArrowLeft className="mr-2 h-4 w-4" />
            Back to Project
          </Link>
        </Button>
        <div>
          <h1 className="text-2xl font-bold tracking-tight text-brand-blue dark:text-foreground">
            Evaluate Project
          </h1>
          <p className="text-muted-foreground mt-1">{project.title}</p>
        </div>
      </div>

      <Card className="border-l-4 border-l-amber-500">
        <CardContent className="flex items-start gap-3 p-4">
          <AlertCircle className="h-5 w-5 text-amber-600 shrink-0 mt-0.5" />
          <div className="flex-1">
            <p className="font-medium text-sm">Important Reminder</p>
            <p className="text-sm text-muted-foreground mt-1">
              Your evaluation will be used to assess this project. Please provide thoughtful and
              constructive feedback to help the team improve.
            </p>
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Evaluation Form</CardTitle>
          <CardDescription>
            Provide your assessment using the {scoringMode} scoring method
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-6">
          {/* Criteria-based scoring */}
          {scoringMode === 'criteria' && criteria && criteria.length > 0 && (
            <div className="space-y-4">
              <h3 className="font-semibold">Criteria Scores</h3>
              {criteria.map((criterion) => (
                <div key={criterion.id} className="space-y-2 p-4 border rounded-lg">
                  <Label htmlFor={criterion.id}>
                    {criterion.label}
                    {evalConfig?.requireAllCriteriaScored !== false && (
                      <span className="text-destructive ml-1">*</span>
                    )}
                  </Label>
                  {criterion.description && (
                    <p className="text-xs text-muted-foreground">{criterion.description}</p>
                  )}
                  <Input
                    id={criterion.id}
                    type="number"
                    min={criterion.minScore ?? 0}
                    max={criterion.maxScore ?? 10}
                    value={criteriaScores[criterion.id] ?? ''}
                    onChange={(e) =>
                      setCriteriaScores({
                        ...criteriaScores,
                        [criterion.id]: parseInt(e.target.value, 10) || 0,
                      })
                    }
                    placeholder={`Score (${criterion.minScore ?? 0}-${criterion.maxScore ?? 10})`}
                  />
                </div>
              ))}
            </div>
          )}

          {/* Global scoring */}
          {scoringMode === 'global' && (
            <div className="space-y-2">
              <Label htmlFor="globalScore">
                Overall Score <span className="text-destructive">*</span>
              </Label>
              <Input
                id="globalScore"
                type="number"
                min="1"
                max="10"
                value={globalScore}
                onChange={(e) => setGlobalScore(e.target.value)}
                placeholder="Enter score (1-10)"
              />
              <p className="text-xs text-muted-foreground">
                Provide a score from 1 to 10 based on your overall assessment
              </p>
            </div>
          )}

          {/* Binary decision */}
          {scoringMode === 'binary' && (
            <div className="space-y-2">
              <Label>
                Decision <span className="text-destructive">*</span>
              </Label>
              <RadioGroup value={binaryDecision} onValueChange={(v) => setBinaryDecision(v as 'accept' | 'reject')}>
                <div className="flex items-center space-x-2 p-4 border rounded-lg hover:bg-emerald-50/50">
                  <RadioGroupItem value="accept" id="accept" />
                  <Label htmlFor="accept" className="flex items-center gap-2 cursor-pointer flex-1">
                    <ThumbsUp className="h-4 w-4 text-emerald-600" />
                    <span>Accept — This project should advance</span>
                  </Label>
                </div>
                <div className="flex items-center space-x-2 p-4 border rounded-lg hover:bg-red-50/50">
                  <RadioGroupItem value="reject" id="reject" />
                  <Label htmlFor="reject" className="flex items-center gap-2 cursor-pointer flex-1">
                    <ThumbsDown className="h-4 w-4 text-red-600" />
                    <span>Reject — This project should not advance</span>
                  </Label>
                </div>
              </RadioGroup>
            </div>
          )}

          {/* Feedback */}
          <div className="space-y-2">
            <Label htmlFor="feedbackText">
              Feedback
              {requireFeedback && <span className="text-destructive ml-1">*</span>}
            </Label>
            <Textarea
              id="feedbackText"
              value={feedbackText}
              onChange={(e) => setFeedbackText(e.target.value)}
              placeholder="Provide your feedback on the project..."
              rows={8}
            />
            {requireFeedback && (
              <p className="text-xs text-muted-foreground">
                Minimum {feedbackMinLength} characters ({feedbackText.length}/{feedbackMinLength})
              </p>
            )}
          </div>
        </CardContent>
      </Card>

      <div className="flex items-center justify-between flex-wrap gap-4">
        <Button
          variant="outline"
          onClick={() => router.push(`/jury/competitions/${roundId}/projects/${projectId}` as Route)}
        >
          Cancel
        </Button>
        <div className="flex gap-3">
          <Button
            variant="outline"
            onClick={handleSaveDraft}
            disabled={autosaveMutation.isPending || submitMutation.isPending}
          >
            <Save className="mr-2 h-4 w-4" />
            {autosaveMutation.isPending ? 'Saving...' : 'Save Draft'}
          </Button>
          <Button
            onClick={handleSubmit}
            disabled={submitMutation.isPending || autosaveMutation.isPending}
            className="bg-brand-blue hover:bg-brand-blue-light"
          >
            <Send className="mr-2 h-4 w-4" />
            {submitMutation.isPending ? 'Submitting...' : 'Submit Evaluation'}
          </Button>
        </div>
      </div>
    </div>
  )
}
