'use client' import { useState, useEffect, useCallback } from 'react' import { Source, ScraperStatus, ScrapeResult, PDFDocument, PDFExtractionResult, BACKEND_URL, } from './types' export function useComplianceScraper() { const [activeTab, setActiveTab] = useState<'sources' | 'pdf' | 'status' | 'logs'>('sources') const [sources, setSources] = useState([]) const [pdfDocuments, setPdfDocuments] = useState([]) const [status, setStatus] = useState(null) const [loading, setLoading] = useState(true) const [scraping, setScraping] = useState(false) const [extracting, setExtracting] = useState(false) const [error, setError] = useState(null) const [success, setSuccess] = useState(null) const [results, setResults] = useState([]) const [pdfResult, setPdfResult] = useState(null) const fetchSources = useCallback(async () => { try { const res = await fetch(`${BACKEND_URL}/api/v1/compliance/scraper/sources`) if (res.ok) { const data = await res.json(); setSources(data.sources || []) } } catch (err) { console.error('Failed to fetch sources:', err) } }, []) const fetchPdfDocuments = useCallback(async () => { try { const res = await fetch(`${BACKEND_URL}/api/v1/compliance/scraper/pdf-documents`) if (res.ok) { const data = await res.json(); setPdfDocuments(data.documents || []) } } catch (err) { console.error('Failed to fetch PDF documents:', err) } }, []) const fetchStatus = useCallback(async () => { try { const res = await fetch(`${BACKEND_URL}/api/v1/compliance/scraper/status`) if (res.ok) { const data = await res.json(); setStatus(data) } } catch (err) { console.error('Failed to fetch status:', err) } }, []) useEffect(() => { const loadData = async () => { setLoading(true) await Promise.all([fetchSources(), fetchStatus(), fetchPdfDocuments()]) setLoading(false) } loadData() }, [fetchSources, fetchStatus, fetchPdfDocuments]) useEffect(() => { if (scraping) { const interval = setInterval(fetchStatus, 2000); return () => clearInterval(interval) } }, [scraping, fetchStatus]) const handleScrapeAll = async () => { setScraping(true); setError(null); setSuccess(null); setResults([]) try { const res = await fetch(`${BACKEND_URL}/api/v1/compliance/scraper/scrape-all`, { method: 'POST' }) if (!res.ok) { const data = await res.json(); throw new Error(data.detail || 'Scraping fehlgeschlagen') } const data = await res.json() setResults([...data.results.success, ...data.results.failed, ...data.results.skipped]) setSuccess(`Scraping abgeschlossen: ${data.results.success.length} erfolgreich, ${data.results.skipped.length} uebersprungen, ${data.results.failed.length} fehlgeschlagen`) await fetchSources() } catch (err: any) { setError(err.message) } finally { setScraping(false) } } const handleScrapeSingle = async (code: string, force: boolean = false) => { setScraping(true); setError(null); setSuccess(null) try { const res = await fetch(`${BACKEND_URL}/api/v1/compliance/scraper/scrape/${code}?force=${force}`, { method: 'POST' }) if (!res.ok) { const data = await res.json(); throw new Error(data.detail || 'Scraping fehlgeschlagen') } const data = await res.json() if (data.status === 'skipped') { setSuccess(`${code}: Bereits vorhanden (${data.requirement_count} Anforderungen)`) } else { setSuccess(`${code}: ${data.requirements_extracted} Anforderungen extrahiert`) } await fetchSources() } catch (err: any) { setError(err.message) } finally { setScraping(false) } } const handleExtractPdf = async (code: string, saveToDb: boolean = true, force: boolean = false) => { setExtracting(true); setError(null); setSuccess(null); setPdfResult(null) try { const res = await fetch(`${BACKEND_URL}/api/v1/compliance/scraper/extract-pdf`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ document_code: code, save_to_db: saveToDb, force }), }) if (!res.ok) { const data = await res.json(); throw new Error(data.detail || 'PDF-Extraktion fehlgeschlagen') } const data: PDFExtractionResult = await res.json() setPdfResult(data) if (data.success) { setSuccess(`${code}: ${data.total_aspects} Pruefaspekte extrahiert, ${data.requirements_created} Requirements erstellt`) } await fetchSources() } catch (err: any) { setError(err.message) } finally { setExtracting(false) } } useEffect(() => { if (success) { const timer = setTimeout(() => setSuccess(null), 5000); return () => clearTimeout(timer) } }, [success]) useEffect(() => { if (error) { const timer = setTimeout(() => setError(null), 10000); return () => clearTimeout(timer) } }, [error]) return { activeTab, setActiveTab, sources, pdfDocuments, status, loading, scraping, extracting, error, success, results, pdfResult, handleScrapeAll, handleScrapeSingle, handleExtractPdf, } }