import { useState, useEffect, useCallback, useRef } from 'react'
import {
  Upload, FileUp, Check, AlertTriangle, ChevronLeft, ChevronRight, History,
} from 'lucide-react'
import api from '@/services/api'
import type {
  ImportPreview, ImportResult, ICDImportResponse,
  ImportLogEntry, ImportLogListResponse,
} from '@/types'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from '@/components/ui/table'
import {
  Tabs, TabsContent, TabsList, TabsTrigger,
} from '@/components/ui/tabs'
import { Skeleton } from '@/components/ui/skeleton'

export function ImportPage() {
  return (
    <div className="p-6 space-y-6">
      <h1 className="text-2xl font-bold">Import</h1>
      <Tabs defaultValue="csv">
        <TabsList>
          <TabsTrigger value="csv">
            <FileUp className="size-4 mr-1.5" />
            CSV-Import
          </TabsTrigger>
          <TabsTrigger value="icd">
            <Upload className="size-4 mr-1.5" />
            ICD-Import
          </TabsTrigger>
          <TabsTrigger value="log">
            <History className="size-4 mr-1.5" />
            Import-Verlauf
          </TabsTrigger>
        </TabsList>

        <TabsContent value="csv" className="mt-4">
          <CsvImportTab />
        </TabsContent>
        <TabsContent value="icd" className="mt-4">
          <IcdImportTab />
        </TabsContent>
        <TabsContent value="log" className="mt-4">
          <ImportLogTab />
        </TabsContent>
      </Tabs>
    </div>
  )
}

// ---------------------------------------------------------------------------
// CSV Import Tab
// ---------------------------------------------------------------------------

