import { createContext, useContext, useState, useCallback, useRef, type ReactNode, } from 'react'; import type { ImportStatementResponse } from '@family-budget/shared'; import { importStatementStream, type SseEvent } from '../api/import'; export interface ImportProgress { active: boolean; stage: string; progress: number; message: string; result?: ImportStatementResponse; error?: string; } interface ImportContextValue { importState: ImportProgress; showModal: boolean; openModal: () => void; closeModal: () => void; startImport: (file: File) => void; clearImport: () => void; } const INITIAL: ImportProgress = { active: false, stage: '', progress: 0, message: '', }; const ImportContext = createContext(null); export function ImportProvider({ children }: { children: ReactNode }) { const [importState, setImportState] = useState(INITIAL); const [showModal, setShowModal] = useState(false); const runningRef = useRef(false); const openModal = useCallback(() => setShowModal(true), []); const closeModal = useCallback(() => setShowModal(false), []); const startImport = useCallback((file: File) => { if (runningRef.current) return; runningRef.current = true; setImportState({ active: true, stage: 'pdf', progress: 0, message: 'Загрузка файла...', }); importStatementStream(file, (event: SseEvent) => { if (event.stage === 'done') { setImportState({ active: false, stage: 'done', progress: 100, message: 'Импорт завершён', result: event.result, }); runningRef.current = false; } else if (event.stage === 'error') { setImportState({ active: false, stage: 'error', progress: 0, message: event.message, error: event.message, }); runningRef.current = false; } else { setImportState({ active: true, stage: event.stage, progress: event.progress, message: event.message, }); } }).catch((err) => { setImportState({ active: false, stage: 'error', progress: 0, message: err instanceof Error ? err.message : 'Ошибка импорта', error: err instanceof Error ? err.message : 'Ошибка импорта', }); runningRef.current = false; }); }, []); const clearImport = useCallback(() => { setImportState(INITIAL); }, []); return ( {children} ); } export function useImport(): ImportContextValue { const ctx = useContext(ImportContext); if (!ctx) throw new Error('useImport must be used within ImportProvider'); return ctx; }