import 'dart:io'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../models/models.dart'; import '../../services/camera_service.dart'; import '../../services/openai_service.dart'; import 'scanner_event.dart'; import 'scanner_state.dart'; class ScannerBloc extends Bloc { final CameraService cameraService; ScannerBloc({required this.cameraService}) : super(const ScannerState()) { on(_onInitializeCamera); on(_onCaptureAndAnalyze); on(_onSwitchCamera); on(_onDismissError); } Future _onInitializeCamera( InitializeCamera event, Emitter emit, ) async { try { final initialized = await cameraService.initializeCamera(); emit( state.copyWith( isInitialized: initialized, hasPermissionError: !initialized, errorMessage: initialized ? null : 'Нет доступа к камере', ), ); } catch (e) { emit( state.copyWith( hasPermissionError: true, errorMessage: 'Ошибка инициализации камеры: $e', ), ); } } Future _onCaptureAndAnalyze( CaptureAndAnalyze event, Emitter emit, ) async { if (cameraService.controller == null) return; emit(state.copyWith(isCapturing: true)); try { // Capture image final imagePath = await cameraService.captureImage(); if (imagePath == null) { throw Exception('Не удалось сделать снимок'); } emit(state.copyWith(isAnalyzing: true, isCapturing: false)); Book? book; // Try OpenAI first if available if (event.openaiApiKey != null && event.openaiApiKey!.isNotEmpty) { print('Using OpenAI service for analysis'); final openaiService = OpenAIService( apiKey: event.openaiApiKey!, baseUrl: event.openaiBaseUrl, ); book = await openaiService.analyzeBookCover(imagePath); } // Fall back to Gemini if OpenAI failed or is not configured // if (book == null) { // if (event.geminiApiKey == null || event.geminiApiKey!.isEmpty) { // throw Exception('API ключ не настроен (ни OpenAI, ни Gemini)'); // } // print('Using Gemini service for analysis'); // final geminiService = GeminiService(apiKey: event.geminiApiKey!); // book = await geminiService.analyzeBookCover(imagePath); // } if (book == null) { throw Exception('Не удалось распознать книгу'); } // Clean up temporary image try { await File(imagePath).delete(); } catch (e) { print('Error deleting temporary file: $e'); } emit( state.copyWith( analyzedBook: book, isAnalyzing: false, isCapturing: false, ), ); } catch (e) { emit( state.copyWith( errorMessage: e.toString(), isCapturing: false, isAnalyzing: false, ), ); } } Future _onSwitchCamera( SwitchCamera event, Emitter emit, ) async { await cameraService.switchCamera(); } void _onDismissError(DismissError event, Emitter emit) { emit(state.copyWith(clearError: true)); } @override Future close() { cameraService.dispose(); return super.close(); } }