import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/core/blocs/session/session_bloc.dart'; import 'package:flux/features/master_data/providers/data/provider_repository.dart'; import 'package:flux/features/master_data/store/models/store_model.dart'; import 'package:get_it/get_it.dart'; import '../models/provider_model.dart'; class ProvidersState extends Equatable { final List allProviders; // Tutti i provider della company final List associatedIds; // ID dei provider attivi nello store selezionato final bool isLoading; final String? errorMessage; const ProvidersState({ this.allProviders = const [], this.associatedIds = const [], this.isLoading = false, this.errorMessage, }); ProvidersState copyWith({ List? allProviders, List? associatedIds, bool? isLoading, String? errorMessage, }) { return ProvidersState( allProviders: allProviders ?? this.allProviders, associatedIds: associatedIds ?? this.associatedIds, isLoading: isLoading ?? this.isLoading, errorMessage: errorMessage, ); } @override List get props => [ allProviders, associatedIds, isLoading, errorMessage, ]; } class ProvidersCubit extends Cubit { final ProviderRepository _repository = GetIt.I(); final SessionBloc _sessionBloc; ProvidersCubit(this._sessionBloc) : super(const ProvidersState()); // Carica i provider della company e quelli associati a uno store specifico Future loadProviders(StoreModel? store) async { emit(state.copyWith(isLoading: true)); try { final all = await _repository.fetchAllCompanyProviders( _sessionBloc.state.company!.id, ); List associated = []; if (store != null) { associated = await _repository.fetchAssociatedProviderIds(store.id!); } emit( state.copyWith( allProviders: all, associatedIds: associated, isLoading: false, ), ); } catch (e) { emit(state.copyWith(isLoading: false, errorMessage: e.toString())); } } // Aggiunge o rimuove l'associazione con lo store Future toggleProviderAssociation({ required String providerId, required String storeId, required bool isCurrentlyAssociated, }) async { try { if (isCurrentlyAssociated) { await _repository.disassociateProviderFromStore( providerId: providerId, storeId: storeId, ); // Aggiorniamo lo stato locale rimuovendo l'ID final newIds = List.from(state.associatedIds) ..remove(providerId); emit(state.copyWith(associatedIds: newIds)); } else { await _repository.associateProviderToStore( providerId: providerId, storeId: storeId, ); // Aggiorniamo lo stato locale aggiungendo l'ID final newIds = List.from(state.associatedIds)..add(providerId); emit(state.copyWith(associatedIds: newIds)); } } catch (e) { emit(state.copyWith(errorMessage: "Errore durante l'aggiornamento: $e")); } } // Salvataggio/Update anagrafica (nuovo o modifica) Future saveProvider( ProviderModel provider, List selectedStoreIds, ) async { emit(state.copyWith(isLoading: true)); // Assicuriamoci di settare la companyId prima di salvare provider = provider.copyWith(companyId: _sessionBloc.state.company!.id); try { // 1. Salviamo l'anagrafica (upsert) // Se è un nuovo provider, l'ID potrebbe essere generato qui dal DB // Quindi carichiamo il risultato del salvataggio per avere l'ID final response = await _repository.saveProvider(provider); // Assumiamo che il saveProvider restituisca l'oggetto salvato con l'ID final pId = provider.id ?? response.id; // 2. Sincronizziamo i negozi await _repository.syncProviderStores(pId!, selectedStoreIds); // 3. Ricarichiamo tutto await loadProviders(null); } catch (e) { emit(state.copyWith(isLoading: false, errorMessage: e.toString())); } } Future saveProviderWithStores( ProviderModel provider, List storeIds, ) async { emit(state.copyWith(isLoading: true)); try { // 1. Salva l'anagrafica provider await _repository.saveProvider(provider); // 2. Sincronizza i negozi (la via più semplice è cancellare e reinserire // o fare un confronto tra i presenti e i nuovi) await _repository.syncProviderStores(provider.id!, storeIds); await loadProviders(null); } catch (e) { emit(state.copyWith(isLoading: false, errorMessage: e.toString())); } } }