import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/features/master_data/staff/data/staff_repository.dart'; import 'package:flux/features/master_data/staff/models/staff_member_model.dart'; import 'package:flux/features/master_data/store/models/store_model.dart'; import 'package:get_it/get_it.dart'; part 'staff_state.dart'; class StaffCubit extends Cubit { final StaffRepository _repository = GetIt.I.get(); final SessionCubit _sessionCubit = GetIt.I(); StaffCubit() : super(const StaffState()); // Carica tutto lo staff della compagnia Future loadAllStaff() async { emit(state.copyWith(status: StaffStatus.loading, error: null)); try { final staff = await _repository.getStaffMembers( _sessionCubit.state.company!.id!, ); final Map> storesByStaff = {}; for (StaffMemberModel member in staff) { storesByStaff[member.id!] = await loadStoresByStaff(member.id!); } emit( state.copyWith( status: StaffStatus.success, allStaff: staff, storesByStaff: storesByStaff, ), ); } catch (e) { emit(state.copyWith(status: StaffStatus.error, error: e.toString())); } } Future> loadStoresByStaff(String staffId) async { try { emit(state.copyWith(error: null)); return await _repository.getStaffMemberStore(staffId); } catch (e) { emit(state.copyWith(error: e.toString())); return []; } } // Carica lo staff di uno specifico negozio e aggiorna la mappa Future loadStaffForStore(String storeId) async { emit(state.copyWith(error: null)); try { final staffInStore = await _repository.getStaffMembersInStore(storeId); final newMap = Map>.from( state.staffByStore, ); newMap[storeId] = staffInStore; emit(state.copyWith(staffByStore: newMap)); } catch (e) { emit(state.copyWith(status: StaffStatus.error, error: e.toString())); } } // Salva o aggiorna un membro Future saveStaffMember(StaffMemberModel member) async { emit(state.copyWith(status: StaffStatus.loading, error: null)); try { await _repository.saveStaffMember(member); await loadAllStaff(); // Ricarichiamo la lista aggiornata } catch (e) { emit(state.copyWith(status: StaffStatus.error, error: e.toString())); } } Future inviteStaffMember({ required StaffMemberModel member, required List selectedStoreIds, }) async { emit(state.copyWith(status: StaffStatus.loading, error: null)); try { // 1. Invitiamo il membro e ci facciamo dare l'ID final newStaffId = await _repository.inviteStaffMember(member); // 2. Assegniamo i negozi uno ad uno (usando il metodo che avevi già nel repo!) if (selectedStoreIds.isNotEmpty) { final List assignTasks = []; for (var storeId in selectedStoreIds) { assignTasks.add(_repository.assignStaffToStore(newStaffId, storeId)); } await Future.wait(assignTasks); // In parallelo per la massima velocità } // 3. Ricarichiamo la lista globale così la UI si aggiorna await loadAllStaff(); // (Nota: se hai un loadStaffForStore o loadAllStaff, chiamalo qui per rinfrescare lo stato) emit(state.copyWith(status: StaffStatus.success)); } catch (e) { emit(state.copyWith(status: StaffStatus.error, error: e.toString())); } } // Associa un dipendente a un negozio Future assignMemberToStore(String staffId, String storeId) async { try { await _repository.assignStaffToStore(staffId, storeId); final stuffStores = await loadStoresByStaff(staffId); final Map> storesByStaff = Map.from( state.storesByStaff, ); storesByStaff[staffId] = stuffStores; emit(state.copyWith(storesByStaff: storesByStaff, error: null)); } catch (e) { emit( state.copyWith( status: StaffStatus.error, error: "Errore nell'assegnazione: $e", ), ); } } // Rimuove un dipendente da un negozio Future removeMemberFromStore(String staffId, String storeId) async { try { await _repository.removeStaffFromStore(staffId, storeId); final stuffStores = await loadStoresByStaff(staffId); final Map> storesByStaff = Map.from( state.storesByStaff, ); storesByStaff[staffId] = stuffStores; emit(state.copyWith(storesByStaff: storesByStaff, error: null)); } catch (e) { emit( state.copyWith( status: StaffStatus.error, error: "Errore nella rimozione: $e", ), ); } } Future saveStaffWithStores({ required StaffMemberModel member, required List selectedStoreIds, }) async { emit(state.copyWith(status: StaffStatus.loading, error: null)); try { // 1. Salva o aggiorna l'anagrafica (ci serve l'ID) // Se è un nuovo membro, Supabase ci restituirà l'ID generato final savedMember = await _repository.saveStaffMember(member); final String staffId = savedMember.id!; // 2. Sincronizzazione Negozi // Per semplicità e pulizia, rimuoviamo le vecchie assegnazioni e inseriamo le nuove // (Oppure facciamo un confronto tra liste, ma il reset & rewrite è più sicuro qui) await _repository.clearStoreAssignments(staffId); if (selectedStoreIds.isNotEmpty) { await Future.wait( selectedStoreIds.map( (storeId) => _repository.assignStaffToStore(staffId, storeId), ), ); } // 3. Rinfresca i dati await loadAllStaff(); emit(state.copyWith(status: StaffStatus.success)); } catch (e) { emit(state.copyWith(status: StaffStatus.error, error: e.toString())); } } }