import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../services/api_service.dart'; import '../services/sync/agente_sync_service.dart'; import '../services/sync/cliente_sync_service.dart'; import '../services/sync/ordine_sync_service.dart'; import '../services/sync/filiale_sync_service.dart'; import '../services/sync/reference_sync_service.dart'; import '../services/image_service.dart'; import 'article_provider.dart'; import 'auth_provider.dart'; import 'customer_provider.dart'; import 'dashboard_provider.dart'; import 'database_provider.dart'; import 'order_provider.dart'; import '../ui/pages/payments/payments_page.dart'; final apiServiceProvider = Provider((ref) { final parametriDao = ref.read(parametriDaoProvider); return ApiService(parametriDao); }); final imageServiceProvider = Provider((ref) { final parametriDao = ref.read(parametriDaoProvider); return ImageService(parametriDao); }); final agenteSyncServiceProvider = Provider((ref) { return AgenteSyncService(ref.read(apiServiceProvider)); }); final clienteSyncServiceProvider = Provider((ref) { final api = ref.read(apiServiceProvider); final clientiDao = ref.read(clientiDaoProvider); final clientiAgenteDao = ref.read(clientiAgenteDaoProvider); return ClienteSyncService(api, clientiDao, clientiAgenteDao); }); final ordineSyncServiceProvider = Provider((ref) { return OrdineSyncService( ref.read(apiServiceProvider), ref.read(ordiniDaoProvider), ref.read(clientiDaoProvider), ref.read(filialiDaoProvider), ref.read(agentiDaoProvider), ); }); final filialeSyncServiceProvider = Provider((ref) { return FilialeSyncService( ref.read(apiServiceProvider), ref.read(filialiDaoProvider), ref.read(clientiDaoProvider), ); }); final referenceSyncServiceProvider = Provider((ref) { return ReferenceSyncService( ref.read(apiServiceProvider), ref.read(tabelleDaoProvider), ref.read(pagamentiDaoProvider), ref.read(scontiDaoProvider), ref.read(articoliDaoProvider), ref.read(listiniDaoProvider), ref.read(promozioniDaoProvider), ref.read(scadenzeDaoProvider), ref.read(statisticheDaoProvider), ref.read(parametriDaoProvider), ref.read(clientiDaoProvider), ); }); class SyncState { final bool isSyncing; final double progress; final String message; final String? error; const SyncState({ this.isSyncing = false, this.progress = 0, this.message = '', this.error, }); } class SyncNotifier extends Notifier { @override SyncState build() => const SyncState(); Future startFullSync( int idAgente, String codAgente, { bool forceFullSync = false, }) async { state = const SyncState( isSyncing: true, message: 'Avvio sincronizzazione...', ); try { final agentiDao = ref.read(agentiDaoProvider); final agente = await agentiDao.findByCode(codAgente); if (agente?.pwd != null) { final authService = ref.read(authServiceProvider); final token = await authService.loginRemote(codAgente, agente!.pwd!); ref.read(apiServiceProvider).token = token; } _update('Token JWT acquisito', 0.02); final parametriDao = ref.read(parametriDaoProvider); final ordineSync = ref.read(ordineSyncServiceProvider); final filialeSync = ref.read(filialeSyncServiceProvider); final clienteSync = ref.read(clienteSyncServiceProvider); final refSync = ref.read(referenceSyncServiceProvider); final lastUpdateStr = forceFullSync ? '200001010000' : (await parametriDao.read('lastUpdate') ?? '200001010000'); await clienteSync.uploadNewCustomers(idAgente, codAgente); _update('Clienti inviati', 0.12); await clienteSync.downloadCustomers(idAgente, codAgente, lastUpdateStr); _update('Clienti attivi scaricati', 0.16); await filialeSync.uploadNewDestinations(idAgente, codAgente); _update('Destinazioni inviate', 0.18); await filialeSync.downloadDestinations( idAgente, codAgente, lastUpdateStr, ); _update('Destinazioni scaricate', 0.20); await ordineSync.uploadNewOrders(idAgente, codAgente); _update('Ordini inviati', 0.22); await Future.wait([ refSync.downloadTabelle(lastUpdateStr), refSync.downloadPagamenti(lastUpdateStr), refSync.downloadSconti(lastUpdateStr), refSync.downloadArticoli(lastUpdateStr), refSync.downloadListini(lastUpdateStr), refSync.downloadListiniArticolo(lastUpdateStr), refSync.downloadPromozioni(lastUpdateStr), refSync.downloadStatistiche(idAgente, codAgente, lastUpdateStr), ]); _update('Dati di riferimento scaricati', 0.60); await Future.wait([ refSync.downloadScadenze(idAgente, codAgente, lastUpdateStr), refSync.downloadListiniCliente(idAgente, codAgente, lastUpdateStr), refSync.downloadScontiCliente(idAgente, codAgente, lastUpdateStr), ordineSync.downloadRemoteOrders(idAgente, codAgente, lastUpdateStr), ]); _update('Dati per agente scaricati', 0.92); await refSync.downloadParametro('PALLET_PERC'); _update('Parametri verificati', 0.98); final now = DateTime.now(); final newLastUpdate = '${now.year}${_pad(now.month)}${_pad(now.day)}${_pad(now.hour)}${_pad(now.minute)}'; await parametriDao.set('lastUpdate', newLastUpdate); state = const SyncState( message: 'Sincronizzazione completata!', progress: 1.0, ); ref.invalidate(articleSearchProvider); ref.invalidate(activeArticleSearchProvider); ref.invalidate(priceCodesProvider); ref.invalidate(customerListProvider); ref.invalidate(customerSearchProvider); ref.invalidate(customerDestinationsProvider); ref.invalidate(customerPaymentsProvider); ref.invalidate(ordersViewProvider); ref.invalidate(ordersSearchViewProvider); ref.invalidate(orderStatsProvider); ref.invalidate(dashboardProvider); ref.invalidate(paymentsProvider); } catch (e) { state = SyncState( error: e.toString(), message: 'Errore durante la sincronizzazione', ); } } String _pad(int n) => n.toString().padLeft(2, '0'); void _update(String msg, double progress) { state = SyncState(isSyncing: true, message: msg, progress: progress); } } final syncProvider = NotifierProvider( SyncNotifier.new, );