import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../api/types.dart'; import '../api/client.dart'; import '../api/openapi_config.dart'; import '../services/auth_service.dart'; import '../models/user_profile.dart'; import '../models/delivery_route.dart'; import '../models/delivery.dart'; final authServiceProvider = Provider((ref) { return AuthService(config: AuthConfig.development); }); final apiClientProvider = Provider((ref) { return CqrsApiClient(config: ApiClientConfig.development); }); final isAuthenticatedProvider = FutureProvider((ref) async { final authService = ref.watch(authServiceProvider); return await authService.isAuthenticated(); }); final userProfileProvider = FutureProvider((ref) async { final authService = ref.watch(authServiceProvider); final token = await authService.getToken(); if (token == null) return null; return authService.decodeToken(token); }); final authTokenProvider = FutureProvider((ref) async { final authService = ref.watch(authServiceProvider); return await authService.getToken(); }); final deliveryRoutesProvider = FutureProvider>((ref) async { final token = await ref.read(authTokenProvider.future); if (token == null) { throw Exception('User not authenticated'); } // Create a new client with auth token final authClient = CqrsApiClient( config: ApiClientConfig( baseUrl: ApiClientConfig.development.baseUrl, defaultHeaders: {'Authorization': 'Bearer $token'}, allowSelfSignedCertificate: ApiClientConfig.development.allowSelfSignedCertificate, ), ); final result = await authClient.executeQuery>( endpoint: 'simpleDeliveryRouteQueryItems', query: _EmptyQuery(), fromJson: (json) { // API returns data wrapped in object with "data" field if (json is Map) { final data = json['data']; if (data is List) { return data.map((r) => DeliveryRoute.fromJson(r as Map)).toList(); } } return []; }, ); return result.whenSuccess((routes) => routes) ?? []; }); final deliveriesProvider = FutureProvider.family, int>((ref, routeFragmentId) async { final token = await ref.read(authTokenProvider.future); if (token == null) { throw Exception('User not authenticated'); } final authClient = CqrsApiClient( config: ApiClientConfig( baseUrl: ApiClientConfig.development.baseUrl, defaultHeaders: {'Authorization': 'Bearer $token'}, allowSelfSignedCertificate: ApiClientConfig.development.allowSelfSignedCertificate, ), ); final result = await authClient.executeQuery>( endpoint: 'simpleDeliveriesQueryItems', query: _DeliveriesQuery(routeFragmentId: routeFragmentId), fromJson: (json) { // API returns data wrapped in object with "data" field if (json is Map) { final data = json['data']; if (data is List) { return data.map((d) => Delivery.fromJson(d as Map)).toList(); } } return []; }, ); return result.whenSuccess((deliveries) => deliveries) ?? []; }); /// Provider to get all deliveries from all routes final allDeliveriesProvider = FutureProvider>((ref) async { final routes = await ref.read(deliveryRoutesProvider.future); if (routes.isEmpty) { return []; } // Fetch deliveries for all routes in parallel using Future.wait final deliveriesFutures = routes.map((route) { return ref.read(deliveriesProvider(route.id).future); }).toList(); // Wait for all futures to complete final deliveriesLists = await Future.wait(deliveriesFutures); // Combine all deliveries into a single list final allDeliveries = []; for (final deliveries in deliveriesLists) { allDeliveries.addAll(deliveries); } return allDeliveries; }); // Language notifier for state management class LanguageNotifier extends Notifier { @override String build() => 'fr'; void setLanguage(String lang) => state = lang; } final languageProvider = NotifierProvider(() { return LanguageNotifier(); }); // Theme mode notifier for manual theme switching class ThemeModeNotifier extends Notifier { @override ThemeMode build() => ThemeMode.dark; void setThemeMode(ThemeMode mode) => state = mode; } final themeModeProvider = NotifierProvider(() { return ThemeModeNotifier(); }); // Collapse state notifier for sidebar persistence class CollapseStateNotifier extends Notifier { @override bool build() => true; // Default: expanded void toggle() => state = !state; void setExpanded(bool expanded) => state = expanded; } final collapseStateProvider = NotifierProvider(() { return CollapseStateNotifier(); }); class _EmptyQuery implements Serializable { @override Map toJson() => {}; } class _DeliveriesQuery implements Serializable { final int routeFragmentId; _DeliveriesQuery({required this.routeFragmentId}); @override Map toJson() => { 'params': { 'routeFragmentId': routeFragmentId, }, }; }