import { useState, useEffect } from 'react' import { Sparkles, FileText, Terminal, X, AlertTriangle } from 'lucide-react' import { TicketPickerModal } from '@/components/session/TicketPickerModal' import { RichTextInput } from '@/components/common/RichTextInput' import { integrationsApi } from '@/api/integrations' import type { AISessionCreateRequest } from '@/types/ai-session' import type { PSATicketInfo, PsaConnectionResponse } from '@/types/integrations' import type { FileUploadResponse } from '@/types/upload' interface FlowPilotIntakeProps { onSubmit: (request: AISessionCreateRequest) => void isLoading: boolean defaultProblem?: string } export function FlowPilotIntake({ onSubmit, isLoading, defaultProblem }: FlowPilotIntakeProps) { const [text, setText] = useState(defaultProblem || '') const [showLogs, setShowLogs] = useState(false) const [logContent, setLogContent] = useState('') const [showTicketPicker, setShowTicketPicker] = useState(false) // PSA connection state const [psaConnection, setPsaConnection] = useState(null) const [psaChecked, setPsaChecked] = useState(false) // Upload state (no session_id yet — uploads linked later) const [_intakeUploads, setIntakeUploads] = useState([]) // Selected ticket state const [selectedTicket, setSelectedTicket] = useState(null) const [selectedTicketId, setSelectedTicketId] = useState(null) const [additionalContext, setAdditionalContext] = useState('') // Check for PSA connection on mount useEffect(() => { let cancelled = false integrationsApi.getConnection() .then((conn) => { if (!cancelled) { setPsaConnection(conn && conn.is_active ? conn : null) setPsaChecked(true) } }) .catch(() => { if (!cancelled) setPsaChecked(true) }) return () => { cancelled = true } }, []) const handleTicketSelected = (ticketId: string, ticket: PSATicketInfo) => { setSelectedTicketId(ticketId) setSelectedTicket(ticket) setShowTicketPicker(false) } const handleClearTicket = () => { setSelectedTicketId(null) setSelectedTicket(null) setAdditionalContext('') } const handleSubmit = () => { // Ticket-based submission if (selectedTicket && selectedTicketId && psaConnection) { const intake_content: Record = { text: additionalContext.trim() || undefined, ticket_data: { summary: selectedTicket.summary, company: selectedTicket.company_name, priority: selectedTicket.priority_name, }, } onSubmit({ intake_type: 'psa_ticket', intake_content, psa_ticket_id: selectedTicketId, psa_connection_id: psaConnection.id, }) return } // Free-text / log submission if (!text.trim() && !logContent.trim()) return const intake_content: Record = {} if (text.trim()) intake_content.text = text.trim() if (logContent.trim()) intake_content.log_content = logContent.trim() const intake_type = logContent.trim() ? text.trim() ? 'combined' : 'log_paste' : 'free_text' onSubmit({ intake_type, intake_content }) } const hasContent = text.trim() || logContent.trim() || selectedTicket if (isLoading) { return (

Analyzing your issue...

FlowPilot is classifying the problem and searching for relevant flows

) } const submitLabel = selectedTicket && selectedTicketId ? `Start Session with Ticket #${selectedTicketId}` : 'Start Session' return (

What are you troubleshooting?

Describe the issue, paste an error message, or pull context from a ticket

{/* Selected ticket card */} {selectedTicket && selectedTicketId && (

#{selectedTicketId} {' — '} {selectedTicket.summary}

{selectedTicket.company_name && {selectedTicket.company_name}} {selectedTicket.priority_name && ( <> {selectedTicket.priority_name} )} {selectedTicket.status_name && ( <> {selectedTicket.status_name} )}
{/* Additional context textarea */}