'use client'

import { useState, useCallback, useMemo } from 'react'
import { useRouter } from 'next/navigation'
import Papa from 'papaparse'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { Badge } from '@/components/ui/badge'
import { Progress } from '@/components/ui/progress'
import {
  AlertCircle,
  CheckCircle2,
  Upload,
  FileSpreadsheet,
  ArrowRight,
  ArrowLeft,
  Loader2,
  X,
} from 'lucide-react'
import { cn } from '@/lib/utils'

interface CSVImportFormProps {
  programId: string
  roundId?: string
  roundName: string
  onSuccess?: () => void
}

type Step = 'upload' | 'mapping' | 'validation' | 'importing' | 'complete'

// Required and optional fields for project import
const PROJECT_FIELDS = [
  { key: 'title', label: 'Title', required: true },
  { key: 'teamName', label: 'Team Name', required: false },
  { key: 'description', label: 'Description', required: false },
  { key: 'tags', label: 'Tags (comma-separated)', required: false },
  { key: 'foundedAt', label: 'Founded Date', required: false },
]

interface ParsedRow {
  [key: string]: string
}

interface ValidationError {
  row: number
  field: string
  message: string
}

interface MappedProject {
  title: string
  teamName?: string
  description?: string
  tags?: string[]
  metadataJson?: Record<string, unknown>
}