function CsvImportTab() {
  const [file, setFile] = useState<File | null>(null)
  const [uploading, setUploading] = useState(false)
  const [confirming, setConfirming] = useState(false)
  const [preview, setPreview] = useState<ImportPreview | null>(null)
  const [result, setResult] = useState<ImportResult | null>(null)
  const [error, setError] = useState('')
  const fileInputRef = useRef<HTMLInputElement>(null)

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    const f = e.dataTransfer.files[0]
    if (f && f.name.toLowerCase().endsWith('.csv')) {
      setFile(f)
      setPreview(null)
      setResult(null)
      setError('')
    }
  }, [])

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const f = e.target.files?.[0]
    if (f) {
      setFile(f)
      setPreview(null)
      setResult(null)
      setError('')
    }
  }

  const uploadPreview = async () => {
    if (!file) return
    setUploading(true)
    setError('')
    try {
      const formData = new FormData()
      formData.append('file', file)
      const res = await api.post<ImportPreview>('/import/csv', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      })
      setPreview(res.data)
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : 'Upload fehlgeschlagen'
      setError(msg)
    } finally {
      setUploading(false)
    }
  }

  const confirmImport = async () => {
    if (!file) return
    setConfirming(true)
    setError('')
    try {
      const formData = new FormData()
      formData.append('file', file)
      const res = await api.post<ImportResult>('/import/csv/confirm', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      })
      setResult(res.data)
      setPreview(null)
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : 'Import fehlgeschlagen'
      setError(msg)
    } finally {
      setConfirming(false)
    }
  }

  const reset = () => {
    setFile(null)
    setPreview(null)
    setResult(null)
    setError('')
    if (fileInputRef.current) fileInputRef.current.value = ''
  }

  return (
    <div className="space-y-4">
      {/* Drop zone */}
      {!preview && !result && (
        <div
          onDragOver={(e) => e.preventDefault()}
          onDrop={handleDrop}
          className="border-2 border-dashed rounded-lg p-10 text-center cursor-pointer hover:border-primary/50 transition-colors"
          onClick={() => fileInputRef.current?.click()}
        >
          <input
            ref={fileInputRef}
            type="file"
            accept=".csv"
            className="hidden"
            onChange={handleFileSelect}
          />
          <Upload className="size-10 mx-auto text-muted-foreground mb-3" />
          {file ? (
            <p className="text-sm">
              <span className="font-medium">{file.name}</span>
              <span className="text-muted-foreground ml-2">
                ({(file.size / 1024).toFixed(1)} KB)
              </span>
            </p>
          ) : (
            <div>
              <p className="font-medium">CSV-Datei hierhin ziehen</p>
              <p className="text-sm text-muted-foreground mt-1">
                oder klicken zum Auswählen
              </p>
            </div>
          )}
        </div>
      )}

      {file && !preview && !result && (
        <div className="flex gap-2">
          <Button onClick={uploadPreview} disabled={uploading}>
            {uploading ? 'Wird hochgeladen...' : 'Vorschau laden'}
          </Button>
          <Button variant="outline" onClick={reset}>Abbrechen</Button>
        </div>
      )}

      {error && (
        <Alert variant="destructive">
          <AlertTriangle className="size-4" />
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {/* Preview */}
      {preview && (
        <div className="space-y-4">
          <Card>
            <CardHeader>
              <CardTitle className="text-lg">
                Vorschau: {preview.filename}
              </CardTitle>
            </CardHeader>
            <CardContent>
              <div className="flex gap-6 text-sm">
                <div>
                  <span className="text-muted-foreground">Zeilen gesamt:</span>{' '}
                  <span className="font-medium">{preview.total_rows}</span>
                </div>
                <div>
                  <span className="text-muted-foreground">Neue Fälle:</span>{' '}
                  <span className="font-medium text-green-600">{preview.new_cases}</span>
                </div>
                <div>
                  <span className="text-muted-foreground">Duplikate:</span>{' '}
                  <span className="font-medium text-amber-600">{preview.duplicates}</span>
                </div>
                {preview.errors.length > 0 && (
                  <div>
                    <span className="text-muted-foreground">Fehler:</span>{' '}
                    <span className="font-medium text-destructive">{preview.errors.length}</span>
                  </div>
                )}
              </div>
            </CardContent>
          </Card>

          {preview.errors.length > 0 && (
            <Alert variant="destructive">
              <AlertTriangle className="size-4" />
              <AlertDescription>
                <ul className="list-disc list-inside space-y-1">
                  {preview.errors.map((e, i) => <li key={i}>{e}</li>)}
                </ul>
              </AlertDescription>
            </Alert>
          )}

          {/* Preview table */}
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>#</TableHead>
                <TableHead>Nachname</TableHead>
                <TableHead>Vorname</TableHead>
                <TableHead>Fallgruppe</TableHead>
                <TableHead>Datum</TableHead>
                <TableHead>Status</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {preview.rows.map((row) => (
                <TableRow key={row.row_number}>
                  <TableCell>{row.row_number}</TableCell>
                  <TableCell className="font-medium">{row.nachname}</TableCell>
                  <TableCell>{row.vorname || '-'}</TableCell>
                  <TableCell>{row.fallgruppe}</TableCell>
                  <TableCell>{row.datum}</TableCell>
                  <TableCell>
                    {row.is_duplicate ? (
                      <Badge variant="outline" className="text-amber-600 border-amber-300">
                        Duplikat
                      </Badge>
                    ) : (
                      <Badge variant="secondary" className="text-green-600">
                        Neu
                      </Badge>
                    )}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>

          <div className="flex gap-2">
            <Button onClick={confirmImport} disabled={confirming || preview.new_cases === 0}>
              {confirming ? 'Wird importiert...' : `${preview.new_cases} Fälle importieren`}
            </Button>
            <Button variant="outline" onClick={reset}>Abbrechen</Button>
          </div>
        </div>
      )}

      {/* Result */}
      {result && (
        <div className="space-y-4">
          <Alert>
            <Check className="size-4" />
            <AlertDescription>
              Import abgeschlossen: {result.imported} importiert, {result.skipped} übersprungen, {result.updated} aktualisiert.
            </AlertDescription>
          </Alert>
          {result.errors.length > 0 && (
            <Alert variant="destructive">
              <AlertTriangle className="size-4" />
              <AlertDescription>
                <ul className="list-disc list-inside space-y-1">
                  {result.errors.map((e, i) => <li key={i}>{e}</li>)}
                </ul>
              </AlertDescription>
            </Alert>
          )}
          <Button onClick={reset}>Neuen Import starten</Button>
        </div>
      )}
    </div>
  )
}

// ---------------------------------------------------------------------------
// ICD Import Tab
// ---------------------------------------------------------------------------

function IcdImportTab() {
  const [file, setFile] = useState<File | null>(null)
  const [uploading, setUploading] = useState(false)
  const [result, setResult] = useState<ICDImportResponse | null>(null)
  const [error, setError] = useState('')
  const fileInputRef = useRef<HTMLInputElement>(null)

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    const f = e.dataTransfer.files[0]
    if (f && (f.name.toLowerCase().endsWith('.xlsx') || f.name.toLowerCase().endsWith('.xls'))) {
      setFile(f)
      setResult(null)
      setError('')
    }
  }, [])

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const f = e.target.files?.[0]
    if (f) {
      setFile(f)
      setResult(null)
      setError('')
    }
  }

  const upload = async () => {
    if (!file) return
    setUploading(true)
    setError('')
    try {
      const formData = new FormData()
      formData.append('file', file)
      const res = await api.post<ICDImportResponse>('/import/icd-xlsx', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      })
      setResult(res.data)
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : 'Upload fehlgeschlagen'
      setError(msg)
    } finally {
      setUploading(false)
    }
  }

  const reset = () => {
    setFile(null)
    setResult(null)
    setError('')
    if (fileInputRef.current) fileInputRef.current.value = ''
  }

  return (
    <div className="space-y-4">
      {!result && (
        <div
          onDragOver={(e) => e.preventDefault()}
          onDrop={handleDrop}
          className="border-2 border-dashed rounded-lg p-10 text-center cursor-pointer hover:border-primary/50 transition-colors"
          onClick={() => fileInputRef.current?.click()}
        >
          <input
            ref={fileInputRef}
            type="file"
            accept=".xlsx,.xls"
            className="hidden"
            onChange={handleFileSelect}
          />
          <Upload className="size-10 mx-auto text-muted-foreground mb-3" />
          {file ? (
            <p className="text-sm">
              <span className="font-medium">{file.name}</span>
              <span className="text-muted-foreground ml-2">
                ({(file.size / 1024).toFixed(1)} KB)
              </span>
            </p>
          ) : (
            <div>
              <p className="font-medium">Excel-Datei (.xlsx) hierhin ziehen</p>
              <p className="text-sm text-muted-foreground mt-1">
                oder klicken zum Auswählen
              </p>
            </div>
          )}
        </div>
      )}

      {file && !result && (
        <div className="flex gap-2">
          <Button onClick={upload} disabled={uploading}>
            {uploading ? 'Wird hochgeladen...' : 'ICD-Codes importieren'}
          </Button>
          <Button variant="outline" onClick={reset}>Abbrechen</Button>
        </div>
      )}

      {error && (
        <Alert variant="destructive">
          <AlertTriangle className="size-4" />
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {result && (
        <div className="space-y-4">
          <Alert>
            <Check className="size-4" />
            <AlertDescription>
              ICD-Import abgeschlossen: {result.updated} Fälle aktualisiert.
            </AlertDescription>
          </Alert>
          {result.errors.length > 0 && (
            <Alert variant="destructive">
              <AlertTriangle className="size-4" />
              <AlertDescription>
                <ul className="list-disc list-inside space-y-1">
                  {result.errors.map((e, i) => <li key={i}>{e}</li>)}
                </ul>
              </AlertDescription>
            </Alert>
          )}
          <Button onClick={reset}>Neuen Import starten</Button>
        </div>
      )}
    </div>
  )
}

// ---------------------------------------------------------------------------
// Import Log Tab
// ---------------------------------------------------------------------------

function ImportLogTab() {
  const [logs, setLogs] = useState<ImportLogEntry[]>([])
  const [total, setTotal] = useState(0)
  const [page, setPage] = useState(1)
  const [loading, setLoading] = useState(true)
  const perPage = 20

  useEffect(() => {
    setLoading(true)
    api.get<ImportLogListResponse>('/import/log', {
      params: { page, per_page: perPage },
    })
      .then((res) => {
        setLogs(res.data.items)
        setTotal(res.data.total)
      })
      .catch(() => {
        setLogs([])
        setTotal(0)
      })
      .finally(() => setLoading(false))
  }, [page])

  const totalPages = Math.ceil(total / perPage)

  if (loading) {
    return (
      <div className="space-y-2">
        {Array.from({ length: 5 }).map((_, i) => (
          <Skeleton key={i} className="h-10 w-full" />
        ))}
      </div>
    )
  }

  if (logs.length === 0) {
    return <p className="text-muted-foreground py-8 text-center">Keine Import-Einträge vorhanden.</p>
  }

  return (
    <div className="space-y-4">
      <Table>
        <TableHeader>
          <TableRow>
            <TableHead>Datum</TableHead>
            <TableHead>Dateiname</TableHead>
            <TableHead>Typ</TableHead>
            <TableHead className="text-right">Importiert</TableHead>
            <TableHead className="text-right">Übersprungen</TableHead>
            <TableHead className="text-right">Fehler</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {logs.map((log) => (
            <TableRow key={log.id}>
              <TableCell>{formatDateTime(log.imported_at)}</TableCell>
              <TableCell className="font-mono text-sm">{log.filename}</TableCell>
              <TableCell>
                <Badge variant="outline">{log.import_type}</Badge>
              </TableCell>
              <TableCell className="text-right">{log.imported_rows}</TableCell>
              <TableCell className="text-right">{log.skipped_rows}</TableCell>
              <TableCell className="text-right">
                {log.error_count > 0 ? (
                  <span className="text-destructive font-medium">{log.error_count}</span>
                ) : (
                  '0'
                )}
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>

      {totalPages > 1 && (
        <div className="flex items-center justify-end gap-2">
          <Button
            variant="outline"
            size="sm"
            disabled={page <= 1}
            onClick={() => setPage((p) => p - 1)}
          >
            <ChevronLeft className="size-4" />
          </Button>
          <span className="text-sm">
            Seite {page} von {totalPages}
          </span>
          <Button
            variant="outline"
            size="sm"
            disabled={page >= totalPages}
            onClick={() => setPage((p) => p + 1)}
          >
            <ChevronRight className="size-4" />
          </Button>
        </div>
      )}
    </div>
  )
}

function formatDateTime(dateStr: string): string {
  try {
    return new Date(dateStr).toLocaleString('de-DE', {
      day: '2-digit', month: '2-digit', year: 'numeric',
      hour: '2-digit', minute: '2-digit',
    })
  } catch {
    return dateStr
  }
}
