'use client'

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Slider } from '@/components/ui/slider'
import { Textarea } from '@/components/ui/textarea'
import { Label } from '@/components/ui/label'
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import { cn } from '@/lib/utils'
import { ThumbsUp, ThumbsDown, CheckCircle2 } from 'lucide-react'

export type EvaluationCriterion = {
  id: string
  label: string
  description?: string | null
  type: 'numeric' | 'text' | 'boolean' | 'advance' | 'section_header'
  weight?: number | null
  minScore: number
  maxScore: number
  required: boolean
  trueLabel: string
  falseLabel: string
  maxLength: number
  placeholder: string
}

export type ScoringMode = 'criteria' | 'global' | 'binary'

export type EvaluationFormFieldsProps = {
  criteria: EvaluationCriterion[]
  scoringMode: ScoringMode
  requireFeedback: boolean
  feedbackMinLength: number
  criteriaValues: Record<string, number | boolean | string>
  globalScore: string
  binaryDecision: '' | 'accept' | 'reject'
  feedbackText: string
  isReadOnly: boolean
  lastSavedAt?: Date | null
  headerDescription?: string
  onCriterionChange: (key: string, value: number | boolean | string) => void
  onGlobalScoreChange: (value: string) => void
  onBinaryChange: (value: 'accept' | 'reject') => void
  onFeedbackChange: (value: string) => void
}

/**
 * Parse an EvaluationForm.criteriaJson payload into typed criteria for display.
 * Kept in this file so every consumer normalizes in the same way.
 */
export function parseCriteriaFromForm(
  criteriaJson: ReadonlyArray<Record<string, unknown>> | null | undefined,
): EvaluationCriterion[] {
  if (!criteriaJson) return []
  return criteriaJson.map((raw) => {
    const c = raw as Record<string, unknown>
    const type = (c.type as EvaluationCriterion['type']) || 'numeric'
    let minScore = 1
    let maxScore = 10
    if (type === 'numeric' && typeof c.scale === 'string') {
      const parts = c.scale.split('-').map(Number)
      if (parts.length === 2 && !Number.isNaN(parts[0]) && !Number.isNaN(parts[1])) {
        minScore = parts[0]
        maxScore = parts[1]
      }
    }
    return {
      id: c.id as string,
      label: c.label as string,
      description: (c.description as string | null | undefined) ?? null,
      type,
      weight: (c.weight as number | null | undefined) ?? null,
      minScore,
      maxScore,
      required: (c.required as boolean | undefined) ?? true,
      trueLabel: (c.trueLabel as string | undefined) || 'Yes',
      falseLabel: (c.falseLabel as string | undefined) || 'No',
      maxLength: (c.maxLength as number | undefined) || 1000,
      placeholder: (c.placeholder as string | undefined) || '',
    }
  })
}

