import 'package:collection/collection.dart'; 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/models/staff_member_model.dart'; import 'package:flux/features/tasks/data/task_repository.dart'; import 'package:flux/features/tasks/models/task_model.dart'; import 'package:flux/features/tasks/models/task_status.dart'; import 'package:get_it/get_it.dart'; part 'task_form_state.dart'; class TaskFormCubit extends Cubit { final TaskRepository _taskRepository = GetIt.I.get(); final TaskModel? _initialTask; final String? _initialTaskId; // Cache in memoria proveniente dallo StaffCubit! final List _globalStaff; final String currentCompanyId = GetIt.I .get() .state .company! .id!; final String? currentStoreId = GetIt.I .get() .state .currentStore ?.id; TaskFormCubit({ required List globalStaff, // Iniettiamo la lista qui TaskModel? initialTask, String? initialTaskId, }) : _globalStaff = globalStaff, _initialTask = initialTask, _initialTaskId = initialTaskId, super(const TaskFormState()) { _initForm(task: initialTask, initialTaskId: initialTaskId); } // --- 1. INIZIALIZZAZIONE SINCRONA --- void _initForm({TaskModel? task, String? initialTaskId}) { final isGlobalMode = task != null ? task.storeId == null : currentStoreId == null; // MAGIA: Estraiamo gli ID dagli oggetti staff, o facciamo fallback su assignedToIds se c'è final existingStaffIds = task?.assignedToStaff.map((s) => s.id!).toList() ?? task?.assignedToIds ?? []; emit( state.copyWith( id: task?.id, title: task?.title ?? '', description: task?.description ?? '', dueDate: task?.dueDate, taskStatus: task?.status ?? TaskStatus.open, isGlobal: isGlobalMode, selectedStaffIds: existingStaffIds, // Ora non si perde più i dipendenti! ), ); _updateStaffScope(isGlobalMode); } // --- 2. SWITCH SCOPE E RAGGRUPPAMENTO --- void toggleGlobalScope(bool isGlobal) { emit( state.copyWith( isGlobal: isGlobal, selectedStaffIds: [], // Resettiamo la selezione se si cambia scope ), ); _updateStaffScope(isGlobal); } void _updateStaffScope(bool isGlobal) { // 1. Filtriamo in memoria final filteredStaff = isGlobal ? _globalStaff : _globalStaff.where((s) => s.store?.id == currentStoreId).toList(); // 2. Raggruppiamo per nome negozio (usando groupBy del pacchetto collection) final groupedStaff = groupBy( filteredStaff, (StaffMemberModel s) => s.store?.name ?? 'Direzione / HQ', ); // 3. Emettiamo il nuovo stato all'istante emit( state.copyWith( status: TaskFormStatus.initial, groupedAvailableStaff: groupedStaff, ), ); } // --- 3. SELEZIONE AVANZATA (SINGOLA E PER NEGOZIO) --- void toggleStaffSelection(String staffId) { final currentList = List.from(state.selectedStaffIds); if (currentList.contains(staffId)) { currentList.remove(staffId); } else { currentList.add(staffId); } emit(state.copyWith(selectedStaffIds: currentList)); } void toggleStoreSelection(String storeName, bool selectAll) { // Recupera tutti i membri di quel gruppo final staffInStore = state.groupedAvailableStaff[storeName] ?? []; final idsInStore = staffInStore.map((s) => s.id!).toList(); final currentSelection = Set.from(state.selectedStaffIds); if (selectAll) { currentSelection.addAll(idsInStore); } else { currentSelection.removeAll(idsInStore); } emit(state.copyWith(selectedStaffIds: currentSelection.toList())); } // --- 4. AGGIORNAMENTO CAMPI STANDARD --- void updateTitle(String title) => emit(state.copyWith(title: title)); void updateDescription(String desc) => emit(state.copyWith(description: desc)); void updateDueDate(DateTime? date) => emit(state.copyWith(dueDate: date, clearDueDate: date == null)); void updateLinkedTicket(String? ticketId) => emit(state.copyWith(linkedTicketId: ticketId)); // --- 5. LOGICA DEI REMINDER FINTI --- void addMockReminder(String type, int minutes) { final currentReminders = List.from(state.reminders); currentReminders.add(TaskReminder(type: type, minutesBefore: minutes)); emit(state.copyWith(reminders: currentReminders)); } void removeMockReminder(int index) { final currentReminders = List.from(state.reminders); currentReminders.removeAt(index); emit(state.copyWith(reminders: currentReminders)); } // --- 6. SALVATAGGIO FINALE --- Future saveTask({required String currentUserId}) async { if (!state.isFormValid) return; emit(state.copyWith(status: TaskFormStatus.submitting)); try { final taskToSave = TaskModel( id: state.id, companyId: currentCompanyId, storeId: state.isGlobal ? null : currentStoreId, // La vera discriminante Globale/Store! createdById: state.id == null ? currentUserId : null, // Lo settiamo solo alla creazione title: state.title.trim(), description: state.description.trim().isEmpty ? null : state.description.trim(), dueDate: state.dueDate, status: state.taskStatus, assignedToIds: state .selectedStaffIds, // L'array che andrà a popolare la tabella di giunzione ); if (state.id == null) { await _taskRepository.createTask(taskToSave); } else { await _taskRepository.updateTask(taskToSave); } emit(state.copyWith(status: TaskFormStatus.success)); } catch (e) { emit( state.copyWith( status: TaskFormStatus.failure, errorMessage: 'Errore durante il salvataggio: $e', ), ); } } }