class TaskModel {
  final DateTime assignmentDate;
  final DateTime? reportedDate;
  final String id;
  final WorkItem? workItem;
  final String workItemId;
  final double plannedTask;
  final double completedTask;
  final AssignedBy assignedBy;
  final AssignedBy? approvedBy;
  final List<TeamMember> teamMembers;
  final List<Comment> comments;
  final List<String> reportedPreSignedUrls;

  TaskModel({
    required this.assignmentDate,
    this.reportedDate,
    required this.id,
    this.workItem,
    required this.workItemId,
    required this.plannedTask,
    required this.completedTask,
    required this.assignedBy,
    this.approvedBy,
    this.teamMembers = const [],
    this.comments = const [],
    this.reportedPreSignedUrls = const [],
  });

  factory TaskModel.fromJson(Map<String, dynamic> json) {
    return TaskModel(
      assignmentDate: DateTime.parse(json['assignmentDate'] ?? DateTime.now().toIso8601String()),
      reportedDate: json['reportedDate'] != null ? DateTime.tryParse(json['reportedDate']) : null,
      id: json['id']?.toString() ?? '',
      workItem: json['workItem'] != null ? WorkItem.fromJson(json['workItem']) : null,
      workItemId: json['workItemId']?.toString() ?? '',
      plannedTask: (json['plannedTask'] as num?)?.toDouble() ?? 0,
      completedTask: (json['completedTask'] as num?)?.toDouble() ?? 0,
      assignedBy: AssignedBy.fromJson(json['assignedBy'] ?? {}),
      approvedBy: json['approvedBy'] != null ? AssignedBy.fromJson(json['approvedBy']) : null,
      teamMembers: (json['teamMembers'] as List<dynamic>?)
              ?.map((e) => TeamMember.fromJson(e))
              .toList() ??
          [],
      comments: (json['comments'] as List<dynamic>?)
              ?.map((e) => Comment.fromJson(e))
              .toList() ??
          [],
      reportedPreSignedUrls: (json['reportedPreSignedUrls'] as List<dynamic>?)
              ?.map((e) => e.toString())
              .toList() ??
          [],
    );
  }
}

class WorkItem {
  final String? id;
  final ActivityMaster? activityMaster;
  final WorkArea? workArea;
  final double? plannedWork;
  final double? completedWork;
  final List<String> preSignedUrls;

  WorkItem({
    this.id,
    this.activityMaster,
    this.workArea,
    this.plannedWork,
    this.completedWork,
    this.preSignedUrls = const [],
  });

  factory WorkItem.fromJson(Map<String, dynamic> json) {
    return WorkItem(
      id: json['id']?.toString(),
      activityMaster: json['activityMaster'] != null
          ? ActivityMaster.fromJson(json['activityMaster'])
          : null,
      workArea: json['workArea'] != null ? WorkArea.fromJson(json['workArea']) : null,
      plannedWork: (json['plannedWork'] as num?)?.toDouble(),
      completedWork: (json['completedWork'] as num?)?.toDouble(),
      preSignedUrls: (json['preSignedUrls'] as List<dynamic>?)
              ?.map((e) => e.toString())
              .toList() ??
          [],
    );
  }
}

class ActivityMaster {
  final String? id;
  final String activityName;

  ActivityMaster({
    this.id,
    required this.activityName,
  });

  factory ActivityMaster.fromJson(Map<String, dynamic> json) {
    return ActivityMaster(
      id: json['id']?.toString(),
      activityName: json['activityName']?.toString() ?? '',
    );
  }
}

class WorkArea {
  final String? id;
  final String areaName;
  final Floor? floor;

  WorkArea({
    this.id,
    required this.areaName,
    this.floor,
  });

  factory WorkArea.fromJson(Map<String, dynamic> json) {
    return WorkArea(
      id: json['id']?.toString(),
      areaName: json['areaName']?.toString() ?? '',
      floor: json['floor'] != null ? Floor.fromJson(json['floor']) : null,
    );
  }
}

class Floor {
  final String floorName;
  final Building? building;

  Floor({required this.floorName, this.building});

  factory Floor.fromJson(Map<String, dynamic> json) {
    return Floor(
      floorName: json['floorName']?.toString() ?? '',
      building: json['building'] != null ? Building.fromJson(json['building']) : null,
    );
  }
}

class Building {
  final String name;

  Building({required this.name});

  factory Building.fromJson(Map<String, dynamic> json) {
    return Building(name: json['name']?.toString() ?? '');
  }
}

class AssignedBy {
  final String id;
  final String firstName;
  final String? lastName;

  AssignedBy({
    required this.id,
    required this.firstName,
    this.lastName,
  });

  factory AssignedBy.fromJson(Map<String, dynamic> json) {
    return AssignedBy(
      id: json['id']?.toString() ?? '',
      firstName: json['firstName']?.toString() ?? '',
      lastName: json['lastName']?.toString(),
    );
  }
}

class TeamMember {
  final String id;
  final String firstName;
  final String? lastName;

  TeamMember({
    required this.id,
    required this.firstName,
    this.lastName,
  });

  factory TeamMember.fromJson(Map<String, dynamic> json) {
    return TeamMember(
      id: json['id']?.toString() ?? '',
      firstName: json['firstName']?.toString() ?? '',
      lastName: json['lastName']?.toString(),
    );
  }
}

class Comment {
  final String comment;
  final TeamMember commentedBy;
  final DateTime timestamp;
  final List<String> preSignedUrls;

  Comment({
    required this.comment,
    required this.commentedBy,
    required this.timestamp,
    this.preSignedUrls = const [],
  });

  factory Comment.fromJson(Map<String, dynamic> json) {
    return Comment(
      comment: json['comment']?.toString() ?? '',
      commentedBy: json['employee'] != null
          ? TeamMember.fromJson(json['employee'])
          : TeamMember(id: '', firstName: '', lastName: null),
      timestamp: json['commentDate'] != null
          ? DateTime.parse(json['commentDate'])
          : DateTime.now(),
      preSignedUrls: (json['preSignedUrls'] as List<dynamic>?)
              ?.map((e) => e.toString())
              .toList() ??
          [],
    );
  }
}
