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<String> assignedToIds;
  final List<StaffMemberModel> 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,
  });

  bool get isGlobal => storeId == null;

  // --- 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<Object?> 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<String>? assignedToIds,
    List<StaffMemberModel>? 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<String, dynamic> map) {
    // 1. Gestiamo l'array nullo di Supabase trasformandolo in lista vuota
    final List<String> parsedAssignedToIds = map['assigned_to_ids'] != null
        ? List<String>.from(map['assigned_to_ids'])
        : [];

    // 2. Mappiamo il JOIN dello staff, se presente
    List<StaffMemberModel> staffList = [];

    // Gestione del JSON proveniente dal Join nidificato (es. task_assignments -> staff_members)
    if (map['task_assignments'] != null) {
      staffList = (map['task_assignments'] as List)
          .map((a) => a['staff_members'])
          .where((s) => s != null)
          .map((s) => StaffMemberModel.fromMap(s))
          .toList();
    }
    // Gestione del JSON piatto (se mai lo userai in altre chiamate RPC o viste)
    else if (map['assigned_to_staff'] != null) {
      staffList = (map['assigned_to_staff'] as List)
          .map((s) => StaffMemberModel.fromMap(s))
          .toList();
    }

    return TaskModel(
      id: map['id'] as String?,
      companyId: map['company_id'] as String?,
      title: map['title'] as String? ?? '',
      description: map['description'] as String?,
      assignedToIds: parsedAssignedToIds,
      assignedToStaff: staffList,
      createdById: map['created_by_id'] as String?,
      dueDate: map['due_date'] != null
          ? DateTime.parse(map['due_date'] as String).toLocal()
          : null,
      status: TaskStatusExtension.fromString(map['status'] as String?),
      createdAt: map['created_at'] != null
          ? DateTime.parse(map['created_at'] as String).toLocal()
          : null,
      storeId: map['store_id'] as String?,
    );
  }

  // --- SERIALIZZAZIONE VERSO SUPABASE ---
  Map<String, dynamic> 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,
    };
  }
}
