'use client'

/**
 * Test Dashboard - Zentrales Test-Registry
 *
 * Aggregiert alle 280+ Tests aus allen Services:
 * - Go Unit Tests (~57)
 * - Python Tests (~50)
 * - BQAS Golden (97)
 * - BQAS RAG (~20)
 * - TypeScript Jest (~8)
 * - SDK Vitest Unit Tests (~43)
 * - SDK Playwright E2E (~25)
 * - E2E Playwright (~5)
 */

import React, { useState, useEffect, useCallback, useRef } from 'react'
import Link from 'next/link'
import { PagePurpose } from '@/components/common/PagePurpose'
import { DevOpsPipelineSidebarResponsive } from '@/components/infrastructure/DevOpsPipelineSidebar'
import type { LLMRoutingOption } from '@/types/infrastructure-modules'
import type {
  ServiceTestInfo,
  TestRegistryStats,
  TestRun,
  CoverageData,
  TabType,
  Toast,
  FailedTest,
  BacklogItem,
  BacklogPriority,
  BacklogStatus,
  TrendDataPoint,
} from './types'

// API Configuration
const API_BASE = '/api/tests'

// ==============================================================================
// Toast Notification Component
// ==============================================================================

function ToastContainer({ toasts, onDismiss }: { toasts: Toast[]; onDismiss: (id: number) => void }) {
  return (
    <div className="fixed bottom-4 right-4 z-50 space-y-2">
      {toasts.map((toast) => (
        <div
          key={toast.id}
          className={`flex items-center gap-3 px-4 py-3 rounded-lg shadow-lg border animate-slide-in ${
            toast.type === 'success'
              ? 'bg-emerald-50 border-emerald-200 text-emerald-800'
              : toast.type === 'error'
                ? 'bg-red-50 border-red-200 text-red-800'
                : toast.type === 'loading'
                  ? 'bg-blue-50 border-blue-200 text-blue-800'
                  : 'bg-slate-50 border-slate-200 text-slate-800'
          }`}
        >
          {toast.type === 'loading' ? (
            <svg className="animate-spin h-5 w-5" fill="none" viewBox="0 0 24 24">
              <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
              <path
                className="opacity-75"
                fill="currentColor"
                d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
              />
            </svg>
          ) : toast.type === 'success' ? (
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
            </svg>
          ) : toast.type === 'error' ? (
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          ) : (
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          )}
          <span className="text-sm font-medium">{toast.message}</span>
          {toast.type !== 'loading' && (
            <button onClick={() => onDismiss(toast.id)} className="ml-2 opacity-60 hover:opacity-100">
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          )}
        </div>
      ))}
    </div>
  )
}

// ==============================================================================
// Helper Components
// ==============================================================================

function MetricCard({
  title,
  value,
  subtitle,
  trend,
  color = 'blue',
}: {
  title: string
  value: string | number
  subtitle?: string
  trend?: 'up' | 'down' | 'stable'
  color?: 'blue' | 'green' | 'red' | 'yellow' | 'orange' | 'purple'
}) {
  const colorClasses = {
    blue: 'bg-blue-50 border-blue-200',
    green: 'bg-emerald-50 border-emerald-200',
    red: 'bg-red-50 border-red-200',
    yellow: 'bg-amber-50 border-amber-200',
    orange: 'bg-orange-50 border-orange-200',
    purple: 'bg-purple-50 border-purple-200',
  }

  const trendIcons = {
    up: (
      <svg className="w-4 h-4 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 10l7-7m0 0l7 7m-7-7v18" />
      </svg>
    ),
    down: (
      <svg className="w-4 h-4 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" />
      </svg>
    ),
    stable: (
      <svg className="w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 12h14" />
      </svg>
    ),
  }

  return (
    <div className={`rounded-xl border p-5 ${colorClasses[color]}`}>
      <div className="flex items-start justify-between">
        <div>
          <p className="text-sm font-medium text-slate-600">{title}</p>
          <p className="mt-1 text-2xl font-bold text-slate-900">{value}</p>
          {subtitle && <p className="mt-1 text-xs text-slate-500">{subtitle}</p>}
        </div>
        {trend && <div className="mt-1">{trendIcons[trend]}</div>}
      </div>
    </div>
  )
}

function ServiceTestCard({
  service,
  onRun,
  isRunning,
  progress,
}: {
  service: ServiceTestInfo
  onRun: (service: string) => void
  isRunning: boolean
  progress?: {
    current_file: string
    files_done: number
    files_total: number
    passed: number
    failed: number
    status: string
  }
}) {
  const passRate = service.total_tests > 0 ? (service.passed_tests / service.total_tests) * 100 : 0

  const getLanguageIcon = (lang: string) => {
    switch (lang) {
      case 'go':
        return '🐹'
      case 'python':
        return '🐍'
      case 'typescript':
        return '📘'
      case 'mixed':
        return '🔀'
      default:
        return '📦'
    }
  }

  const getStatusColor = (status: string) => {
    switch (status) {
      case 'passed':
        return 'bg-emerald-100 text-emerald-700'
      case 'failed':
        return 'bg-red-100 text-red-700'
      case 'running':
        return 'bg-blue-100 text-blue-700'
      default:
        return 'bg-slate-100 text-slate-700'
    }
  }

  return (
    <div className="bg-white rounded-xl border border-slate-200 p-5 hover:border-orange-300 transition-colors">
      <div className="flex items-start justify-between mb-4">
        <div className="flex items-center gap-3">
          <span className="text-2xl">{getLanguageIcon(service.language)}</span>
          <div>
            <h3 className="font-semibold text-slate-900">{service.display_name}</h3>
            <p className="text-xs text-slate-500">
              {service.port ? `Port ${service.port}` : 'Library'} • {service.language}
            </p>
          </div>
        </div>
        <span className={`px-2 py-1 rounded text-xs font-medium ${getStatusColor(service.status)}`}>
          {service.status === 'passed' ? 'Bestanden' : service.status === 'failed' ? 'Fehler' : 'Ausstehend'}
        </span>
      </div>

      <div className="space-y-3">
        <div>
          <div className="flex items-center justify-between text-sm mb-1">
            <span className="text-slate-600">Pass Rate</span>
            <span className="font-medium text-slate-900">{passRate.toFixed(0)}%</span>
          </div>
          <div className="h-2 bg-slate-100 rounded-full overflow-hidden">
            <div
              className={`h-full rounded-full transition-all ${
                passRate >= 80 ? 'bg-emerald-500' : passRate >= 60 ? 'bg-amber-500' : 'bg-red-500'
              }`}
              style={{ width: `${passRate}%` }}
            />
          </div>
        </div>

        <div className="grid grid-cols-3 gap-2 text-center">
          <div className="p-2 bg-slate-50 rounded-lg">
            <p className="text-lg font-bold text-slate-900">{service.total_tests}</p>
            <p className="text-xs text-slate-500">Tests</p>
          </div>
          <div className="p-2 bg-emerald-50 rounded-lg">
            <p className="text-lg font-bold text-emerald-600">{service.passed_tests}</p>
            <p className="text-xs text-slate-500">Bestanden</p>
          </div>
          <div className="p-2 bg-red-50 rounded-lg">
            <p className="text-lg font-bold text-red-600">{service.failed_tests}</p>
            <p className="text-xs text-slate-500">Fehler</p>
          </div>
        </div>

        {service.coverage_percent && (
          <div className="flex items-center justify-between text-sm pt-2 border-t border-slate-100">
            <span className="text-slate-600">Coverage</span>
            <span className={`font-medium ${service.coverage_percent >= 70 ? 'text-emerald-600' : 'text-amber-600'}`}>
              {service.coverage_percent.toFixed(1)}%
            </span>
          </div>
        )}

        {/* Progress-Anzeige wenn Tests laufen */}
        {isRunning && progress && progress.status === 'running' && (
          <div className="mb-3 p-3 bg-orange-50 rounded-lg border border-orange-200">
            <div className="flex items-center justify-between text-xs text-orange-700 mb-2">
              <span className="font-mono truncate max-w-[180px]">{progress.current_file || 'Starte...'}</span>
              <span>{progress.files_done}/{progress.files_total} Dateien</span>
            </div>
            <div className="h-1.5 bg-orange-100 rounded-full overflow-hidden">
              <div
                className="h-full bg-orange-500 rounded-full transition-all"
                style={{ width: `${progress.files_total > 0 ? (progress.files_done / progress.files_total) * 100 : 0}%` }}
              />
            </div>
            <div className="flex items-center justify-between mt-2 text-xs">
              <span className="text-emerald-600 font-medium">{progress.passed} bestanden</span>
              <span className="text-red-600 font-medium">{progress.failed} fehler</span>
            </div>
          </div>
        )}

        <button
          onClick={() => onRun(service.service)}
          disabled={isRunning}
          className={`w-full py-2 rounded-lg text-sm font-medium transition-all ${
            isRunning
              ? 'bg-orange-100 text-orange-600 cursor-wait'
              : 'bg-orange-600 text-white hover:bg-orange-700 active:scale-98'
          }`}
        >
          {isRunning ? (
            <span className="flex items-center justify-center gap-2">
              <svg className="animate-spin h-4 w-4" fill="none" viewBox="0 0 24 24">
                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
              </svg>
              {progress && progress.status === 'running' ? `${progress.passed + progress.failed} Tests...` : 'Laeuft...'}
            </span>
          ) : (
            'Tests starten'
          )}
        </button>
      </div>
    </div>
  )
}

