'use client'

import { useState, useEffect, useCallback, useTransition, useMemo } from 'react'
import { useRouter } from 'next/navigation'
import { useForm, Controller } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { useDebouncedCallback } from 'use-debounce'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { Slider } from '@/components/ui/slider'
import { Switch } from '@/components/ui/switch'
import { Badge } from '@/components/ui/badge'
import { Progress } from '@/components/ui/progress'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import {
  Loader2,
  Save,
  Send,
  CheckCircle2,
  AlertCircle,
  Clock,
  Star,
  ThumbsUp,
  ThumbsDown,
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { toast } from 'sonner'
import { CountdownTimer } from '@/components/shared/countdown-timer'

// Define criterion type from the evaluation form JSON
type CriterionType = 'numeric' | 'text' | 'boolean' | 'advance' | 'section_header'

interface CriterionCondition {
  criterionId: string
  operator: 'equals' | 'greaterThan' | 'lessThan'
  value: number | string | boolean
}

interface Criterion {
  id: string
  label: string
  description?: string
  type?: CriterionType // defaults to 'numeric'
  // Numeric
  scale?: number // max value (e.g., 5 or 10)
  weight?: number
  required?: boolean
  // Text
  maxLength?: number
  placeholder?: string
  // Boolean
  trueLabel?: string
  falseLabel?: string
  // Conditional visibility
  condition?: CriterionCondition
  // Section grouping
  sectionId?: string
}

interface EvaluationFormProps {
  assignmentId: string
  evaluationId: string | null
  projectTitle: string
  criteria: Criterion[]
  initialData?: {
    criterionScoresJson: Record<string, number | string | boolean> | null
    globalScore: number | null
    binaryDecision: boolean | null
    feedbackText: string | null
    status: string
  }
  isVotingOpen: boolean
  deadline?: Date | null
}

const createEvaluationSchema = (criteria: Criterion[]) => {
  const criterionFields: Record<string, z.ZodTypeAny> = {}
  for (const c of criteria) {
    const type = c.type || 'numeric'
    if (type === 'section_header') continue
    if (type === 'numeric') {
      criterionFields[c.id] = z.number()
    } else if (type === 'text') {
      criterionFields[c.id] = z.string()
    } else if (type === 'boolean' || type === 'advance') {
      criterionFields[c.id] = z.boolean()
    }
  }
  return z.object({
    criterionScores: z.object(criterionFields).passthrough(),
    globalScore: z.number().int().min(1).max(10),
    binaryDecision: z.boolean(),
    feedbackText: z.string().min(10, 'Please provide at least 10 characters of feedback'),
  })
}

type EvaluationFormData = {
  criterionScores: Record<string, number | string | boolean>
  globalScore: number
  binaryDecision: boolean
  feedbackText: string
}

/** Evaluate whether a condition is met based on current form values */
function evaluateCondition(
  condition: CriterionCondition,
  scores: Record<string, number | string | boolean>
): boolean {
  const val = scores[condition.criterionId]
  if (val === undefined) return false
  switch (condition.operator) {
    case 'equals':
      return val === condition.value
    case 'greaterThan':
      return typeof val === 'number' && typeof condition.value === 'number' && val > condition.value
    case 'lessThan':
      return typeof val === 'number' && typeof condition.value === 'number' && val < condition.value
    default:
      return true
  }
}

export function EvaluationForm({
  assignmentId,
  evaluationId,
  projectTitle,
  criteria,
  initialData,
  isVotingOpen,
  deadline,
}: EvaluationFormProps) {
  const router = useRouter()
  const [isPending, startTransition] = useTransition()
  const [autosaveStatus, setAutosaveStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle')
  const [lastSaved, setLastSaved] = useState<Date | null>(null)

  // Progress tracking state
  const [touchedCriteria, setTouchedCriteria] = useState<Set<string>>(() => {
    const initial = new Set<string>()
    if (initialData?.criterionScoresJson) {
      for (const key of Object.keys(initialData.criterionScoresJson)) {
        initial.add(key)
      }
    }
    return initial
  })
  const [globalScoreTouched, setGlobalScoreTouched] = useState(
    () => initialData?.globalScore != null
  )
  const [decisionTouched, setDecisionTouched] = useState(
    () => initialData?.binaryDecision != null
  )

  // Compute which criteria are scorable (not section headers)
  const scorableCriteria = useMemo(
    () => criteria.filter((c) => (c.type || 'numeric') !== 'section_header'),
    [criteria]
  )

  // Initialize criterion scores with existing data or defaults
  const defaultCriterionScores: Record<string, number | string | boolean> = {}
  scorableCriteria.forEach((c) => {
    const type = c.type || 'numeric'
    const existing = initialData?.criterionScoresJson?.[c.id]
    if (type === 'numeric') {
      defaultCriterionScores[c.id] = typeof existing === 'number' ? existing : Math.ceil((c.scale ?? 5) / 2)
    } else if (type === 'text') {
      defaultCriterionScores[c.id] = typeof existing === 'string' ? existing : ''
    } else if (type === 'boolean' || type === 'advance') {
      defaultCriterionScores[c.id] = typeof existing === 'boolean' ? existing : false
    }
  })

  const form = useForm<EvaluationFormData>({
    resolver: zodResolver(createEvaluationSchema(criteria)),
    defaultValues: {
      criterionScores: defaultCriterionScores,
      globalScore: initialData?.globalScore ?? 5,
      binaryDecision: initialData?.binaryDecision ?? false,
      feedbackText: initialData?.feedbackText ?? '',
    },
    mode: 'onChange',
  })

  const { watch, handleSubmit, control, formState } = form
  const { errors, isValid, isDirty } = formState

  // Progress tracking callbacks
  const onCriterionTouch = useCallback((criterionId: string) => {
    setTouchedCriteria((prev) => {
      if (prev.has(criterionId)) return prev
      const next = new Set(prev)
      next.add(criterionId)
      return next
    })
  }, [])

  // Compute progress - section_headers count as always complete (skip them)
  const feedbackValue = watch('feedbackText')
  const watchedScores = watch('criterionScores')
  const progress = useMemo(() => {
    // Only count scorable criteria (not section headers)
    const totalItems = scorableCriteria.length + 3

    // Count completed criteria
    let criteriaDone = 0
    for (const c of scorableCriteria) {
      const type = c.type || 'numeric'
      if (type === 'numeric') {
        if (touchedCriteria.has(c.id)) criteriaDone++
      } else if (type === 'text') {
        const val = watchedScores?.[c.id]
        if (typeof val === 'string' && val.length > 0) criteriaDone++
      } else if (type === 'boolean' || type === 'advance') {
        if (touchedCriteria.has(c.id)) criteriaDone++
      }
    }

    const completedItems =
      criteriaDone +
      (globalScoreTouched ? 1 : 0) +
      (decisionTouched ? 1 : 0) +
      (feedbackValue.length >= 10 ? 1 : 0)
    const percentage = Math.round((completedItems / totalItems) * 100)
    return { totalItems, completedItems, percentage, criteriaDone, criteriaTotal: scorableCriteria.length }
  }, [scorableCriteria, touchedCriteria, watchedScores, globalScoreTouched, decisionTouched, feedbackValue])

  // tRPC mutations
  const startEvaluation = trpc.evaluation.start.useMutation()
  const autosave = trpc.evaluation.autosave.useMutation()
  const submit = trpc.evaluation.submit.useMutation()

  const utils = trpc.useUtils()

  // State to track the current evaluation ID (might be created on first autosave)
  const [currentEvaluationId, setCurrentEvaluationId] = useState<string | null>(evaluationId)

  // Create evaluation if it doesn't exist
  useEffect(() => {
    if (!currentEvaluationId && isVotingOpen) {
      startEvaluation.mutate(
        { assignmentId },
        {
          onSuccess: (data) => {
            setCurrentEvaluationId(data.id)
          },
        }
      )
    }
  }, [assignmentId, currentEvaluationId, isVotingOpen])

  // Debounced autosave function
  const debouncedAutosave = useDebouncedCallback(
    async (data: EvaluationFormData) => {
      if (!currentEvaluationId || !isVotingOpen) return

      setAutosaveStatus('saving')

      try {
        await autosave.mutateAsync({
          id: currentEvaluationId,
          criterionScoresJson: data.criterionScores,
          globalScore: data.globalScore,
          binaryDecision: data.binaryDecision,
          feedbackText: data.feedbackText,
        })

        setAutosaveStatus('saved')
        setLastSaved(new Date())

        // Reset to idle after a few seconds
        setTimeout(() => setAutosaveStatus('idle'), 3000)
      } catch (error) {
        console.error('Autosave failed:', error)
        setAutosaveStatus('error')
      }
    },
    3000 // 3 second debounce
  )

  // Watch form values and trigger autosave
  const watchedValues = watch()

  useEffect(() => {
    if (isDirty && isVotingOpen) {
      debouncedAutosave(watchedValues)
    }
  }, [watchedValues, isDirty, isVotingOpen, debouncedAutosave])

  // Submit handler
  const onSubmit = async (data: EvaluationFormData) => {
    if (!currentEvaluationId) {
      toast.error('Evaluation is still being created. Please wait a moment and try again.')
      return
    }

    try {
      await submit.mutateAsync({
        id: currentEvaluationId,
        criterionScoresJson: data.criterionScores,
        globalScore: data.globalScore,
        binaryDecision: data.binaryDecision,
        feedbackText: data.feedbackText,
      })

      // Invalidate queries and redirect
      utils.assignment.myAssignments.invalidate()

      toast.success('Evaluation submitted successfully!')

      startTransition(() => {
        router.push('/jury/competitions')
        router.refresh()
      })
    } catch (error) {
      console.error('Submit failed:', error)
      toast.error(error instanceof Error ? error.message : 'Failed to submit evaluation. Please try again.')
    }
  }

  const isSubmitted = initialData?.status === 'SUBMITTED' || initialData?.status === 'LOCKED'
  const isReadOnly = isSubmitted || !isVotingOpen

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
      {/* Status bar */}
      <div className="sticky top-0 z-10 -mx-4 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 px-4 py-3 border-b">
        <div className="flex items-center justify-between flex-wrap gap-2">
          <div className="flex items-center gap-3 min-w-0 flex-1">
            <h2 className="font-semibold truncate max-w-[200px] sm:max-w-none">
              {projectTitle}
            </h2>
            {!isReadOnly && deadline && (
              <CountdownTimer deadline={new Date(deadline)} />
            )}
            {!isReadOnly && (
              <ProgressIndicator
                percentage={progress.percentage}
                criteriaDone={progress.criteriaDone}
                criteriaTotal={progress.criteriaTotal}
              />
            )}
            <AutosaveIndicator status={autosaveStatus} lastSaved={lastSaved} />
          </div>

          {!isReadOnly && (
            <div className="flex items-center gap-2">
              <AlertDialog>
                <AlertDialogTrigger asChild>
                  <Button
                    type="button"
                    disabled={!isValid || submit.isPending || startEvaluation.isPending}
                  >
                    {submit.isPending ? (
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    ) : (
                      <Send className="mr-2 h-4 w-4" />
                    )}
                    Submit Evaluation
                  </Button>
                </AlertDialogTrigger>
                <AlertDialogContent>
                  <AlertDialogHeader>
                    <AlertDialogTitle>Submit Evaluation?</AlertDialogTitle>
                    <AlertDialogDescription>
                      Once submitted, you cannot edit your evaluation. Please review
                      your scores and feedback before confirming.
                    </AlertDialogDescription>
                  </AlertDialogHeader>
                  <AlertDialogFooter>
                    <AlertDialogCancel>Cancel</AlertDialogCancel>
                    <AlertDialogAction
                      onClick={handleSubmit(onSubmit)}
                      disabled={submit.isPending}
                    >
                      {submit.isPending ? (
                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      ) : null}
                      Confirm Submit
                    </AlertDialogAction>
                  </AlertDialogFooter>
                </AlertDialogContent>
              </AlertDialog>
            </div>
          )}

          {isReadOnly && (
            <Badge variant="secondary">
              <CheckCircle2 className="mr-1 h-3 w-3" />
              {isSubmitted ? 'Submitted' : 'Read Only'}
            </Badge>
          )}
        </div>
      </div>

      {/* Criteria scoring */}
      {criteria.length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle className="text-lg">Evaluation Criteria</CardTitle>
            <CardDescription>
              Rate the project on each criterion below
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-6">
            {criteria.map((criterion) => {
              const type = criterion.type || 'numeric'

              // Evaluate conditional visibility
              if (criterion.condition) {
                const conditionMet = evaluateCondition(criterion.condition, watchedScores ?? {})
                if (!conditionMet) return null
              }

              // Section header
              if (type === 'section_header') {
                return <SectionHeaderField key={criterion.id} criterion={criterion} />
              }

              // Numeric (default)
              if (type === 'numeric') {
                return (
                  <NumericCriterionField
                    key={criterion.id}
                    criterion={criterion}
                    control={control}
                    disabled={isReadOnly}
                    onTouch={onCriterionTouch}
                  />
                )
              }

              // Text
              if (type === 'text') {
                return (
                  <TextCriterionField
                    key={criterion.id}
                    criterion={criterion}
                    control={control}
                    disabled={isReadOnly}
                    onTouch={onCriterionTouch}
                  />
                )
              }

              // Boolean
              if (type === 'boolean') {
                return (
                  <BooleanCriterionField
                    key={criterion.id}
                    criterion={criterion}
                    control={control}
                    disabled={isReadOnly}
                    onTouch={onCriterionTouch}
                  />
                )
              }

              // Advance (prominent boolean-valued criterion)
              if (type === 'advance') {
                return (
                  <AdvanceCriterionField
                    key={criterion.id}
                    criterion={criterion}
                    control={control}
                    disabled={isReadOnly}
                    onTouch={onCriterionTouch}
                  />
                )
              }

              return null
            })}
          </CardContent>
        </Card>
      )}

      {/* Global score */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Overall Score</CardTitle>
          <CardDescription>
            Rate the project overall on a scale of 1 to 10
          </CardDescription>
        </CardHeader>
        <CardContent>
          <Controller
            name="globalScore"
            control={control}
            render={({ field }) => (
              <div className="space-y-4">
                <div className="flex items-center justify-between">
                  <span className="text-sm text-muted-foreground">Poor</span>
                  <span className="text-4xl font-bold">{field.value}</span>
                  <span className="text-sm text-muted-foreground">Excellent</span>
                </div>
                <Slider
                  min={1}
                  max={10}
                  step={1}
                  value={[field.value]}
                  onValueChange={(v) => {
                    field.onChange(v[0])
                    setGlobalScoreTouched(true)
                  }}
                  disabled={isReadOnly}
                  className="py-4"
                />
                <div className="flex justify-between">
                  {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((num) => (
                    <button
                      key={num}
                      type="button"
                      onClick={() => {
                        if (!isReadOnly) {
                          field.onChange(num)
                          setGlobalScoreTouched(true)
                        }
                      }}
                      disabled={isReadOnly}
                      className={cn(
                        'w-8 h-8 rounded-full text-sm font-medium transition-colors',
                        field.value === num
                          ? 'bg-primary text-primary-foreground'
                          : 'bg-muted hover:bg-muted/80',
                        isReadOnly && 'opacity-50 cursor-not-allowed'
                      )}
                    >
                      {num}
                    </button>
                  ))}
                </div>
              </div>
            )}
          />
        </CardContent>
      </Card>

      {/* Binary decision */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Recommendation</CardTitle>
          <CardDescription>
            Do you recommend this project to advance to the next round?
          </CardDescription>
        </CardHeader>
        <CardContent>
          <Controller
            name="binaryDecision"
            control={control}
            render={({ field }) => (
              <div className="flex gap-4">
                <Button
                  type="button"
                  variant={field.value ? 'default' : 'outline'}
                  className={cn(
                    'flex-1 h-20',
                    field.value && 'bg-green-600 hover:bg-green-700'
                  )}
                  onClick={() => {
                    if (!isReadOnly) {
                      field.onChange(true)
                      setDecisionTouched(true)
                    }
                  }}
                  disabled={isReadOnly}
                >
                  <ThumbsUp className="mr-2 h-6 w-6" />
                  Yes, Recommend
                </Button>
                <Button
                  type="button"
                  variant={!field.value ? 'default' : 'outline'}
                  className={cn(
                    'flex-1 h-20',
                    !field.value && 'bg-red-600 hover:bg-red-700'
                  )}
                  onClick={() => {
                    if (!isReadOnly) {
                      field.onChange(false)
                      setDecisionTouched(true)
                    }
                  }}
                  disabled={isReadOnly}
                >
                  <ThumbsDown className="mr-2 h-6 w-6" />
                  No, Do Not Recommend
                </Button>
              </div>
            )}
          />
        </CardContent>
      </Card>

      {/* Feedback text */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Written Feedback</CardTitle>
          <CardDescription>
            Provide constructive feedback for this project (minimum 10 characters)
          </CardDescription>
        </CardHeader>
        <CardContent>
          <Controller
            name="feedbackText"
            control={control}
            render={({ field }) => (
              <div className="space-y-2">
                <Textarea
                  {...field}
                  placeholder="Share your thoughts on the project's strengths, weaknesses, and potential..."
                  rows={6}
                  maxLength={5000}
                  disabled={isReadOnly}
                  className={cn(
                    errors.feedbackText && 'border-destructive'
                  )}
                />
                <div className="flex items-center justify-between">
                  {errors.feedbackText ? (
                    <p className="text-sm text-destructive">
                      {errors.feedbackText.message}
                    </p>
                  ) : (
                    <p className="text-sm text-muted-foreground">
                      {field.value.length} characters
                    </p>
                  )}
                </div>
              </div>
            )}
          />
        </CardContent>
      </Card>

      {/* Error display */}
      {submit.error && (
        <Card className="border-destructive">
          <CardContent className="flex items-center gap-2 py-4">
            <AlertCircle className="h-5 w-5 text-destructive" />
            <p className="text-sm text-destructive">
              {submit.error.message || 'Failed to submit evaluation. Please try again.'}
            </p>
          </CardContent>
        </Card>
      )}

      {/* Bottom submit button for mobile */}
      {!isReadOnly && (
        <div className="flex flex-col gap-3 pb-safe">
          {/* Autosave Status */}
          <div className="flex items-center justify-end gap-2 text-sm">
            {autosaveStatus === 'saved' && (
              <span className="flex items-center gap-1.5 text-green-600">
                <CheckCircle2 className="h-3.5 w-3.5" />
                All changes saved
              </span>
            )}
            {autosaveStatus === 'saving' && (
              <span className="flex items-center gap-1.5 text-muted-foreground">
                <Loader2 className="h-3.5 w-3.5 animate-spin" />
                Saving...
              </span>
            )}
            {autosaveStatus === 'error' && (
              <span className="flex items-center gap-1.5 text-amber-600">
                <AlertCircle className="h-3.5 w-3.5" />
                Unsaved changes
              </span>
            )}
            {autosaveStatus === 'idle' && isDirty && (
              <span className="flex items-center gap-1.5 text-amber-600">
                <AlertCircle className="h-3.5 w-3.5" />
                Unsaved changes
              </span>
            )}
          </div>
          <div className="flex justify-end">
          <AlertDialog>
            <AlertDialogTrigger asChild>
              <Button
                type="button"
                size="lg"
                disabled={!isValid || submit.isPending || startEvaluation.isPending}
                className="w-full sm:w-auto"
              >
                {submit.isPending ? (
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                ) : (
                  <Send className="mr-2 h-4 w-4" />
                )}
                Submit Evaluation
              </Button>
            </AlertDialogTrigger>
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>Submit Evaluation?</AlertDialogTitle>
                <AlertDialogDescription>
                  Once submitted, you cannot edit your evaluation. Please review
                  your scores and feedback before confirming.
                </AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel>Cancel</AlertDialogCancel>
                <AlertDialogAction
                  onClick={handleSubmit(onSubmit)}
                  disabled={submit.isPending}
                >
                  {submit.isPending ? (
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  ) : null}
                  Confirm Submit
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>
          </div>
        </div>
      )}
    </form>
  )
}

// Section header component (no input)
function SectionHeaderField({ criterion }: { criterion: Criterion }) {
  return (
    <div className="border-b pb-2 pt-4 first:pt-0">
      <h3 className="font-semibold text-lg">{criterion.label}</h3>
      {criterion.description && (
        <p className="text-sm text-muted-foreground mt-1">{criterion.description}</p>
      )}
    </div>
  )
}

// Numeric criterion field component (original behavior)
function NumericCriterionField({
  criterion,
  control,
  disabled,
  onTouch,
}: {
  criterion: Criterion
  control: any
  disabled: boolean
  onTouch: (criterionId: string) => void
}) {
  const scale = criterion.scale ?? 5
  return (
    <Controller
      name={`criterionScores.${criterion.id}`}
      control={control}
      render={({ field }) => (
        <div className="space-y-3">
          <div className="flex items-start justify-between gap-4">
            <div className="space-y-1">
              <Label className="text-base font-medium">{criterion.label}</Label>
              {criterion.description && (
                <p className="text-sm text-muted-foreground">
                  {criterion.description}
                </p>
              )}
            </div>
            <Badge variant="secondary" className="shrink-0">
              {field.value}/{scale}
            </Badge>
          </div>

          <div className="flex items-center gap-2">
            <span className="text-xs text-muted-foreground w-4">1</span>
            <Slider
              min={1}
              max={scale}
              step={1}
              value={[typeof field.value === 'number' ? field.value : Math.ceil(scale / 2)]}
              onValueChange={(v) => {
                field.onChange(v[0])
                onTouch(criterion.id)
              }}
              disabled={disabled}
              className="flex-1"
            />
            <span className="text-xs text-muted-foreground w-4">{scale}</span>
          </div>

          {/* Visual rating buttons */}
          <div className="flex gap-1 flex-wrap">
            {Array.from({ length: scale }, (_, i) => i + 1).map((num) => (
              <button
                key={num}
                type="button"
                onClick={() => {
                  if (!disabled) {
                    field.onChange(num)
                    onTouch(criterion.id)
                  }
                }}
                disabled={disabled}
                className={cn(
                  'w-9 h-9 rounded-md text-sm font-medium transition-colors',
                  field.value === num
                    ? 'bg-primary text-primary-foreground'
                    : field.value > num
                      ? 'bg-primary/20 text-primary'
                      : 'bg-muted hover:bg-muted/80',
                  disabled && 'opacity-50 cursor-not-allowed'
                )}
              >
                {num}
              </button>
            ))}
          </div>
        </div>
      )}
    />
  )
}

// Text criterion field component
function TextCriterionField({
  criterion,
  control,
  disabled,
  onTouch,
}: {
  criterion: Criterion
  control: any
  disabled: boolean
  onTouch: (criterionId: string) => void
}) {
  return (
    <Controller
      name={`criterionScores.${criterion.id}`}
      control={control}
      render={({ field }) => (
        <div className="space-y-3">
          <div className="space-y-1">
            <div className="flex items-center gap-2">
              <Label className="text-base font-medium">{criterion.label}</Label>
              {criterion.required && (
                <Badge variant="destructive" className="text-xs">Required</Badge>
              )}
            </div>
            {criterion.description && (
              <p className="text-sm text-muted-foreground">
                {criterion.description}
              </p>
            )}
          </div>
          <Textarea
            value={typeof field.value === 'string' ? field.value : ''}
            onChange={(e) => {
              field.onChange(e.target.value)
              onTouch(criterion.id)
            }}
            placeholder={criterion.placeholder || 'Enter your response...'}
            rows={3}
            maxLength={criterion.maxLength ?? 1000}
            disabled={disabled}
          />
          <p className="text-xs text-muted-foreground">
            {typeof field.value === 'string' ? field.value.length : 0}
            {criterion.maxLength ? ` / ${criterion.maxLength}` : ''} characters
          </p>
        </div>
      )}
    />
  )
}

// Boolean criterion field component
function BooleanCriterionField({
  criterion,
  control,
  disabled,
  onTouch,
}: {
  criterion: Criterion
  control: any
  disabled: boolean
  onTouch: (criterionId: string) => void
}) {
  const trueLabel = criterion.trueLabel || 'Yes'
  const falseLabel = criterion.falseLabel || 'No'

  return (
    <Controller
      name={`criterionScores.${criterion.id}`}
      control={control}
      render={({ field }) => (
        <div className="space-y-3">
          <div className="space-y-1">
            <div className="flex items-center gap-2">
              <Label className="text-base font-medium">{criterion.label}</Label>
              {criterion.required && (
                <Badge variant="destructive" className="text-xs">Required</Badge>
              )}
            </div>
            {criterion.description && (
              <p className="text-sm text-muted-foreground">
                {criterion.description}
              </p>
            )}
          </div>
          <div className="flex gap-3">
            <Button
              type="button"
              variant={field.value === true ? 'default' : 'outline'}
              className={cn(
                'flex-1 h-12',
                field.value === true && 'bg-green-600 hover:bg-green-700'
              )}
              onClick={() => {
                if (!disabled) {
                  field.onChange(true)
                  onTouch(criterion.id)
                }
              }}
              disabled={disabled}
            >
              <ThumbsUp className="mr-2 h-4 w-4" />
              {trueLabel}
            </Button>
            <Button
              type="button"
              variant={field.value === false ? 'default' : 'outline'}
              className={cn(
                'flex-1 h-12',
                field.value === false && 'bg-red-600 hover:bg-red-700'
              )}
              onClick={() => {
                if (!disabled) {
                  field.onChange(false)
                  onTouch(criterion.id)
                }
              }}
              disabled={disabled}
            >
              <ThumbsDown className="mr-2 h-4 w-4" />
              {falseLabel}
            </Button>
          </div>
        </div>
      )}
    />
  )
}

// Advance criterion field component (prominent boolean — "should this project advance?")
function AdvanceCriterionField({
  criterion,
  control,
  disabled,
  onTouch,
}: {
  criterion: Criterion
  control: any
  disabled: boolean
  onTouch: (criterionId: string) => void
}) {
  const trueLabel = criterion.trueLabel || 'Yes'
  const falseLabel = criterion.falseLabel || 'No'

  return (
    <Controller
      name={`criterionScores.${criterion.id}`}
      control={control}
      render={({ field }) => (
        <div className="space-y-3 p-5 border-2 border-brand-blue/30 rounded-xl bg-brand-blue/5">
          <div className="space-y-1">
            <div className="flex items-center gap-2">
              <Label className="text-base font-semibold text-brand-blue">{criterion.label}</Label>
              {criterion.required && (
                <Badge variant="destructive" className="text-xs">Required</Badge>
              )}
            </div>
            {criterion.description && (
              <p className="text-sm text-muted-foreground">
                {criterion.description}
              </p>
            )}
          </div>
          <div className="flex gap-4">
            <Button
              type="button"
              variant={field.value === true ? 'default' : 'outline'}
              className={cn(
                'flex-1 h-14 rounded-xl border-2 text-base font-semibold transition-all',
                field.value === true
                  ? 'border-emerald-500 bg-emerald-50 text-emerald-700 shadow-sm ring-2 ring-emerald-200 hover:bg-emerald-100'
                  : 'border-border hover:border-emerald-300 hover:bg-emerald-50/50'
              )}
              onClick={() => {
                if (!disabled) {
                  field.onChange(true)
                  onTouch(criterion.id)
                }
              }}
              disabled={disabled}
            >
              <ThumbsUp className="mr-2 h-5 w-5" />
              {trueLabel}
            </Button>
            <Button
              type="button"
              variant={field.value === false ? 'default' : 'outline'}
              className={cn(
                'flex-1 h-14 rounded-xl border-2 text-base font-semibold transition-all',
                field.value === false
                  ? 'border-red-500 bg-red-50 text-red-700 shadow-sm ring-2 ring-red-200 hover:bg-red-100'
                  : 'border-border hover:border-red-300 hover:bg-red-50/50'
              )}
              onClick={() => {
                if (!disabled) {
                  field.onChange(false)
                  onTouch(criterion.id)
                }
              }}
              disabled={disabled}
            >
              <ThumbsDown className="mr-2 h-5 w-5" />
              {falseLabel}
            </Button>
          </div>
        </div>
      )}
    />
  )
}

// Progress indicator component
function ProgressIndicator({
  percentage,
  criteriaDone,
  criteriaTotal,
}: {
  percentage: number
  criteriaDone: number
  criteriaTotal: number
}) {
  return (
    <div className="flex items-center gap-2 shrink-0">
      <Progress value={percentage} className="w-16 sm:w-24 h-2" />
      <span className="text-xs text-muted-foreground whitespace-nowrap">
        <span className="sm:hidden">{percentage}%</span>
        <span className="hidden sm:inline">
          {criteriaDone} of {criteriaTotal} criteria scored &middot; {percentage}%
        </span>
      </span>
    </div>
  )
}

// Autosave indicator component
function AutosaveIndicator({
  status,
  lastSaved,
}: {
  status: 'idle' | 'saving' | 'saved' | 'error'
  lastSaved: Date | null
}) {
  if (status === 'idle' && lastSaved) {
    return (
      <span className="text-xs text-muted-foreground hidden sm:inline">
        Saved
      </span>
    )
  }

  if (status === 'saving') {
    return (
      <span className="flex items-center gap-1 text-xs text-muted-foreground">
        <Loader2 className="h-3 w-3 animate-spin" />
        <span className="hidden sm:inline">Saving...</span>
      </span>
    )
  }

  if (status === 'saved') {
    return (
      <span className="flex items-center gap-1 text-xs text-green-600">
        <CheckCircle2 className="h-3 w-3" />
        <span className="hidden sm:inline">Saved</span>
      </span>
    )
  }

  if (status === 'error') {
    return (
      <span className="flex items-center gap-1 text-xs text-destructive">
        <AlertCircle className="h-3 w-3" />
        <span className="hidden sm:inline">Save failed</span>
      </span>
    )
  }

  return null
}
