'use client'

import { useState, useEffect, useCallback, useRef } from 'react'
import type {
  ServiceTestInfo,
  TestRegistryStats,
  TestRun,
  CoverageData,
  TabType,
  Toast,
  FailedTest,
  BacklogItem,
  ServiceProgress,
} from '../types'

const API_BASE = '/api/tests'

// 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 },
}

export function useTestDashboard() {
  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, ServiceProgress>>({})

  // 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 {
      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) {
        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)
      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)
      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,
          }))

          if (progress.status === 'running' && progress.files_total > 0) {
            const toastMsg = `${service}: ${progress.current_file} (${progress.passed} bestanden, ${progress.failed} fehler)`
            updateToast(loadingToast, 'loading', toastMsg)
          }
        }
      } catch (err) {
        // Ignore polling errors
      }
    }

    pollInterval = setInterval(pollProgress, 1000)

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

      if (response.ok) {
        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 {
      if (pollInterval) {
        clearInterval(pollInterval)
      }
      setRunningServices((prev) => {
        const next = new Set(prev)
        next.delete(service)
        return next
      })
      setServiceProgress((prev) => {
        const next = { ...prev }
        delete next[service]
        return next
      })
    }
  }

  return {
    activeTab,
    setActiveTab,
    isLoading,
    error,
    toasts,
    removeToast,
    services,
    stats,
    coverage,
    testRuns,
    failedTests,
    backlogItems,
    usePostgres,
    runningServices,
    serviceProgress,
    fetchData,
    updateTestStatus,
    updateTestPriority,
    runTests,
  }
}