export function CSVImportForm({ programId, roundId, roundName, onSuccess }: CSVImportFormProps) {
  const router = useRouter()
  const [step, setStep] = useState<Step>('upload')
  const [file, setFile] = useState<File | null>(null)
  const [csvData, setCsvData] = useState<ParsedRow[]>([])
  const [csvHeaders, setCsvHeaders] = useState<string[]>([])
  const [columnMapping, setColumnMapping] = useState<Record<string, string>>({})
  const [validationErrors, setValidationErrors] = useState<ValidationError[]>([])
  const [importProgress, setImportProgress] = useState(0)

  const importMutation = trpc.project.importCSV.useMutation({
    onSuccess: () => {
      setStep('complete')
      onSuccess?.()
    },
  })

  // Handle file selection and parsing
  const handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFile = e.target.files?.[0]
    if (!selectedFile) return

    setFile(selectedFile)

    Papa.parse<ParsedRow>(selectedFile, {
      header: true,
      skipEmptyLines: true,
      complete: (results) => {
        if (results.data.length === 0) {
          return
        }

        const headers = results.meta.fields || []
        setCsvHeaders(headers)
        setCsvData(results.data)

        // Auto-map columns with exact or similar names
        const autoMapping: Record<string, string> = {}
        PROJECT_FIELDS.forEach((field) => {
          const matchingHeader = headers.find(
            (h) =>
              h.toLowerCase() === field.key.toLowerCase() ||
              h.toLowerCase().replace(/[_\s-]/g, '') ===
                field.key.toLowerCase().replace(/[_\s-]/g, '') ||
              h.toLowerCase().includes(field.key.toLowerCase())
          )
          if (matchingHeader) {
            autoMapping[field.key] = matchingHeader
          }
        })
        setColumnMapping(autoMapping)

        setStep('mapping')
      },
      error: (error) => {
        console.error('CSV parse error:', error)
      },
    })
  }, [])

  // Handle column mapping change
  const handleMappingChange = (fieldKey: string, csvColumn: string) => {
    setColumnMapping((prev) => ({
      ...prev,
      [fieldKey]: csvColumn === '__none__' ? '' : csvColumn,
    }))
  }

  // Validate mapped data
  const validateData = useCallback((): {
    valid: MappedProject[]
    errors: ValidationError[]
  } => {
    const errors: ValidationError[] = []
    const valid: MappedProject[] = []

    csvData.forEach((row, index) => {
      const rowNum = index + 2 // +2 for header row and 0-indexing

      // Check required fields
      const titleColumn = columnMapping.title
      const title = titleColumn ? row[titleColumn]?.trim() : ''

      if (!title) {
        errors.push({
          row: rowNum,
          field: 'title',
          message: 'Title is required',
        })
        return
      }

      // Build mapped project
      const project: MappedProject = {
        title,
      }

      // Optional fields
      const teamNameColumn = columnMapping.teamName
      if (teamNameColumn && row[teamNameColumn]) {
        project.teamName = row[teamNameColumn].trim()
      }

      const descriptionColumn = columnMapping.description
      if (descriptionColumn && row[descriptionColumn]) {
        project.description = row[descriptionColumn].trim()
      }

      const tagsColumn = columnMapping.tags
      if (tagsColumn && row[tagsColumn]) {
        project.tags = row[tagsColumn]
          .split(',')
          .map((t) => t.trim())
          .filter(Boolean)
      }

      // Store unmapped columns as metadata
      const mappedColumns = new Set(Object.values(columnMapping).filter(Boolean))
      const unmappedData: Record<string, unknown> = {}
      Object.entries(row).forEach(([key, value]) => {
        if (!mappedColumns.has(key) && value?.trim()) {
          unmappedData[key] = value.trim()
        }
      })
      if (Object.keys(unmappedData).length > 0) {
        project.metadataJson = unmappedData
      }

      valid.push(project)
    })

    return { valid, errors }
  }, [csvData, columnMapping])

  // Proceed to validation step
  const handleProceedToValidation = () => {
    const { valid, errors } = validateData()
    setValidationErrors(errors)
    setStep('validation')
  }

  // Start import
  const handleStartImport = async () => {
    const { valid } = validateData()

    if (valid.length === 0) return

    setStep('importing')
    setImportProgress(0)

    try {
      await importMutation.mutateAsync({
        programId,
        roundId,
        projects: valid,
      })
      setImportProgress(100)
    } catch (error) {
      console.error('Import failed:', error)
      setStep('validation')
    }
  }

  // Validation summary
  const validationSummary = useMemo(() => {
    const { valid, errors } = validateData()
    return {
      total: csvData.length,
      valid: valid.length,
      errors: errors.length,
      errorRows: [...new Set(errors.map((e) => e.row))].length,
    }
  }, [csvData, validateData])

  // Render step content
  const renderStep = () => {
    switch (step) {
      case 'upload':
        return (
          <Card>
            <CardHeader>
              <CardTitle>Upload CSV File</CardTitle>
              <CardDescription>
                Upload a CSV file containing project data to import into{' '}
                <strong>{roundName}</strong>
              </CardDescription>
            </CardHeader>
            <CardContent>
              <div className="space-y-4">
                <div
                  className={cn(
                    'border-2 border-dashed rounded-lg p-8 text-center transition-colors',
                    'hover:border-primary/50 cursor-pointer'
                  )}
                  onClick={() => document.getElementById('csv-file')?.click()}
                >
                  <FileSpreadsheet className="mx-auto h-12 w-12 text-muted-foreground" />
                  <p className="mt-2 font-medium">
                    Drop your CSV file here or click to browse
                  </p>
                  <p className="text-sm text-muted-foreground">
                    Supports .csv files only
                  </p>
                  <Input
                    id="csv-file"
                    type="file"
                    accept=".csv"
                    onChange={handleFileSelect}
                    className="hidden"
                  />
                </div>

                <div className="rounded-lg bg-muted p-4">
                  <p className="text-sm font-medium mb-2">Expected columns:</p>
                  <ul className="text-sm text-muted-foreground space-y-1">
                    {PROJECT_FIELDS.map((field) => (
                      <li key={field.key}>
                        <strong>{field.label}</strong>
                        {field.required && (
                          <Badge variant="destructive" className="ml-2 text-xs">
                            Required
                          </Badge>
                        )}
                      </li>
                    ))}
                  </ul>
                </div>
              </div>
            </CardContent>
          </Card>
        )

      case 'mapping':
        return (
          <Card>
            <CardHeader>
              <CardTitle>Map Columns</CardTitle>
              <CardDescription>
                Map your CSV columns to project fields. {csvData.length} rows
                found.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              {/* File info */}
              <div className="flex items-center gap-3 rounded-lg bg-muted p-3">
                <FileSpreadsheet className="h-8 w-8 text-muted-foreground" />
                <div>
                  <p className="font-medium">{file?.name}</p>
                  <p className="text-sm text-muted-foreground">
                    {csvData.length} rows, {csvHeaders.length} columns
                  </p>
                </div>
                <Button
                  variant="ghost"
                  size="sm"
                  className="ml-auto"
                  onClick={() => {
                    setFile(null)
                    setCsvData([])
                    setCsvHeaders([])
                    setColumnMapping({})
                    setStep('upload')
                  }}
                >
                  <X className="h-4 w-4" />
                </Button>
              </div>

              {/* Column mapping */}
              <div className="space-y-4">
                {PROJECT_FIELDS.map((field) => (
                  <div
                    key={field.key}
                    className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4"
                  >
                    <div className="sm:w-48 flex items-center gap-2">
                      <Label className="font-medium">{field.label}</Label>
                      {field.required && (
                        <Badge variant="destructive" className="text-xs">
                          Required
                        </Badge>
                      )}
                    </div>
                    <Select
                      value={columnMapping[field.key] || '__none__'}
                      onValueChange={(v) => handleMappingChange(field.key, v)}
                    >
                      <SelectTrigger className="flex-1">
                        <SelectValue placeholder="Select column" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="__none__">
                          <span className="text-muted-foreground">
                            -- Not mapped --
                          </span>
                        </SelectItem>
                        {csvHeaders.map((header) => (
                          <SelectItem key={header} value={header}>
                            {header}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                ))}
              </div>

              {/* Preview */}
              <div className="space-y-2">
                <Label className="font-medium">Preview (first 5 rows)</Label>
                <div className="rounded-lg border overflow-x-auto">
                  <Table>
                    <TableHeader>
                      <TableRow>
                        {PROJECT_FIELDS.filter(
                          (f) => columnMapping[f.key]
                        ).map((field) => (
                          <TableHead key={field.key}>{field.label}</TableHead>
                        ))}
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {csvData.slice(0, 5).map((row, index) => (
                        <TableRow key={index}>
                          {PROJECT_FIELDS.filter(
                            (f) => columnMapping[f.key]
                          ).map((field) => (
                            <TableCell key={field.key} className="max-w-[200px] truncate">
                              {row[columnMapping[field.key]] || '-'}
                            </TableCell>
                          ))}
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </div>
              </div>

              {/* Actions */}
              <div className="flex justify-between">
                <Button
                  variant="outline"
                  onClick={() => {
                    setFile(null)
                    setCsvData([])
                    setCsvHeaders([])
                    setColumnMapping({})
                    setStep('upload')
                  }}
                >
                  <ArrowLeft className="mr-2 h-4 w-4" />
                  Back
                </Button>
                <Button
                  onClick={handleProceedToValidation}
                  disabled={!columnMapping.title}
                >
                  Validate Data
                  <ArrowRight className="ml-2 h-4 w-4" />
                </Button>
              </div>
            </CardContent>
          </Card>
        )

      case 'validation':
        return (
          <Card>
            <CardHeader>
              <CardTitle>Validation Summary</CardTitle>
              <CardDescription>
                Review the validation results before importing
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              {/* Summary */}
              <div className="grid gap-4 sm:grid-cols-3">
                <div className="rounded-lg bg-muted p-4 text-center">
                  <p className="text-3xl font-bold">{validationSummary.total}</p>
                  <p className="text-sm text-muted-foreground">Total Rows</p>
                </div>
                <div className="rounded-lg bg-green-500/10 p-4 text-center">
                  <p className="text-3xl font-bold text-green-600">
                    {validationSummary.valid}
                  </p>
                  <p className="text-sm text-muted-foreground">Valid Projects</p>
                </div>
                <div className="rounded-lg bg-red-500/10 p-4 text-center">
                  <p className="text-3xl font-bold text-red-600">
                    {validationSummary.errorRows}
                  </p>
                  <p className="text-sm text-muted-foreground">Rows with Errors</p>
                </div>
              </div>

              {/* Errors list */}
              {validationErrors.length > 0 && (
                <div className="space-y-2">
                  <Label className="font-medium text-destructive">
                    Validation Errors
                  </Label>
                  <div className="rounded-lg border border-destructive/50 bg-destructive/5 p-4 max-h-60 overflow-y-auto">
                    {validationErrors.slice(0, 20).map((error, index) => (
                      <div
                        key={index}
                        className="flex items-start gap-2 text-sm py-1"
                      >
                        <AlertCircle className="h-4 w-4 text-destructive shrink-0 mt-0.5" />
                        <span>
                          <strong>Row {error.row}:</strong> {error.message}
                        </span>
                      </div>
                    ))}
                    {validationErrors.length > 20 && (
                      <p className="text-sm text-muted-foreground mt-2">
                        ... and {validationErrors.length - 20} more errors
                      </p>
                    )}
                  </div>
                </div>
              )}

              {/* Success message */}
              {validationSummary.valid > 0 && validationErrors.length === 0 && (
                <div className="flex items-center gap-2 rounded-lg bg-green-500/10 p-4 text-green-700">
                  <CheckCircle2 className="h-5 w-5" />
                  <span>All {validationSummary.valid} projects are valid and ready to import!</span>
                </div>
              )}

              {/* Actions */}
              <div className="flex justify-between">
                <Button variant="outline" onClick={() => setStep('mapping')}>
                  <ArrowLeft className="mr-2 h-4 w-4" />
                  Back to Mapping
                </Button>
                <Button
                  onClick={handleStartImport}
                  disabled={validationSummary.valid === 0 || importMutation.isPending}
                >
                  {importMutation.isPending ? (
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  ) : (
                    <Upload className="mr-2 h-4 w-4" />
                  )}
                  Import {validationSummary.valid} Projects
                </Button>
              </div>

              {/* Import error */}
              {importMutation.error && (
                <div className="flex items-center gap-2 rounded-lg bg-destructive/10 p-4 text-destructive">
                  <AlertCircle className="h-5 w-5" />
                  <span>
                    Import failed: {importMutation.error.message}
                  </span>
                </div>
              )}
            </CardContent>
          </Card>
        )

      case 'importing':
        return (
          <Card>
            <CardContent className="flex flex-col items-center justify-center py-12">
              <Loader2 className="h-12 w-12 animate-spin text-primary" />
              <p className="mt-4 font-medium">Importing projects...</p>
              <p className="text-sm text-muted-foreground">
                Please wait while we process your data
              </p>
              <Progress value={importProgress} className="mt-4 w-48" />
            </CardContent>
          </Card>
        )

      case 'complete':
        return (
          <Card>
            <CardContent className="flex flex-col items-center justify-center py-12">
              <div className="flex h-16 w-16 items-center justify-center rounded-full bg-green-500/10">
                <CheckCircle2 className="h-8 w-8 text-green-600" />
              </div>
              <p className="mt-4 text-xl font-semibold">Import Complete!</p>
              <p className="text-muted-foreground">
                Successfully imported {validationSummary.valid} projects into{' '}
                <strong>{roundName}</strong>
              </p>
              <div className="mt-6 flex gap-3">
                <Button variant="outline" onClick={() => router.back()}>
                  Back to Projects
                </Button>
                <Button
                  onClick={() => {
                    setFile(null)
                    setCsvData([])
                    setCsvHeaders([])
                    setColumnMapping({})
                    setValidationErrors([])
                    setStep('upload')
                  }}
                >
                  Import More
                </Button>
              </div>
            </CardContent>
          </Card>
        )
    }
  }

  return (
    <div className="space-y-6">
      {/* Progress indicator */}
      <div className="flex items-center justify-center gap-2">
        {(['upload', 'mapping', 'validation', 'complete'] as const).map(
          (s, index) => (
            <div key={s} className="flex items-center">
              {index > 0 && (
                <div
                  className={cn(
                    'h-0.5 w-8 mx-1',
                    step === s ||
                      ['upload', 'mapping', 'validation', 'complete'].indexOf(
                        step
                      ) >
                        ['upload', 'mapping', 'validation', 'complete'].indexOf(s)
                      ? 'bg-primary'
                      : 'bg-muted'
                  )}
                />
              )}
              <div
                className={cn(
                  'flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium',
                  step === s
                    ? 'bg-primary text-primary-foreground'
                    : ['upload', 'mapping', 'validation', 'complete'].indexOf(
                          step
                        ) > ['upload', 'mapping', 'validation', 'complete'].indexOf(s)
                      ? 'bg-primary/20 text-primary'
                      : 'bg-muted text-muted-foreground'
                )}
              >
                {index + 1}
              </div>
            </div>
          )
        )}
      </div>

      {renderStep()}
    </div>
  )
}
