import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'dart:io'; import '../data/models/analysis_models.dart'; import 'analysis_api_service.dart'; const _defaultApiBaseUrl = String.fromEnvironment( 'TC_API_BASE_URL', defaultValue: 'http://127.0.0.1:8000/api', ); final apiBaseUrlProvider = Provider((ref) => _defaultApiBaseUrl); final analysisApiServiceProvider = Provider((ref) { return AnalysisApiService(baseUrl: _defaultApiBaseUrl); }); final selectedSessionIdProvider = StateProvider((ref) => null); final selectedObservationIdProvider = StateProvider((ref) => null); final sessionListProvider = FutureProvider>(( ref, ) async { final api = ref.watch(analysisApiServiceProvider); return api.listSessions(); }); final observationListProvider = FutureProvider>(( ref, ) async { final api = ref.watch(analysisApiServiceProvider); return api.listObservations(); }); final selectedSessionSnapshotProvider = FutureProvider((ref) async { final sessionId = ref.watch(selectedSessionIdProvider); if (sessionId == null) { return null; } final api = ref.watch(analysisApiServiceProvider); return api.getSession(sessionId); }); final selectedObservationProvider = FutureProvider((ref) async { final observationId = ref.watch(selectedObservationIdProvider); if (observationId == null) { return null; } final api = ref.watch(analysisApiServiceProvider); return api.getObservation(observationId); }); final sessionActionsProvider = Provider((ref) { return SessionActions(ref); }); class SessionActions { SessionActions(this._ref); final Ref _ref; Future createDemoSession() async { return createCapturedSession( durationMs: 4820, sampleRate: 16000, channels: 1, tags: const ['stub', 'periodic', 'mobile-lab'], captureMetadata: const { 'source': 'flutter-demo', 'noise_floor_db': -41, 'device': 'flutter-shell', }, ); } Future createCapturedSession({ required int durationMs, required int sampleRate, required int channels, List tags = const [], Map captureMetadata = const {}, }) async { final api = _ref.read(analysisApiServiceProvider); final observation = await api.createObservation( durationMs: durationMs, sampleRate: sampleRate, channels: channels, tags: tags, captureMetadata: captureMetadata, ); final session = await api.createSession(observationId: observation.id); _ref.read(selectedSessionIdProvider.notifier).state = session.sessionId; _ref.read(selectedObservationIdProvider.notifier).state = null; _ref.invalidate(observationListProvider); _ref.invalidate(sessionListProvider); _ref.invalidate(selectedSessionSnapshotProvider); _ref.invalidate(selectedObservationProvider); return session; } Future createUploadedSession({ required String filePath, required int durationMs, required int sampleRate, required int channels, List tags = const [], Map captureMetadata = const {}, }) async { final api = _ref.read(analysisApiServiceProvider); final file = File(filePath); if (!await file.exists()) { throw Exception('Recorded file not found at $filePath'); } final observation = await api.uploadObservation( filePath: filePath, durationMs: durationMs, sampleRate: sampleRate, channels: channels, tags: tags, captureMetadata: captureMetadata, ); final session = await api.createSession(observationId: observation.id); _ref.read(selectedSessionIdProvider.notifier).state = session.sessionId; _ref.read(selectedObservationIdProvider.notifier).state = null; _ref.invalidate(observationListProvider); _ref.invalidate(sessionListProvider); _ref.invalidate(selectedSessionSnapshotProvider); _ref.invalidate(selectedObservationProvider); return session; } Future createSessionForObservation( String observationId, { String mode = 'initial_analysis', }) async { final api = _ref.read(analysisApiServiceProvider); final session = await api.createSession( observationId: observationId, mode: mode, ); _ref.read(selectedSessionIdProvider.notifier).state = session.sessionId; _ref.read(selectedObservationIdProvider.notifier).state = null; _ref.invalidate(sessionListProvider); _ref.invalidate(selectedSessionSnapshotProvider); _ref.invalidate(selectedObservationProvider); return session; } void selectSession(String sessionId) { _ref.read(selectedSessionIdProvider.notifier).state = sessionId; _ref.read(selectedObservationIdProvider.notifier).state = null; _ref.invalidate(selectedSessionSnapshotProvider); _ref.invalidate(selectedObservationProvider); } void selectObservation(String observationId) { _ref.read(selectedObservationIdProvider.notifier).state = observationId; _ref.read(selectedSessionIdProvider.notifier).state = null; _ref.invalidate(selectedObservationProvider); _ref.invalidate(selectedSessionSnapshotProvider); } }