export function EvaluationFormFields({
  criteria,
  scoringMode,
  requireFeedback,
  feedbackMinLength,
  criteriaValues,
  globalScore,
  binaryDecision,
  feedbackText,
  isReadOnly,
  lastSavedAt,
  headerDescription,
  onCriterionChange,
  onGlobalScoreChange,
  onBinaryChange,
  onFeedbackChange,
}: EvaluationFormFieldsProps) {
  const description =
    headerDescription ??
    (scoringMode === 'criteria'
      ? 'Complete all required fields below'
      : `Provide your assessment using the ${scoringMode} scoring method`)

  return (
    <Card>
      <CardHeader>
        <div className="flex items-start justify-between">
          <div>
            <CardTitle>Evaluation Form</CardTitle>
            <CardDescription>{description}</CardDescription>
          </div>
          {lastSavedAt && (
            <span className="text-xs text-muted-foreground flex items-center gap-1">
              <CheckCircle2 className="h-3 w-3 text-emerald-500" />
              Saved {lastSavedAt.toLocaleTimeString()}
            </span>
          )}
        </div>
      </CardHeader>
      <CardContent className="space-y-6">
        {scoringMode === 'criteria' && criteria.length > 0 && (
          <div className="space-y-4">
            {criteria.map((criterion) => {
              if (criterion.type === 'section_header') {
                return (
                  <div key={criterion.id} 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>
                )
              }

              if (criterion.type === 'advance') {
                const currentValue = criteriaValues[criterion.id]
                return (
                  <div
                    key={criterion.id}
                    className="space-y-3 p-5 border-2 border-brand-blue/30 rounded-xl bg-brand-blue/5"
                  >
                    <div className="space-y-1">
                      <Label className="text-base font-semibold text-brand-blue">
                        {criterion.label}
                        <span className="text-destructive ml-1">*</span>
                      </Label>
                      {criterion.description && (
                        <p className="text-sm text-muted-foreground">{criterion.description}</p>
                      )}
                    </div>
                    <div className="flex gap-4">
                      <button
                        type="button"
                        disabled={isReadOnly}
                        onClick={() => onCriterionChange(criterion.id, true)}
                        className={cn(
                          'flex-1 h-14 rounded-xl border-2 flex items-center justify-center text-base font-semibold transition-all',
                          currentValue === true
                            ? 'border-emerald-500 bg-emerald-50 text-emerald-700 shadow-sm ring-2 ring-emerald-200'
                            : 'border-border hover:border-emerald-300 hover:bg-emerald-50/50',
                          isReadOnly && 'opacity-60 cursor-default',
                        )}
                      >
                        <ThumbsUp className="mr-2 h-5 w-5" />
                        {criterion.trueLabel || 'Yes'}
                      </button>
                      <button
                        type="button"
                        disabled={isReadOnly}
                        onClick={() => onCriterionChange(criterion.id, false)}
                        className={cn(
                          'flex-1 h-14 rounded-xl border-2 flex items-center justify-center text-base font-semibold transition-all',
                          currentValue === false
                            ? 'border-red-500 bg-red-50 text-red-700 shadow-sm ring-2 ring-red-200'
                            : 'border-border hover:border-red-300 hover:bg-red-50/50',
                          isReadOnly && 'opacity-60 cursor-default',
                        )}
                      >
                        <ThumbsDown className="mr-2 h-5 w-5" />
                        {criterion.falseLabel || 'No'}
                      </button>
                    </div>
                  </div>
                )
              }

              if (criterion.type === 'boolean') {
                const currentValue = criteriaValues[criterion.id]
                return (
                  <div key={criterion.id} className="space-y-3 p-4 border rounded-lg">
                    <div className="space-y-1">
                      <Label className="text-base font-medium">
                        {criterion.label}
                        {criterion.required && <span className="text-destructive ml-1">*</span>}
                      </Label>
                      {criterion.description && (
                        <p className="text-sm text-muted-foreground">{criterion.description}</p>
                      )}
                    </div>
                    <div className="flex gap-3">
                      <button
                        type="button"
                        disabled={isReadOnly}
                        onClick={() => onCriterionChange(criterion.id, true)}
                        className={cn(
                          'flex-1 h-12 rounded-lg border-2 flex items-center justify-center text-sm font-medium transition-all',
                          currentValue === true
                            ? 'border-emerald-500 bg-emerald-50 text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-400'
                            : 'border-border hover:border-emerald-300 hover:bg-emerald-50/50',
                          isReadOnly && 'opacity-60 cursor-default',
                        )}
                      >
                        <ThumbsUp className="mr-2 h-4 w-4" />
                        {criterion.trueLabel}
                      </button>
                      <button
                        type="button"
                        disabled={isReadOnly}
                        onClick={() => onCriterionChange(criterion.id, false)}
                        className={cn(
                          'flex-1 h-12 rounded-lg border-2 flex items-center justify-center text-sm font-medium transition-all',
                          currentValue === false
                            ? 'border-red-500 bg-red-50 text-red-700 dark:bg-red-950/40 dark:text-red-400'
                            : 'border-border hover:border-red-300 hover:bg-red-50/50',
                          isReadOnly && 'opacity-60 cursor-default',
                        )}
                      >
                        <ThumbsDown className="mr-2 h-4 w-4" />
                        {criterion.falseLabel}
                      </button>
                    </div>
                  </div>
                )
              }

              if (criterion.type === 'text') {
                const currentValue = (criteriaValues[criterion.id] as string) || ''
                return (
                  <div key={criterion.id} className="space-y-3 p-4 border rounded-lg">
                    <div className="space-y-1">
                      <Label className="text-base font-medium">
                        {criterion.label}
                        {criterion.required && <span className="text-destructive ml-1">*</span>}
                      </Label>
                      {criterion.description && (
                        <p className="text-sm text-muted-foreground">{criterion.description}</p>
                      )}
                    </div>
                    <Textarea
                      value={currentValue}
                      onChange={(e) => onCriterionChange(criterion.id, e.target.value)}
                      placeholder={criterion.placeholder || 'Enter your response...'}
                      rows={4}
                      maxLength={criterion.maxLength}
                      disabled={isReadOnly}
                    />
                    <p className="text-xs text-muted-foreground text-right">
                      {currentValue.length}/{criterion.maxLength}
                    </p>
                  </div>
                )
              }

              // Default: numeric criterion
              const min = criterion.minScore ?? 1
              const max = criterion.maxScore ?? 10
              const currentValue = criteriaValues[criterion.id]
              const displayValue = typeof currentValue === 'number' ? currentValue : undefined
              const sliderValue =
                typeof currentValue === 'number' ? currentValue : Math.ceil((min + max) / 2)

              return (
                <div key={criterion.id} className="space-y-3 p-4 border rounded-lg">
                  <div className="flex items-start justify-between gap-4">
                    <div className="space-y-1">
                      <Label className="text-base font-medium">
                        {criterion.label}
                        {criterion.required && <span className="text-destructive ml-1">*</span>}
                      </Label>
                      {criterion.description && (
                        <p className="text-sm text-muted-foreground">{criterion.description}</p>
                      )}
                    </div>
                    <span className="shrink-0 rounded-md bg-muted px-2.5 py-1 text-sm font-bold tabular-nums">
                      {displayValue !== undefined ? displayValue : '—'}/{max}
                    </span>
                  </div>

                  <div className="flex items-center gap-2">
                    <span className="text-xs text-muted-foreground w-4">{min}</span>
                    <Slider
                      min={min}
                      max={max}
                      step={1}
                      value={[sliderValue]}
                      onValueChange={(v) => onCriterionChange(criterion.id, v[0])}
                      className="flex-1"
                      disabled={isReadOnly}
                    />
                    <span className="text-xs text-muted-foreground w-4">{max}</span>
                  </div>

                  <div className="flex gap-1 flex-wrap">
                    {Array.from({ length: max - min + 1 }, (_, i) => i + min).map((num) => (
                      <button
                        key={num}
                        type="button"
                        disabled={isReadOnly}
                        onClick={() => onCriterionChange(criterion.id, num)}
                        className={cn(
                          'w-9 h-9 rounded-md text-sm font-medium transition-colors',
                          displayValue !== undefined && displayValue === num
                            ? 'bg-primary text-primary-foreground'
                            : displayValue !== undefined && displayValue > num
                              ? 'bg-primary/20 text-primary'
                              : 'bg-muted hover:bg-muted/80',
                          isReadOnly && 'cursor-default',
                        )}
                      >
                        {num}
                      </button>
                    ))}
                  </div>
                </div>
              )
            })}
          </div>
        )}

        {scoringMode === 'global' && (
          <div className="space-y-3">
            <div className="flex items-center justify-between">
              <Label>
                Overall Score <span className="text-destructive">*</span>
              </Label>
              <span className="rounded-md bg-muted px-2.5 py-1 text-sm font-bold tabular-nums">
                {globalScore || '—'}/10
              </span>
            </div>
            <div className="flex items-center gap-2">
              <span className="text-xs text-muted-foreground">1</span>
              <Slider
                min={1}
                max={10}
                step={1}
                value={[globalScore ? parseInt(globalScore, 10) : 5]}
                onValueChange={(v) => onGlobalScoreChange(v[0].toString())}
                className="flex-1"
                disabled={isReadOnly}
              />
              <span className="text-xs text-muted-foreground">10</span>
            </div>
            <div className="flex gap-1 flex-wrap">
              {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((num) => {
                const current = globalScore ? parseInt(globalScore, 10) : 0
                return (
                  <button
                    key={num}
                    type="button"
                    disabled={isReadOnly}
                    onClick={() => onGlobalScoreChange(num.toString())}
                    className={cn(
                      'w-9 h-9 rounded-md text-sm font-medium transition-colors',
                      current === num
                        ? 'bg-primary text-primary-foreground'
                        : current > num
                          ? 'bg-primary/20 text-primary'
                          : 'bg-muted hover:bg-muted/80',
                      isReadOnly && 'cursor-default',
                    )}
                  >
                    {num}
                  </button>
                )
              })}
            </div>
          </div>
        )}

        {scoringMode === 'binary' && (
          <div className="space-y-2">
            <Label>
              Decision <span className="text-destructive">*</span>
            </Label>
            <RadioGroup
              value={binaryDecision}
              onValueChange={(v) => onBinaryChange(v as 'accept' | 'reject')}
              disabled={isReadOnly}
            >
              <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 &mdash; 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 &mdash; This project should not advance</span>
                </Label>
              </div>
            </RadioGroup>
          </div>
        )}

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