import React, { useState, useEffect } from 'react'; import { createPortal } from 'react-dom'; import { motion, AnimatePresence } from 'framer-motion'; import { X, Search, Sparkles, Building, ChevronRight, Loader2, CheckCircle, Cpu, Tractor, HardHat, Info } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '@clerk/clerk-react'; import { createProject, lookupCompany, matchProgram } from '../../api/client'; import toast from 'react-hot-toast'; interface Props { onClose: () => void; } const WizardModal: React.FC = ({ onClose }) => { const navigate = useNavigate(); const { userId } = useAuth(); const [step, setStep] = useState(1); const [nip, setNip] = useState(''); const [desc, setDesc] = useState(''); const [isSearching, setIsSearching] = useState(false); const [companyFound, setCompanyFound] = useState(false); const [analyzing, setAnalyzing] = useState(false); const [analysisLogs, setAnalysisLogs] = useState([]); const [selectedProgram, setSelectedProgram] = useState(1); const [expandedProgram, setExpandedProgram] = useState(null); const [companyDetails, setCompanyDetails] = useState<{name: string, status: string, nip?: string} | null>(null); const [recommendedPrograms, setRecommendedPrograms] = useState([]); const [manualEntry, setManualEntry] = useState(false); const [clarifyingQuestions, setClarifyingQuestions] = useState([]); const [clarificationAnswers, setClarificationAnswers] = useState([]); const [clarificationPanelOpen, setClarificationPanelOpen] = useState(false); const handleSearchCompany = async () => { const cleanedNip = nip.replace(/\D/g, ''); if (cleanedNip.length !== 10) { toast.error("NIP musi składać się dokładnie z 10 cyfr."); return; } setIsSearching(true); try { const data = await lookupCompany(cleanedNip); setCompanyDetails({ name: data.name, status: data.status, nip: cleanedNip }); setCompanyFound(true); setManualEntry(false); } catch(e: any) { const errMsg = e.response?.data?.detail || "Nie znaleziono w bazie GUS. Możesz kontynuować, wpisując nazwę ręcznie."; toast.error(errMsg); setCompanyFound(false); setManualEntry(true); setCompanyDetails({ name: '', status: 'Dane wprowadzone ręcznie', nip: nip }); } finally { setIsSearching(false); } }; const handleStartAnalysis = async (additionalContext?: string) => { if (!desc && !additionalContext) return; setStep(3); setAnalyzing(true); setAnalysisLogs(prev => [...prev, additionalContext ? 'Aktualizacja analizy z nowymi danymi...' : 'Inicjalizowanie silnika RAG...']); // Złącz główny opis i dodatkowy kontekst z pytań jeśli są const finalDesc = additionalContext ? `${desc}\n\n[DOPRECYZOWANIE]:\n${additionalContext}` : desc; if (additionalContext) setDesc(finalDesc); try { const data = await matchProgram(finalDesc, nip); setRecommendedPrograms(data.programs || []); if (data.programs && data.programs.length > 0) setSelectedProgram(data.programs[0].id); setClarifyingQuestions(data.clarifying_questions || []); setClarificationAnswers(new Array((data.clarifying_questions || []).length).fill('')); setClarificationPanelOpen((data.clarifying_questions || []).length > 0); setAnalysisLogs(prev => [...prev, 'Zakończono generowanie raportu dopasowania.']); } catch(e) { toast.error("Wystąpił problem ze zgłaszaniem do modelu AI"); } finally { setAnalyzing(false); } }; const renderStepContent = () => { switch(step) { case 1: return (

Podłącz profil firmy

System automatycznie pobierze dane rejestrowe z bazy GUS/KRS, by dopasować odpowiednie programy.

setNip(e.target.value)} style={{ width: '100%', padding: '1rem 1rem 1rem 3rem', background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(59, 130, 246, 0.4)', borderRadius: '12px', color: '#fff', fontSize: '1.1rem', outline: 'none' }} onKeyDown={e => e.key === 'Enter' && handleSearchCompany()} />
{!manualEntry && ( { setManualEntry(true); setCompanyDetails({ name: '', status: 'Dane wprowadzone ręcznie', nip: nip }); }}> Wprowadź dane ręcznie )}
{companyFound && !manualEntry && companyDetails && (
Znaleziono firmę
NIP: {nip.replace(/\D/g, '')}
{companyDetails.name} • {companyDetails.status}
)} {manualEntry && ( setCompanyDetails({ name: e.target.value, status: 'Dane wpisane ręcznie', nip: nip })} placeholder="Wpisz pełną nazwę przedsiębiorstwa..." style={{ width: '100%', padding: '1rem', background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(245, 158, 11, 0.4)', borderRadius: '12px', color: '#fff', fontSize: '1.1rem', outline: 'none' }} /> )}
); case 2: return (

Opisz planowaną inwestycję

Napisz swoimi słowami, co zamierzasz zrobić. Sztuczna Inteligencja przejdzie przez tekst wyciągając kryteria kluczowe dla dotacji.