import 'package:equatable/equatable.dart'; import 'package:flux/features/master_data/staff/models/staff_member_model.dart'; import 'package:flux/features/tasks/models/task_status.dart'; class TaskModel extends Equatable { final String? id; final String? companyId; final String title; final String? description; final List assignedToIds; final List assignedToStaff; // I dati completi dal JOIN final String? createdById; final DateTime? dueDate; final TaskStatus status; final DateTime? createdAt; final String? storeId; const TaskModel({ this.id, this.companyId, required this.title, this.description, this.assignedToIds = const [], this.assignedToStaff = const [], this.createdById, this.dueDate, this.status = TaskStatus.open, this.createdAt, this.storeId, }); // --- FACTORY: MODELLO VUOTO (Per le creazioni) --- factory TaskModel.empty({String? companyId, String? createdById}) { return TaskModel( companyId: companyId, title: '', description: '', assignedToIds: const [], assignedToStaff: const [], createdById: createdById, status: TaskStatus.open, createdAt: DateTime.now(), ); } // --- EQUATABLE: PROPRIETÀ DA COMPARARE --- @override List get props => [ id, companyId, title, description, assignedToIds, assignedToStaff, createdById, dueDate, status, createdAt, storeId, ]; // --- COPY WITH --- TaskModel copyWith({ String? id, String? companyId, String? title, String? description, List? assignedToIds, List? assignedToStaff, String? createdById, DateTime? dueDate, bool clearDueDate = false, // Flag ninja per resettare la scadenza TaskStatus? status, DateTime? createdAt, String? storeId, bool clearStoreId = false, }) { return TaskModel( id: id ?? this.id, companyId: companyId ?? this.companyId, title: title ?? this.title, description: description ?? this.description, assignedToIds: assignedToIds ?? this.assignedToIds, assignedToStaff: assignedToStaff ?? this.assignedToStaff, createdById: createdById ?? this.createdById, dueDate: clearDueDate ? null : (dueDate ?? this.dueDate), status: status ?? this.status, createdAt: createdAt ?? this.createdAt, storeId: clearStoreId ? null : (storeId ?? this.storeId), ); } // --- SERIALIZZAZIONE DA SUPABASE --- factory TaskModel.fromMap(Map json) { // 1. Gestiamo l'array nullo di Supabase trasformandolo in lista vuota final List parsedAssignedToIds = json['assigned_to_ids'] != null ? List.from(json['assigned_to_ids']) : []; // 2. Mappiamo il JOIN dello staff, se presente List parsedAssignedToStaff = []; if (json['assigned_to_staff'] != null) { final staffList = json['assigned_to_staff'] as List; parsedAssignedToStaff = staffList .map((s) => StaffMemberModel.fromMap(s as Map)) .toList(); } return TaskModel( id: json['id'] as String?, companyId: json['company_id'] as String?, title: json['title'] as String? ?? '', description: json['description'] as String?, assignedToIds: parsedAssignedToIds, assignedToStaff: parsedAssignedToStaff, createdById: json['created_by_id'] as String?, dueDate: json['due_date'] != null ? DateTime.parse(json['due_date'] as String).toLocal() : null, status: TaskStatusExtension.fromString(json['status'] as String?), createdAt: json['created_at'] != null ? DateTime.parse(json['created_at'] as String).toLocal() : null, storeId: json['store_id'] as String?, ); } // --- SERIALIZZAZIONE VERSO SUPABASE --- Map toMap() { return { if (id != null) 'id': id, if (companyId != null) 'company_id': companyId, 'title': title, if (description != null) 'description': description, // Passiamo l'array vuoto se non ci sono assegnazioni 'assigned_to_ids': assignedToIds.isEmpty ? null : assignedToIds, if (createdById != null) 'created_by_id': createdById, 'due_date': dueDate?.toUtc().toIso8601String(), 'status': status.toValue, 'store_id': storeId, }; } }