import 'package:bloc/bloc.dart'; import 'package:dartz/dartz.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:injectable/injectable.dart'; import '../../../domain/category/category.dart'; import '../../../domain/product/product.dart'; part 'sync_setting_event.dart'; part 'sync_setting_state.dart'; part 'sync_setting_bloc.freezed.dart'; @injectable class SyncSettingBloc extends Bloc { final IProductRepository _productRepository; final ICategoryRepository _categoryRepository; SyncSettingBloc(this._productRepository, this._categoryRepository) : super(SyncSettingState.initial()) { on(_onSyncSettingEvent); } Future _onSyncSettingEvent( SyncSettingEvent event, Emitter emit, ) { return event.map( loadStats: (e) => _onLoadStats(emit), syncAllData: (e) => _onSyncAllData(emit), clearAllData: (e) => _onClearAllData(emit), syncProducts: (e) => _onSyncProducts(emit), syncCategories: (e) => _onSyncCategories(emit), clearCategories: (e) => _onClearCategories(emit), clearProducts: (e) => _onClearProducts(emit), ); } Future _onLoadStats(Emitter emit) async { emit( state.copyWith( isLoading: true, failureOptionProduct: none(), failureOptionCategory: none(), ), ); final productStats = await _productRepository.getDatabaseStats(); final categoryStats = await _categoryRepository.getDatabaseStats(); productStats.fold( (failure) { emit( state.copyWith( isLoading: false, failureOptionProduct: optionOf(failure), ), ); }, (data) { emit( state.copyWith( isLoading: false, productStats: data, failureOptionProduct: none(), ), ); }, ); categoryStats.fold( (failure) { emit( state.copyWith( isLoading: false, failureOptionCategory: optionOf(failure), ), ); }, (data) { emit( state.copyWith( isLoading: false, categoryStats: data, failureOptionCategory: none(), ), ); }, ); } Future _onSyncAllData(Emitter emit) async { emit( state.copyWith( isSyncing: true, failureOptionSyncCategory: none(), failureOptionSyncProduct: none(), ), ); // Sync categories first final categoryResult = await _categoryRepository.syncAllCategories(); bool categorySuccess = false; categoryResult.fold( (failure) { emit( state.copyWith(failureOptionSyncCategory: optionOf(left(failure))), ); }, (success) { categorySuccess = true; emit( state.copyWith(failureOptionSyncCategory: optionOf(right(success))), ); }, ); // Only sync products if categories synced successfully if (categorySuccess) { final productResult = await _productRepository.syncAllProducts(); productResult.fold( (failure) { emit( state.copyWith( isSyncing: false, failureOptionSyncProduct: optionOf(left(failure)), ), ); }, (success) { emit( state.copyWith( isSyncing: false, failureOptionSyncProduct: optionOf(right(success)), ), ); }, ); } else { emit(state.copyWith(isSyncing: false)); } // Reload stats after sync add(const SyncSettingEvent.loadStats()); } Future _onClearAllData(Emitter emit) async { emit(state.copyWith(isLoading: true)); try { // Clear products and categories await _productRepository.clearAllProducts(); await _categoryRepository.clearAllCategories(); // Clear caches _productRepository.clearCache(); _categoryRepository.clearCache(); emit(state.copyWith(isLoading: false)); // Reload stats after clearing add(const SyncSettingEvent.loadStats()); } catch (e) { emit(state.copyWith(isLoading: false)); } } Future _onSyncProducts(Emitter emit) async { emit(state.copyWith(isLoading: true, failureOptionSyncProduct: none())); final result = await _productRepository.syncAllProducts(); result.fold( (failure) { emit( state.copyWith( isLoading: false, failureOptionSyncProduct: optionOf(left(failure)), ), ); }, (success) { emit( state.copyWith( isLoading: false, failureOptionSyncProduct: optionOf(right(success)), ), ); }, ); // Reload stats after sync add(const SyncSettingEvent.loadStats()); } Future _onSyncCategories(Emitter emit) async { emit(state.copyWith(isLoading: true, failureOptionSyncCategory: none())); final result = await _categoryRepository.syncAllCategories(); result.fold( (failure) { emit( state.copyWith( isLoading: false, failureOptionSyncCategory: optionOf(left(failure)), ), ); }, (success) { emit( state.copyWith( isLoading: false, failureOptionSyncCategory: optionOf(right(success)), ), ); }, ); // Reload stats after sync add(const SyncSettingEvent.loadStats()); } Future _onClearCategories(Emitter emit) async { await _categoryRepository.clearAllCategories(); _categoryRepository.clearCache(); } Future _onClearProducts(Emitter emit) async { await _productRepository.clearAllProducts(); _productRepository.clearCache(); } }