function CoverageChart({ data }: { data: CoverageData[] }) {
  if (data.length === 0) {
    return (
      <div className="text-center py-8 text-slate-400">
        Keine Coverage-Daten verfuegbar
      </div>
    )
  }

  const sortedData = [...data].sort((a, b) => b.coverage_percent - a.coverage_percent)

  return (
    <div className="space-y-3">
      {sortedData.map((item) => (
        <div key={item.service}>
          <div className="flex items-center justify-between text-sm mb-1">
            <span className="text-slate-600 truncate max-w-[200px]">{item.display_name}</span>
            <span
              className={`font-medium ${
                item.coverage_percent >= 80 ? 'text-emerald-600' : item.coverage_percent >= 60 ? 'text-amber-600' : 'text-red-600'
              }`}
            >
              {item.coverage_percent.toFixed(1)}%
            </span>
          </div>
          <div className="h-2 bg-slate-100 rounded-full overflow-hidden">
            <div
              className={`h-full rounded-full transition-all ${
                item.coverage_percent >= 80 ? 'bg-emerald-500' : item.coverage_percent >= 60 ? 'bg-amber-500' : 'bg-red-500'
              }`}
              style={{ width: `${item.coverage_percent}%` }}
            />
          </div>
        </div>
      ))}
    </div>
  )
}

function FrameworkDistribution({ data }: { data: Record<string, number> }) {
  const total = Object.values(data).reduce((a, b) => a + b, 0)
  if (total === 0) return null

  const frameworkLabels: Record<string, string> = {
    go_test: 'Go Tests',
    pytest: 'Python (pytest)',
    jest: 'Jest (TS)',
    vitest: 'Vitest (SDK)',
    playwright: 'Playwright (E2E)',
    bqas_golden: 'BQAS Golden',
    bqas_rag: 'BQAS RAG',
    bqas_synthetic: 'BQAS Synthetic',
  }

  const frameworkColors: Record<string, string> = {
    go_test: 'bg-cyan-500',
    pytest: 'bg-yellow-500',
    jest: 'bg-blue-500',
    vitest: 'bg-orange-500',
    playwright: 'bg-purple-500',
    bqas_golden: 'bg-emerald-500',
    bqas_rag: 'bg-teal-500',
    bqas_synthetic: 'bg-amber-500',
  }

  return (
    <div className="space-y-3">
      {Object.entries(data)
        .sort((a, b) => b[1] - a[1])
        .map(([framework, count]) => (
          <div key={framework} className="flex items-center gap-3">
            <div className={`w-3 h-3 rounded-full ${frameworkColors[framework] || 'bg-slate-400'}`} />
            <span className="text-sm text-slate-600 flex-1">{frameworkLabels[framework] || framework}</span>
            <span className="text-sm font-medium text-slate-900">{count}</span>
            <span className="text-xs text-slate-400">({((count / total) * 100).toFixed(0)}%)</span>
          </div>
        ))}
    </div>
  )
}

