import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:ristoris/database/database.dart'; import 'package:ristoris/database/tables/agenti.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) { final agentiDao = ref.read(agentiDaoProvider); return AgenteSyncService(ref.read(apiServiceProvider), agentiDao); }); 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('Autenticazione riuscita', 0.02); final parametriDao = ref.read(parametriDaoProvider); final agenteSync = ref.read(agenteSyncServiceProvider); 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 agenteSync.downloadAgenti(idAgente, codAgente, lastUpdateStr); await clienteSync.uploadNewCustomers(idAgente, codAgente); _update('Clienti inviati', 0.12); // cicla per tutti gli agenti a db List agenti = await agentiDao.listAll(); await filialeSync.uploadNewDestinations(idAgente, codAgente); _update('Destinazioni inviate', 0.18); 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); for (int i = 0; i < agenti.length; i++) { final agente = agenti[i]; _update('Aggiornamento per codice ${agente.codAgente} ', 0.16); await clienteSync.downloadCustomers(agente.idAgente, agente.codAgente!, lastUpdateStr); _update('(${agente.codAgente}) Clienti attivi scaricati', 0.16); await filialeSync.downloadDestinations( agente.idAgente, agente.codAgente!, lastUpdateStr, ); _update('(${agente.codAgente}) Destinazioni scaricate', 0.20); await Future.wait([ refSync.downloadScadenze(agente.idAgente, agente.codAgente!, lastUpdateStr), refSync.downloadListiniCliente(agente.idAgente, agente.codAgente!, lastUpdateStr), refSync.downloadScontiCliente(agente.idAgente, agente.codAgente!, lastUpdateStr), ordineSync.downloadRemoteOrders(agente.idAgente, agente.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(orderProvider); 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, );