'use client'

import { useState, useEffect, useCallback, useRef } from 'react'
import type {
  ServiceTestInfo,
  TestRegistryStats,
  TestRun,
  CoverageData,
  TabType,
  Toast,
  FailedTest,
  BacklogItem,
} from '../types'
import { API_BASE, DEMO_SERVICES, DEMO_STATS } from '../_lib/constants'
import type { ServiceProgress } from '../_components/ServiceTestCard'

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 {
      // 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 toastMsg = `${service}: ${progress.current_file} (${progress.passed} bestanden, ${progress.failed} fehler)`
            updateToast(loadingToast, 'loading', toastMsg)
          }
        }
      } catch {
        // 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) {
        // 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-'))

  return {
    // Tab
    activeTab,
    setActiveTab,
    // Loading / Error
    isLoading,
    error,
    fetchData,
    // Toast
    toasts,
    removeToast,
    // Data
    services,
    stats,
    coverage,
    testRuns,
    failedTests,
    backlogItems,
    usePostgres,
    // Running
    runningServices,
    serviceProgress,
    // Actions
    updateTestStatus,
    updateTestPriority,
    runTests,
    // Derived
    unitServices,
    bqasServices,
  }
}