function TestRunsTable({ runs }: { runs: TestRun[] }) {
  if (runs.length === 0) {
    return (
      <div className="text-center py-8 text-slate-400">
        Keine Test-Laeufe vorhanden
      </div>
    )
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-slate-200">
            <th className="text-left py-3 px-4 font-medium text-slate-600">ID</th>
            <th className="text-left py-3 px-4 font-medium text-slate-600">Service</th>
            <th className="text-left py-3 px-4 font-medium text-slate-600">Zeitpunkt</th>
            <th className="text-right py-3 px-4 font-medium text-slate-600">Tests</th>
            <th className="text-right py-3 px-4 font-medium text-slate-600">Bestanden</th>
            <th className="text-right py-3 px-4 font-medium text-slate-600">Dauer</th>
            <th className="text-center py-3 px-4 font-medium text-slate-600">Status</th>
          </tr>
        </thead>
        <tbody>
          {runs.map((run) => (
            <tr key={run.id} className="border-b border-slate-100 hover:bg-slate-50">
              <td className="py-3 px-4 font-mono text-xs text-slate-500">{run.id.slice(-8)}</td>
              <td className="py-3 px-4 text-slate-900">{run.service}</td>
              <td className="py-3 px-4 text-slate-600">
                {new Date(run.started_at).toLocaleString('de-DE')}
              </td>
              <td className="py-3 px-4 text-right text-slate-600">{run.total_tests}</td>
              <td className="py-3 px-4 text-right">
                <span className="text-emerald-600">{run.passed_tests}</span>
                <span className="text-slate-400"> / </span>
                <span className="text-red-600">{run.failed_tests}</span>
              </td>
              <td className="py-3 px-4 text-right text-slate-500">
                {run.duration_seconds.toFixed(1)}s
              </td>
              <td className="py-3 px-4 text-center">
                <span
                  className={`px-2 py-1 rounded text-xs font-medium ${
                    run.status === 'completed'
                      ? 'bg-emerald-100 text-emerald-700'
                      : run.status === 'failed'
                        ? 'bg-red-100 text-red-700'
                        : run.status === 'running'
                          ? 'bg-blue-100 text-blue-700'
                          : 'bg-slate-100 text-slate-700'
                  }`}
                >
                  {run.status}
                </span>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

// ==============================================================================
// Guide Tab
// ==============================================================================

function GuideTab() {
  return (
    <div className="space-y-8">
      <div className="bg-gradient-to-r from-orange-50 to-amber-50 rounded-xl border border-orange-200 p-6">
        <h2 className="text-xl font-bold text-slate-900 mb-4 flex items-center gap-2">
          <svg className="w-6 h-6 text-orange-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
          </svg>
          Was ist das Test Dashboard?
        </h2>
        <p className="text-slate-700 leading-relaxed">
          Das <strong>Test Dashboard</strong> ist die zentrale Uebersicht fuer alle 260+ Tests im Breakpilot-System.
          Es aggregiert Tests aus verschiedenen Services (Go, Python, TypeScript) ohne diese physisch zu migrieren.
          Tests bleiben an ihren konventionellen Orten, werden aber hier zentral ueberwacht und ausgefuehrt.
          Seit 2026-02 inklusive AI Compliance SDK Unit Tests (Vitest) und E2E Tests (Playwright).
        </p>
      </div>

      <div className="bg-white rounded-xl border border-slate-200 p-6">
        <h3 className="text-lg font-semibold text-slate-900 mb-4">Test-Kategorien</h3>
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
          <div className="p-4 bg-cyan-50 rounded-lg border border-cyan-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">🐹</span>
              <h4 className="font-medium text-cyan-800">Go Unit Tests (~57)</h4>
            </div>
            <p className="text-sm text-cyan-700">
              consent-service, billing-service, school-service, edu-search-service, ai-compliance-sdk
            </p>
          </div>
          <div className="p-4 bg-yellow-50 rounded-lg border border-yellow-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">🐍</span>
              <h4 className="font-medium text-yellow-800">Python Tests (~50)</h4>
            </div>
            <p className="text-sm text-yellow-700">
              backend, voice-service, klausur-service, geo-service
            </p>
          </div>
          <div className="p-4 bg-emerald-50 rounded-lg border border-emerald-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">🎯</span>
              <h4 className="font-medium text-emerald-800">BQAS Golden (97)</h4>
            </div>
            <p className="text-sm text-emerald-700">
              Validierte Referenz-Tests mit LLM-Judge fuer Intent-Erkennung
            </p>
          </div>
          <div className="p-4 bg-teal-50 rounded-lg border border-teal-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">📚</span>
              <h4 className="font-medium text-teal-800">BQAS RAG (~20)</h4>
            </div>
            <p className="text-sm text-teal-700">
              RAG-Judge Tests fuer Retrieval, Citations, Hallucination-Control
            </p>
          </div>
          <div className="p-4 bg-blue-50 rounded-lg border border-blue-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">📘</span>
              <h4 className="font-medium text-blue-800">TypeScript Jest (~8)</h4>
            </div>
            <p className="text-sm text-blue-700">
              Website Unit Tests fuer React-Komponenten
            </p>
          </div>
          <div className="p-4 bg-orange-50 rounded-lg border border-orange-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">⚡</span>
              <h4 className="font-medium text-orange-800">SDK Vitest (~43)</h4>
            </div>
            <p className="text-sm text-orange-700">
              AI Compliance SDK Unit Tests: Types, Export, Components, Reducer
            </p>
          </div>
          <div className="p-4 bg-purple-50 rounded-lg border border-purple-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">🎭</span>
              <h4 className="font-medium text-purple-800">SDK Playwright (~25)</h4>
            </div>
            <p className="text-sm text-purple-700">
              SDK E2E Tests: Navigation, Workflow, Command Bar, Export
            </p>
          </div>
          <div className="p-4 bg-slate-50 rounded-lg border border-slate-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">🌐</span>
              <h4 className="font-medium text-slate-800">Website E2E (~5)</h4>
            </div>
            <p className="text-sm text-slate-700">
              End-to-End Tests fuer kritische User Flows
            </p>
          </div>
          <div className="p-4 bg-indigo-50 rounded-lg border border-indigo-200">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-xl">🔗</span>
              <h4 className="font-medium text-indigo-800">Integration Tests (~15)</h4>
            </div>
            <p className="text-sm text-indigo-700">
              Docker Compose basierte E2E-Tests mit Backend, Consent-Service, DB
            </p>
          </div>
        </div>
      </div>

      <div className="bg-white rounded-xl border border-slate-200 p-6">
        <h3 className="text-lg font-semibold text-slate-900 mb-4">Architektur</h3>
        <pre className="bg-slate-50 p-4 rounded-lg text-xs overflow-x-auto">
{`┌────────────────────────────────────────────────────────────────────┐
│               Admin-v2 Test Dashboard                               │
│               /infrastructure/tests                                 │
├────────────────────────────────────────────────────────────────────┤
│  ┌────────────┐  ┌────────────┐  ┌────────────┐  ┌─────────────┐  │
│  │ Unit Tests │  │ SDK Tests  │  │   BQAS     │  │ E2E Tests   │  │
│  │  (Go, Py)  │  │  (Vitest)  │  │ (LLM/RAG)  │  │ (Playwright)│  │
│  └────────────┘  └────────────┘  └────────────┘  └─────────────┘  │
│        │               │               │               │           │
│        ▼               ▼               ▼               ▼           │
│  ┌──────────────────────────────────────────────────────────────┐ │
│  │                    Test Registry API                          │ │
│  │              /backend/api/tests/registry.py                   │ │
│  └──────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────┘

Tests bleiben wo sie sind:
- /consent-service/internal/**/*_test.go
- /backend/tests/test_*.py
- /voice-service/tests/bqas/
- /admin-v2/components/sdk/__tests__/*.test.ts   (Vitest)
- /admin-v2/e2e/specs/*.spec.ts                  (Playwright)`}
        </pre>
      </div>

      {/* CI/CD Workflow Anleitung */}
      <div className="bg-blue-50 rounded-xl border border-blue-200 p-6">
        <h3 className="text-lg font-semibold text-blue-900 mb-4 flex items-center gap-2">
          <svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
          </svg>
          CI/CD Integration
        </h3>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          <div>
            <h4 className="font-medium text-blue-800 mb-2">🤖 Automatisch (bei jedem Push/PR)</h4>
            <ul className="space-y-2 text-sm text-blue-700">
              <li className="flex items-start gap-2">
                <span className="text-green-500 mt-1">✓</span>
                <span><strong>Unit Tests</strong> - Go & Python Tests laufen automatisch</span>
              </li>
              <li className="flex items-start gap-2">
                <span className="text-green-500 mt-1">✓</span>
                <span><strong>Test-Ergebnisse</strong> - Werden ans Dashboard gesendet</span>
              </li>
              <li className="flex items-start gap-2">
                <span className="text-green-500 mt-1">✓</span>
                <span><strong>Backlog</strong> - Fehlgeschlagene Tests erscheinen hier</span>
              </li>
              <li className="flex items-start gap-2">
                <span className="text-green-500 mt-1">✓</span>
                <span><strong>Linting</strong> - Code-Qualitaet bei PRs pruefen</span>
              </li>
            </ul>
          </div>

          <div>
            <h4 className="font-medium text-blue-800 mb-2">👆 Manuell (Button oder Tag)</h4>
            <ul className="space-y-2 text-sm text-blue-700">
              <li className="flex items-start gap-2">
                <span className="text-orange-500 mt-1">▶</span>
                <span><strong>Docker Builds</strong> - Container erstellen</span>
              </li>
              <li className="flex items-start gap-2">
                <span className="text-orange-500 mt-1">▶</span>
                <span><strong>SBOM/Scans</strong> - Sicherheitsanalyse ausfuehren</span>
              </li>
              <li className="flex items-start gap-2">
                <span className="text-orange-500 mt-1">▶</span>
                <span><strong>Deployment</strong> - In Produktion deployen</span>
              </li>
              <li className="flex items-start gap-2">
                <span className="text-orange-500 mt-1">▶</span>
                <span><strong>Pipeline starten</strong> - Im CI/CD Dashboard</span>
              </li>
            </ul>
          </div>
        </div>

        <div className="mt-4 pt-4 border-t border-blue-200">
          <p className="text-sm text-blue-600">
            <strong>Daten-Fluss:</strong> Gitea Actions → POST /api/tests/ci-result → PostgreSQL → Test Dashboard
          </p>
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <Link
          href="/ai/test-quality"
          className="p-4 bg-slate-50 rounded-lg border border-slate-200 hover:border-orange-300 hover:bg-orange-50 transition-colors"
        >
          <div className="flex items-center gap-3">
            <svg className="w-8 h-8 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
            <div>
              <p className="font-medium text-slate-900">BQAS Dashboard</p>
              <p className="text-xs text-slate-500">Detaillierte BQAS-Metriken und Trend-Analyse</p>
            </div>
          </div>
        </Link>
        <Link
          href="/infrastructure/ci-cd"
          className="p-4 bg-slate-50 rounded-lg border border-slate-200 hover:border-orange-300 hover:bg-orange-50 transition-colors"
        >
          <div className="flex items-center gap-3">
            <svg className="w-8 h-8 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
            <div>
              <p className="font-medium text-slate-900">CI/CD Pipelines</p>
              <p className="text-xs text-slate-500">Gitea Actions und automatische Test-Planung</p>
            </div>
          </div>
        </Link>
      </div>
    </div>
  )
}

// ==============================================================================
// Backlog Component
// ==============================================================================

function FailedTestCard({
  test,
  onStatusChange,
  onPriorityChange,
  priority = 'medium',
  failureCount = 1,
}: {
  test: FailedTest
  onStatusChange: (testId: string, status: string) => void
  onPriorityChange?: (testId: string, priority: string) => void
  priority?: BacklogPriority
  failureCount?: number
}) {
  const errorTypeColors: Record<string, string> = {
    assertion: 'bg-amber-100 text-amber-700',
    nil_pointer: 'bg-red-100 text-red-700',
    type_error: 'bg-purple-100 text-purple-700',
    network: 'bg-blue-100 text-blue-700',
    timeout: 'bg-orange-100 text-orange-700',
    logic_error: 'bg-slate-100 text-slate-700',
    unknown: 'bg-slate-100 text-slate-700',
  }

  const statusColors: Record<string, string> = {
    open: 'bg-red-100 text-red-700',
    in_progress: 'bg-blue-100 text-blue-700',
    fixed: 'bg-emerald-100 text-emerald-700',
    wont_fix: 'bg-slate-100 text-slate-700',
    flaky: 'bg-purple-100 text-purple-700',
  }

  const priorityColors: Record<string, string> = {
    critical: 'bg-red-500 text-white',
    high: 'bg-orange-500 text-white',
    medium: 'bg-yellow-500 text-white',
    low: 'bg-slate-400 text-white',
  }

  const priorityLabels: Record<string, string> = {
    critical: '!!! Kritisch',
    high: '!! Hoch',
    medium: '! Mittel',
    low: 'Niedrig',
  }

  return (
    <div className="bg-white rounded-lg border border-slate-200 p-4 hover:border-red-300 transition-colors">
      <div className="flex items-start justify-between mb-3">
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 mb-1 flex-wrap">
            <span className={`px-2 py-0.5 rounded text-xs font-medium ${priorityColors[priority]}`}>
              {priorityLabels[priority]}
            </span>
            <span className={`px-2 py-0.5 rounded text-xs font-medium ${errorTypeColors[test.error_type] || errorTypeColors.unknown}`}>
              {test.error_type.replace('_', ' ')}
            </span>
            <span className="text-xs text-slate-400">{test.service}</span>
            {failureCount > 1 && (
              <span className="px-1.5 py-0.5 rounded bg-red-100 text-red-600 text-xs font-medium">
                {failureCount}x fehlgeschlagen
              </span>
            )}
          </div>
          <h4 className="font-mono text-sm font-medium text-slate-900 truncate" title={test.name}>
            {test.name}
          </h4>
          <p className="text-xs text-slate-500 truncate" title={test.file_path}>
            {test.file_path}
          </p>
        </div>
        <div className="flex flex-col gap-1 ml-2">
          <select
            value={test.status}
            onChange={(e) => onStatusChange(test.id, e.target.value)}
            className={`px-2 py-1 rounded text-xs font-medium cursor-pointer border-0 ${statusColors[test.status]}`}
          >
            <option value="open">Offen</option>
            <option value="in_progress">In Arbeit</option>
            <option value="fixed">Behoben</option>
            <option value="wont_fix">Ignoriert</option>
            <option value="flaky">Flaky</option>
          </select>
          {onPriorityChange && (
            <select
              value={priority}
              onChange={(e) => onPriorityChange(test.id, e.target.value)}
              className="px-2 py-1 rounded text-xs font-medium cursor-pointer border border-slate-200"
            >
              <option value="critical">Kritisch</option>
              <option value="high">Hoch</option>
              <option value="medium">Mittel</option>
              <option value="low">Niedrig</option>
            </select>
          )}
        </div>
      </div>

      <div className="bg-red-50 rounded-lg p-3 mb-3">
        <p className="text-sm text-red-800 font-medium mb-1">Fehlermeldung:</p>
        <p className="text-xs text-red-700 font-mono break-words">
          {test.error_message || 'Keine Details verfuegbar'}
        </p>
      </div>

      {test.suggestion && (
        <div className="bg-emerald-50 rounded-lg p-3">
          <p className="text-sm text-emerald-800 font-medium mb-1">💡 Loesungsvorschlag:</p>
          <p className="text-xs text-emerald-700">
            {test.suggestion}
          </p>
        </div>
      )}

      <div className="mt-3 pt-3 border-t border-slate-100 flex items-center justify-between text-xs text-slate-400">
        <span>Zuletzt fehlgeschlagen: {test.last_failed ? new Date(test.last_failed).toLocaleString('de-DE') : 'Unbekannt'}</span>
        <button
          className="text-orange-600 hover:text-orange-700 font-medium"
          onClick={() => {
            navigator.clipboard.writeText(test.id)
          }}
        >
          ID kopieren
        </button>
      </div>
    </div>
  )
}

function BacklogTab({
  failedTests,
  onStatusChange,
  onPriorityChange,
  isLoading,
  backlogItems,
  usePostgres = false,
}: {
  failedTests: FailedTest[]
  onStatusChange: (testId: string, status: string) => void
  onPriorityChange?: (testId: string, priority: string) => void
  isLoading: boolean
  backlogItems?: BacklogItem[]
  usePostgres?: boolean
}) {
  const [filterStatus, setFilterStatus] = useState<string>('open')
  const [filterService, setFilterService] = useState<string>('all')
  const [filterPriority, setFilterPriority] = useState<string>('all')
  const [llmAutoAnalysis, setLlmAutoAnalysis] = useState<boolean>(true)
  const [llmRouting, setLlmRouting] = useState<LLMRoutingOption>('smart_routing')

  // Nutze PostgreSQL-Backlog wenn verfuegbar, sonst Legacy
  const items = usePostgres && backlogItems ? backlogItems : failedTests

  // Gruppiere nach Service
  const services = [...new Set(items.map(t => 'service' in t ? t.service : (t as BacklogItem).service))]

  // Filtere Items
  const filteredItems = items.filter(item => {
    const status = 'status' in item ? item.status : 'open'
    const service = 'service' in item ? item.service : ''
    const priority = 'priority' in item ? (item as BacklogItem).priority : 'medium'

    if (filterStatus !== 'all' && status !== filterStatus) return false
    if (filterService !== 'all' && service !== filterService) return false
    if (filterPriority !== 'all' && priority !== filterPriority) return false
    return true
  })

  // Zaehle nach Status
  const openCount = items.filter(t => t.status === 'open').length
  const inProgressCount = items.filter(t => t.status === 'in_progress').length
  const fixedCount = items.filter(t => t.status === 'fixed').length
  const flakyCount = items.filter(t => t.status === 'flaky').length

  // Zaehle nach Prioritaet (nur bei PostgreSQL)
  const criticalCount = backlogItems?.filter(t => t.priority === 'critical').length || 0
  const highCount = backlogItems?.filter(t => t.priority === 'high').length || 0

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-12">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-orange-600"></div>
      </div>
    )
  }

  // Konvertiere BacklogItem zu FailedTest fuer die Anzeige
  const convertToFailedTest = (item: BacklogItem): FailedTest => ({
    id: String(item.id),
    name: item.test_name,
    service: item.service,
    file_path: item.test_file || '',
    error_message: item.error_message || '',
    error_type: item.error_type || 'unknown',
    suggestion: item.fix_suggestion || '',
    run_id: '',
    last_failed: item.last_failed_at,
    status: item.status,
  })

  return (
    <div className="space-y-6">
      {/* Stats */}
      <div className="grid grid-cols-2 md:grid-cols-5 gap-4">
        <div className="bg-red-50 border border-red-200 rounded-xl p-4">
          <p className="text-2xl font-bold text-red-600">{openCount}</p>
          <p className="text-sm text-red-700">Offene Fehler</p>
        </div>
        <div className="bg-blue-50 border border-blue-200 rounded-xl p-4">
          <p className="text-2xl font-bold text-blue-600">{inProgressCount}</p>
          <p className="text-sm text-blue-700">In Arbeit</p>
        </div>
        <div className="bg-emerald-50 border border-emerald-200 rounded-xl p-4">
          <p className="text-2xl font-bold text-emerald-600">{fixedCount}</p>
          <p className="text-sm text-emerald-700">Behoben</p>
        </div>
        <div className="bg-purple-50 border border-purple-200 rounded-xl p-4">
          <p className="text-2xl font-bold text-purple-600">{flakyCount}</p>
          <p className="text-sm text-purple-700">Flaky</p>
        </div>
        {usePostgres && criticalCount + highCount > 0 && (
          <div className="bg-orange-50 border border-orange-200 rounded-xl p-4">
            <p className="text-2xl font-bold text-orange-600">{criticalCount + highCount}</p>
            <p className="text-sm text-orange-700">Kritisch/Hoch</p>
          </div>
        )}
      </div>

      {/* PostgreSQL Badge */}
      {usePostgres && (
        <div className="flex items-center gap-2 px-3 py-1.5 bg-emerald-50 border border-emerald-200 rounded-lg w-fit">
          <svg className="w-4 h-4 text-emerald-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
          </svg>
          <span className="text-xs text-emerald-700 font-medium">Persistente Speicherung aktiv (PostgreSQL)</span>
        </div>
      )}

      {/* LLM Analysis Toggle */}
      <div className="bg-gradient-to-r from-violet-50 to-purple-50 border border-violet-200 rounded-xl p-4">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 bg-violet-100 rounded-lg flex items-center justify-center">
              <svg className="w-5 h-5 text-violet-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
              </svg>
            </div>
            <div>
              <h4 className="font-medium text-slate-800">Automatische LLM-Analyse</h4>
              <p className="text-xs text-slate-500">KI-gestuetzte Fix-Vorschlaege fuer Backlog-Eintraege</p>
            </div>
          </div>
          <label className="relative inline-flex items-center cursor-pointer">
            <input
              type="checkbox"
              checked={llmAutoAnalysis}
              onChange={(e) => setLlmAutoAnalysis(e.target.checked)}
              className="sr-only peer"
            />
            <div className="w-11 h-6 bg-slate-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-violet-300 rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-violet-600"></div>
          </label>
        </div>

        {llmAutoAnalysis && (
          <div className="mt-4 pt-4 border-t border-violet-200">
            <p className="text-xs text-slate-600 mb-3">LLM-Routing Strategie:</p>
            <div className="flex flex-wrap gap-2">
              <label className={`flex items-center gap-2 px-3 py-2 rounded-lg border cursor-pointer transition-colors ${
                llmRouting === 'local_only'
                  ? 'bg-violet-100 border-violet-300 text-violet-800'
                  : 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
              }`}>
                <input
                  type="radio"
                  name="llm-routing"
                  value="local_only"
                  checked={llmRouting === 'local_only'}
                  onChange={() => setLlmRouting('local_only')}
                  className="sr-only"
                />
                <span className="text-sm font-medium">Nur lokales 32B LLM</span>
                <span className="text-xs px-1.5 py-0.5 bg-emerald-100 text-emerald-700 rounded">DSGVO</span>
              </label>
              <label className={`flex items-center gap-2 px-3 py-2 rounded-lg border cursor-pointer transition-colors ${
                llmRouting === 'claude_preferred'
                  ? 'bg-violet-100 border-violet-300 text-violet-800'
                  : 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
              }`}>
                <input
                  type="radio"
                  name="llm-routing"
                  value="claude_preferred"
                  checked={llmRouting === 'claude_preferred'}
                  onChange={() => setLlmRouting('claude_preferred')}
                  className="sr-only"
                />
                <span className="text-sm font-medium">Claude bevorzugt</span>
                <span className="text-xs px-1.5 py-0.5 bg-blue-100 text-blue-700 rounded">Qualitaet</span>
              </label>
              <label className={`flex items-center gap-2 px-3 py-2 rounded-lg border cursor-pointer transition-colors ${
                llmRouting === 'smart_routing'
                  ? 'bg-violet-100 border-violet-300 text-violet-800'
                  : 'bg-white border-slate-200 text-slate-600 hover:bg-slate-50'
              }`}>
                <input
                  type="radio"
                  name="llm-routing"
                  value="smart_routing"
                  checked={llmRouting === 'smart_routing'}
                  onChange={() => setLlmRouting('smart_routing')}
                  className="sr-only"
                />
                <span className="text-sm font-medium">Smart Routing</span>
                <span className="text-xs px-1.5 py-0.5 bg-amber-100 text-amber-700 rounded">Empfohlen</span>
              </label>
            </div>
            <p className="text-xs text-slate-500 mt-2">
              {llmRouting === 'local_only' && 'Alle Analysen werden mit Qwen2.5-32B lokal durchgefuehrt. Keine Daten verlassen den Server.'}
              {llmRouting === 'claude_preferred' && 'Verwendet Claude fuer beste Fix-Qualitaet. Nur Code-Snippets werden uebertragen.'}
              {llmRouting === 'smart_routing' && 'Privacy Classifier entscheidet automatisch: Sensitive Daten → lokal, Code → Claude.'}
            </p>
          </div>
        )}
      </div>

      {/* Filter */}
      <div className="flex flex-wrap gap-4 items-center">
        <div>
          <label className="text-sm text-slate-600 mr-2">Status:</label>
          <select
            value={filterStatus}
            onChange={(e) => setFilterStatus(e.target.value)}
            className="px-3 py-1.5 rounded-lg border border-slate-200 text-sm"
          >
            <option value="all">Alle</option>
            <option value="open">Offen ({openCount})</option>
            <option value="in_progress">In Arbeit ({inProgressCount})</option>
            <option value="fixed">Behoben ({fixedCount})</option>
            <option value="flaky">Flaky ({flakyCount})</option>
            <option value="wont_fix">Ignoriert</option>
          </select>
        </div>
        <div>
          <label className="text-sm text-slate-600 mr-2">Service:</label>
          <select
            value={filterService}
            onChange={(e) => setFilterService(e.target.value)}
            className="px-3 py-1.5 rounded-lg border border-slate-200 text-sm"
          >
            <option value="all">Alle Services</option>
            {services.map(s => (
              <option key={s} value={s}>{s}</option>
            ))}
          </select>
        </div>
        {usePostgres && (
          <div>
            <label className="text-sm text-slate-600 mr-2">Prioritaet:</label>
            <select
              value={filterPriority}
              onChange={(e) => setFilterPriority(e.target.value)}
              className="px-3 py-1.5 rounded-lg border border-slate-200 text-sm"
            >
              <option value="all">Alle</option>
              <option value="critical">Kritisch</option>
              <option value="high">Hoch</option>
              <option value="medium">Mittel</option>
              <option value="low">Niedrig</option>
            </select>
          </div>
        )}
        <div className="ml-auto text-sm text-slate-500">
          {filteredItems.length} von {items.length} Tests angezeigt
        </div>
      </div>

      {/* Test-Liste */}
      {filteredItems.length === 0 ? (
        <div className="text-center py-12 bg-emerald-50 rounded-xl border border-emerald-200">
          <svg className="w-12 h-12 mx-auto text-emerald-400 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          <p className="text-emerald-700 font-medium">
            {filterStatus === 'open' ? 'Keine offenen Fehler! 🎉' : 'Keine Tests mit diesem Filter gefunden.'}
          </p>
          {filterStatus === 'open' && (
            <p className="text-sm text-emerald-600 mt-2">
              Alle Tests bestanden. Bereit fuer Go-Live!
            </p>
          )}
        </div>
      ) : (
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
          {filteredItems.map((item) => {
            const test = usePostgres && 'test_name' in item
              ? convertToFailedTest(item as BacklogItem)
              : item as FailedTest
            const priority = usePostgres && 'priority' in item
              ? (item as BacklogItem).priority
              : 'medium'
            const failureCount = usePostgres && 'failure_count' in item
              ? (item as BacklogItem).failure_count
              : 1

            return (
              <FailedTestCard
                key={test.id}
                test={test}
                onStatusChange={onStatusChange}
                onPriorityChange={onPriorityChange}
                priority={priority}
                failureCount={failureCount}
              />
            )
          })}
        </div>
      )}

      {/* Info */}
      <div className="bg-blue-50 border border-blue-200 rounded-xl p-4">
        <div className="flex items-start gap-3">
          <svg className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          <div>
            <p className="text-sm text-blue-800 font-medium">Workflow fuer fehlgeschlagene Tests:</p>
            <ol className="text-xs text-blue-700 mt-2 space-y-1 list-decimal list-inside">
              <li>Markiere den Test als "In Arbeit" wenn du daran arbeitest</li>
              <li>Analysiere die Fehlermeldung und den Loesungsvorschlag</li>
              <li>Behebe den Fehler im Code</li>
              <li>Fuehre den Test erneut aus (Button im Service-Tab)</li>
              <li>Markiere als "Behoben" wenn der Test besteht</li>
              {usePostgres && <li>Setze "Flaky" fuer sporadisch fehlschlagende Tests</li>}
            </ol>
          </div>
        </div>
      </div>
    </div>
  )
}

// ==============================================================================
// Main Component
// ==============================================================================

export default function TestDashboardPage() {
  const [activeTab, setActiveTab] = useState<TabType>('overview')
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  // Toast state
  const [toasts, setToasts] = useState<Toast[]>([])
  const toastIdRef = useRef(0)

  const addToast = useCallback((type: Toast['type'], message: string) => {
    const id = ++toastIdRef.current
    setToasts((prev) => [...prev, { id, type, message }])
    if (type !== 'loading') {
      setTimeout(() => {
        setToasts((prev) => prev.filter((t) => t.id !== id))
      }, 5000)
    }
    return id
  }, [])

  const removeToast = useCallback((id: number) => {
    setToasts((prev) => prev.filter((t) => t.id !== id))
  }, [])

  const updateToast = useCallback((id: number, type: Toast['type'], message: string) => {
    setToasts((prev) => prev.map((t) => (t.id === id ? { ...t, type, message } : t)))
    if (type !== 'loading') {
      setTimeout(() => {
        setToasts((prev) => prev.filter((t) => t.id !== id))
      }, 5000)
    }
  }, [])

  // Data states
  const [services, setServices] = useState<ServiceTestInfo[]>([])
  const [stats, setStats] = useState<TestRegistryStats | null>(null)
  const [coverage, setCoverage] = useState<CoverageData[]>([])
  const [testRuns, setTestRuns] = useState<TestRun[]>([])
  const [failedTests, setFailedTests] = useState<FailedTest[]>([])
  const [backlogItems, setBacklogItems] = useState<BacklogItem[]>([])
  const [usePostgres, setUsePostgres] = useState(false)

  // Running states
  const [runningServices, setRunningServices] = useState<Set<string>>(new Set())

  // Progress states fuer laufende Tests
  const [serviceProgress, setServiceProgress] = useState<Record<string, {
    current_file: string
    files_done: number
    files_total: number
    passed: number
    failed: number
    status: string
  }>>({})

  // Demo data for when API is not available
  const DEMO_SERVICES: ServiceTestInfo[] = [
    { service: 'consent-service', display_name: 'Consent Service', port: 8081, language: 'go', total_tests: 22, passed_tests: 20, failed_tests: 2, skipped_tests: 0, pass_rate: 90.9, coverage_percent: 82.3, last_run: new Date().toISOString(), status: 'failed' },
    { service: 'backend', display_name: 'Python Backend', port: 8000, language: 'python', total_tests: 40, passed_tests: 38, failed_tests: 2, skipped_tests: 0, pass_rate: 95.0, coverage_percent: 75.1, last_run: new Date().toISOString(), status: 'failed' },
    { service: 'klausur-service', display_name: 'Klausur Service', port: 8086, language: 'python', total_tests: 8, passed_tests: 8, failed_tests: 0, skipped_tests: 0, pass_rate: 100, coverage_percent: 71.2, last_run: new Date().toISOString(), status: 'passed' },
    { service: 'billing-service', display_name: 'Billing Service', port: 8082, language: 'go', total_tests: 5, passed_tests: 5, failed_tests: 0, skipped_tests: 0, pass_rate: 100, coverage_percent: 78.5, last_run: new Date().toISOString(), status: 'passed' },
    { service: 'school-service', display_name: 'School Service', port: 8084, language: 'go', total_tests: 6, passed_tests: 6, failed_tests: 0, skipped_tests: 0, pass_rate: 100, coverage_percent: 81.4, last_run: new Date().toISOString(), status: 'passed' },
    { service: 'sdk-unit', display_name: 'SDK Unit Tests (Vitest)', port: undefined, language: 'typescript', total_tests: 43, passed_tests: 43, failed_tests: 0, skipped_tests: 0, pass_rate: 100, coverage_percent: 85.2, last_run: new Date().toISOString(), status: 'passed' },
    { service: 'sdk-e2e', display_name: 'SDK E2E Tests (Playwright)', port: undefined, language: 'typescript', total_tests: 25, passed_tests: 25, failed_tests: 0, skipped_tests: 0, pass_rate: 100, coverage_percent: undefined, last_run: new Date().toISOString(), status: 'passed' },
    { service: 'integration-tests', display_name: 'Integration Tests', port: undefined, language: 'python', total_tests: 15, passed_tests: 15, failed_tests: 0, skipped_tests: 0, pass_rate: 100, coverage_percent: undefined, last_run: new Date().toISOString(), status: 'passed' },
  ]

  const DEMO_STATS: TestRegistryStats = {
    total_tests: 278,
    total_passed: 263,
    total_failed: 15,
    total_skipped: 0,
    overall_pass_rate: 94.6,
    average_coverage: 78.5,
    services_count: 11,
    by_category: { unit: 118, bqas: 117, e2e: 30, integration: 15 },
    by_framework: { go_test: 57, pytest: 68, bqas_golden: 97, bqas_rag: 20, jest: 8, vitest: 43, playwright: 30 },
  }

  // Fetch data
  const fetchData = useCallback(async () => {
    setIsLoading(true)
    setError(null)

    try {
      const registryResponse = await fetch(`${API_BASE}/registry`)
      if (registryResponse.ok) {
        const data = await registryResponse.json()
        setServices(data.services || DEMO_SERVICES)
        setStats(data.stats || DEMO_STATS)
      } else {
        setServices(DEMO_SERVICES)
        setStats(DEMO_STATS)
      }

      const coverageResponse = await fetch(`${API_BASE}/coverage`)
      if (coverageResponse.ok) {
        const data = await coverageResponse.json()
        setCoverage(data.services || [])
      } else {
        setCoverage(DEMO_SERVICES.filter(s => s.coverage_percent).map(s => ({
          service: s.service,
          display_name: s.display_name,
          coverage_percent: s.coverage_percent!,
          language: s.language,
        })))
      }

      const runsResponse = await fetch(`${API_BASE}/runs`)
      if (runsResponse.ok) {
        const data = await runsResponse.json()
        setTestRuns(data.runs || [])
      }

      // Lade fehlgeschlagene Tests fuer Backlog
      const failedResponse = await fetch(`${API_BASE}/failed`)
      if (failedResponse.ok) {
        const data = await failedResponse.json()
        setFailedTests(data.tests || [])
      }

      // Versuche PostgreSQL-Backlog zu laden (neue API)
      try {
        const backlogResponse = await fetch(`${API_BASE}/backlog`)
        if (backlogResponse.ok) {
          const data = await backlogResponse.json()
          if (data.items && data.items.length > 0) {
            setBacklogItems(data.items)
            setUsePostgres(true)
          }
        }
      } catch {
        // PostgreSQL nicht verfuegbar, nutze Legacy
        setUsePostgres(false)
      }

    } catch (err) {
      console.error('Failed to fetch test registry data:', err)
      setServices(DEMO_SERVICES)
      setStats(DEMO_STATS)
      setCoverage(DEMO_SERVICES.filter(s => s.coverage_percent).map(s => ({
        service: s.service,
        display_name: s.display_name,
        coverage_percent: s.coverage_percent!,
        language: s.language,
      })))
    } finally {
      setIsLoading(false)
    }
  }, [])

  useEffect(() => {
    fetchData()
  }, [fetchData])

  // Update failed test status
  const updateTestStatus = async (testId: string, status: string) => {
    try {
      // Nutze PostgreSQL-Endpoint wenn verfuegbar
      const endpoint = usePostgres
        ? `${API_BASE}/backlog/${testId}/status`
        : `${API_BASE}/failed/${encodeURIComponent(testId)}/status?status=${status}`

      const response = await fetch(endpoint, {
        method: 'POST',
        headers: usePostgres ? { 'Content-Type': 'application/json' } : undefined,
        body: usePostgres ? JSON.stringify({ status }) : undefined,
      })

      if (response.ok) {
        // Aktualisiere lokalen State
        if (usePostgres) {
          setBacklogItems(prev =>
            prev.map(t => String(t.id) === testId ? { ...t, status: status as any } : t)
          )
        }
        setFailedTests(prev =>
          prev.map(t => t.id === testId ? { ...t, status: status as any } : t)
        )
        addToast('success', `Test-Status auf "${status}" gesetzt`)
      }
    } catch (err) {
      console.error('Failed to update test status:', err)
      // Trotzdem lokal aktualisieren fuer bessere UX
      setFailedTests(prev =>
        prev.map(t => t.id === testId ? { ...t, status: status as any } : t)
      )
      if (usePostgres) {
        setBacklogItems(prev =>
          prev.map(t => String(t.id) === testId ? { ...t, status: status as any } : t)
        )
      }
    }
  }

  // Update failed test priority (nur PostgreSQL)
  const updateTestPriority = async (testId: string, priority: string) => {
    if (!usePostgres) return

    try {
      const response = await fetch(`${API_BASE}/backlog/${testId}/priority`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ priority }),
      })

      if (response.ok) {
        setBacklogItems(prev =>
          prev.map(t => String(t.id) === testId ? { ...t, priority: priority as any } : t)
        )
        addToast('success', `Prioritaet auf "${priority}" gesetzt`)
      }
    } catch (err) {
      console.error('Failed to update test priority:', err)
      // Trotzdem lokal aktualisieren
      setBacklogItems(prev =>
        prev.map(t => String(t.id) === testId ? { ...t, priority: priority as any } : t)
      )
    }
  }

  // Run tests mit Progress-Polling
  const runTests = async (service: string) => {
    setRunningServices((prev) => new Set(prev).add(service))
    const loadingToast = addToast('loading', `Tests fuer ${service} werden gestartet...`)

    // Progress-Polling starten
    let pollInterval: NodeJS.Timeout | null = null
    const pollProgress = async () => {
      try {
        const progressResponse = await fetch(`${API_BASE}/progress/${service}`)
        if (progressResponse.ok) {
          const progress = await progressResponse.json()
          setServiceProgress((prev) => ({
            ...prev,
            [service]: progress,
          }))

          // Toast-Message mit aktuellem Fortschritt aktualisieren
          if (progress.status === 'running' && progress.files_total > 0) {
            const percent = Math.round((progress.files_done / progress.files_total) * 100)
            const toastMsg = `${service}: ${progress.current_file} (${progress.passed} bestanden, ${progress.failed} fehler)`
            updateToast(loadingToast, 'loading', toastMsg)
          }
        }
      } catch (err) {
        // Ignore polling errors
      }
    }

    // Start polling (alle 1 Sekunde)
    pollInterval = setInterval(pollProgress, 1000)

    try {
      const response = await fetch(`${API_BASE}/run/${service}`, {
        method: 'POST',
      })

      if (response.ok) {
        const result = await response.json()
        // Warte kurz und pruefe finalen Progress
        await new Promise(resolve => setTimeout(resolve, 500))
        await pollProgress()
        const finalProgress = serviceProgress[service]
        const passedMsg = finalProgress ? `${finalProgress.passed} bestanden, ${finalProgress.failed} fehler` : 'abgeschlossen'
        updateToast(loadingToast, 'success', `${service}: Tests ${passedMsg}`)
        await fetchData()
      } else {
        updateToast(loadingToast, 'info', `${service}: Demo-Modus (API nicht verfuegbar)`)
      }
    } catch (err) {
      console.error('Failed to run tests:', err)
      updateToast(loadingToast, 'info', `${service}: Demo-Modus (API nicht verfuegbar)`)
    } finally {
      // Polling stoppen
      if (pollInterval) {
        clearInterval(pollInterval)
      }
      setRunningServices((prev) => {
        const next = new Set(prev)
        next.delete(service)
        return next
      })
      // Progress-Daten entfernen nach Abschluss
      setServiceProgress((prev) => {
        const next = { ...prev }
        delete next[service]
        return next
      })
    }
  }

  // Filter services by category
  const unitServices = services.filter(s => !s.service.startsWith('bqas-'))
  const bqasServices = services.filter(s => s.service.startsWith('bqas-'))

  // Tab content renderer
  const renderTabContent = () => {
    switch (activeTab) {
      case 'overview':
        return (
          <div className="space-y-6">
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
              <MetricCard
                title="Gesamt Tests"
                value={stats?.total_tests || 195}
                subtitle={`${stats?.services_count || 8} Services`}
                color="orange"
              />
              <MetricCard
                title="Pass Rate"
                value={`${stats?.overall_pass_rate?.toFixed(1) || 92.3}%`}
                subtitle={`${stats?.total_passed || 180} bestanden`}
                trend="up"
                color="green"
              />
              <MetricCard
                title="Fehlgeschlagen"
                value={stats?.total_failed || 15}
                subtitle="Tests mit Fehlern"
                color="red"
              />
              <MetricCard
                title="Coverage"
                value={`${stats?.average_coverage?.toFixed(1) || 76.8}%`}
                subtitle="Durchschnitt"
                color="purple"
              />
            </div>

            <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
              <div className="bg-white rounded-xl border border-slate-200 p-6">
                <h3 className="text-lg font-semibold text-slate-900 mb-4">Framework-Verteilung</h3>
                <FrameworkDistribution data={stats?.by_framework || {}} />
              </div>

              <div className="bg-white rounded-xl border border-slate-200 p-6">
                <h3 className="text-lg font-semibold text-slate-900 mb-4">Coverage nach Service</h3>
                <CoverageChart data={coverage} />
              </div>
            </div>

            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="text-lg font-semibold text-slate-900 mb-4">Service-Uebersicht</h3>
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
                {services.slice(0, 8).map((service) => (
                  <ServiceTestCard
                    key={service.service}
                    service={service}
                    onRun={runTests}
                    isRunning={runningServices.has(service.service)}
                    progress={serviceProgress[service.service]}
                  />
                ))}
              </div>
            </div>
          </div>
        )

      case 'unit':
        return (
          <div className="space-y-6">
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="text-lg font-semibold text-slate-900 mb-4">Unit Tests (Go & Python)</h3>
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {unitServices.map((service) => (
                  <ServiceTestCard
                    key={service.service}
                    service={service}
                    onRun={runTests}
                    isRunning={runningServices.has(service.service)}
                    progress={serviceProgress[service.service]}
                  />
                ))}
              </div>
            </div>
          </div>
        )

      case 'bqas':
        return (
          <div className="space-y-6">
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <div className="flex items-center justify-between mb-6">
                <div>
                  <h3 className="text-lg font-semibold text-slate-900">BQAS (LLM Quality Assurance)</h3>
                  <p className="text-sm text-slate-500">Golden Suite, RAG Tests und Synthetic Tests</p>
                </div>
                <Link
                  href="/ai/test-quality"
                  className="px-4 py-2 bg-orange-100 text-orange-700 rounded-lg text-sm font-medium hover:bg-orange-200 transition-colors"
                >
                  Vollstaendiges BQAS Dashboard →
                </Link>
              </div>

              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                {bqasServices.map((service) => (
                  <ServiceTestCard
                    key={service.service}
                    service={service}
                    onRun={runTests}
                    isRunning={runningServices.has(service.service)}
                    progress={serviceProgress[service.service]}
                  />
                ))}
              </div>
            </div>

            <div className="bg-blue-50 border border-blue-200 rounded-xl p-4">
              <div className="flex items-start gap-3">
                <svg className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
                <div>
                  <p className="text-sm text-blue-800">
                    <strong>Tipp:</strong> Das vollstaendige BQAS Dashboard unter <Link href="/ai/test-quality" className="underline">/ai/test-quality</Link> bietet
                    detaillierte Metriken, Trend-Analyse und Intent-spezifische Scores.
                  </p>
                </div>
              </div>
            </div>
          </div>
        )

      case 'history':
        return (
          <div className="bg-white rounded-xl border border-slate-200 p-6">
            <h3 className="text-lg font-semibold text-slate-900 mb-6">Test Run Historie</h3>
            <TestRunsTable runs={testRuns} />
          </div>
        )

      case 'backlog':
        return (
          <BacklogTab
            failedTests={failedTests}
            onStatusChange={updateTestStatus}
            onPriorityChange={usePostgres ? updateTestPriority : undefined}
            isLoading={isLoading}
            backlogItems={backlogItems}
            usePostgres={usePostgres}
          />
        )

      case 'guide':
        return <GuideTab />

      default:
        return null
    }
  }

  return (
    <div className="space-y-6">
      <ToastContainer toasts={toasts} onDismiss={removeToast} />

      <PagePurpose
        title="Test Dashboard"
        purpose="Zentrales Dashboard fuer alle 260+ Tests. Aggregiert Unit Tests (Go, Python), SDK Tests (Vitest), E2E Tests (Playwright) und BQAS Quality Tests aus allen Services ohne physische Migration."
        audience={['Entwickler', 'QA', 'DevOps']}
        architecture={{
          services: ['Python Backend (Port 8000)', 'Voice Service (Port 8091)', 'SDK Backend (Port 8085)'],
          databases: ['PostgreSQL', 'Qdrant'],
        }}
        relatedPages={[
          { name: 'BQAS Dashboard', href: '/ai/test-quality', description: 'Detaillierte LLM-Qualitaetsmetriken' },
          { name: 'CI/CD', href: '/infrastructure/ci-cd', description: 'Pipelines und Deployments' },
          { name: 'Security', href: '/infrastructure/security', description: 'DevSecOps Dashboard' },
          { name: 'Developer Portal', href: '/developers', description: 'SDK & API Dokumentation' },
        ]}
        collapsible={true}
        defaultCollapsed={true}
      />

      {/* DevOps Pipeline Sidebar */}
      <DevOpsPipelineSidebarResponsive currentTool="tests" />

      {error && (
        <div className="p-4 bg-red-50 border border-red-200 rounded-lg text-red-700 flex items-center gap-3">
          <svg className="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          <span>{error}</span>
          <button onClick={fetchData} className="ml-auto text-red-600 hover:text-red-800 text-sm font-medium">
            Erneut versuchen
          </button>
        </div>
      )}

      <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
        <div className="border-b border-slate-200">
          <nav className="flex gap-6 px-6">
            {[
              { id: 'overview', label: 'Uebersicht' },
              { id: 'unit', label: 'Unit Tests' },
              { id: 'bqas', label: 'BQAS' },
              { id: 'backlog', label: `Backlog (${failedTests.filter(t => t.status === 'open').length})`, highlight: failedTests.filter(t => t.status === 'open').length > 0, isBacklog: true },
              { id: 'history', label: 'Historie' },
              { id: 'guide', label: 'Anleitung' },
            ].map((tab) => (
              <button
                key={tab.id}
                onClick={() => setActiveTab(tab.id as TabType)}
                className={`py-4 text-sm font-medium border-b-2 transition-colors ${
                  activeTab === tab.id
                    ? 'border-orange-600 text-orange-600'
                    : tab.highlight
                      ? 'border-transparent text-blue-500 hover:text-blue-600'
                      : 'border-transparent text-slate-500 hover:text-slate-700'
                }`}
              >
                {tab.label}
              </button>
            ))}
          </nav>
        </div>

        <div className="p-6">
          {isLoading ? (
            <div className="flex items-center justify-center py-12">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-orange-600"></div>
            </div>
          ) : (
            renderTabContent()
          )}
        </div>
      </div>

      <div className="flex items-center justify-between text-sm text-slate-500 px-2">
        <div>
          <span className="font-medium">Test Registry:</span> /api/tests
        </div>
        <div className="flex items-center gap-4">
          <Link href="/ai/test-quality" className="text-orange-600 hover:text-orange-700">
            BQAS Details
          </Link>
          <Link href="/infrastructure/ci-cd" className="text-orange-600 hover:text-orange-700">
            CI/CD Pipelines
          </Link>
        </div>
      </div>

      <style jsx>{`
        @keyframes slide-in {
          from {
            transform: translateX(100%);
            opacity: 0;
          }
          to {
            transform: translateX(0);
            opacity: 1;
          }
        }
        .animate-slide-in {
          animation: slide-in 0.3s ease-out;
        }
      `}</style>
    </div>
  )
}
