import 'dart:typed_data';

import 'package:flutter/cupertino.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/assigned_employee.dart';
import 'package:test_sa/models/new_models/building.dart';
import 'package:test_sa/models/new_models/department.dart';
import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/models/new_models/mapped_sites.dart';
import 'package:test_sa/models/new_models/site.dart';
import 'package:test_sa/models/timer_model.dart';

class GasRefillModel {
  GasRefillModel({
    this.id,
    this.gasRefillNo,
    this.expectedDate,
    this.expectedTime,
    this.startDate,
    this.startTime,
    this.endDate,
    this.endTime,
    this.engSignature,
    this.nurseSignature,
    this.workingHours,
    this.extensionNo,
    this.employeeId,
    this.name,
    this.createdDate,
    this.site,
    this.building,
    this.floor,
    this.department,
    this.assignedEmployee,
    this.status,
    this.comment,
    this.mapSite,
    this.mappedFloor,
    this.mappedBuilding,
    this.mappedDepartment,
    this.techComment,
    this.gasRefillDetails,
    this.localEngineerSignature,
    this.localNurseSignature,
    this.timer,
    this.gasRefillTimePicker,
    this.timerModelList,
    this.gasRefillTimers,
    this.gasRefillAttachments,
    this.gasRefillContactPerson,
    this.statusValue,
  });

  num? id; // Now nullable
  String? gasRefillNo; // Now nullable
  String? expectedDate; // Now nullable
  String? expectedTime; // Now nullable
  String? startDate; // Now nullable
  String? startTime; // Now nullable
  String? endDate; // Now nullable
  String? endTime; // Now nullable
  String? engSignature; // Now nullable
  String? nurseSignature; // Now nullable
  double? workingHours;
  dynamic extensionNo;
  String? employeeId;
  String? name;
  String? createdDate;
  Site? site; // Now nullable
  Building? building; // Now nullable
  Floor? floor; // Now nullable
  Department? department; // Now nullable
  MappedSite? mapSite; // Now nullable
  MappedBuilding? mappedBuilding; // Now nullable
  MappedFloor? mappedFloor; // Now nullable
  MappedDepartment? mappedDepartment; //
  AssignedEmployee? assignedEmployee; // Now nullable
  Lookup? status; // Now nullable
  String? comment; // Now nullable
  String? techComment; // Now nullable
  List<GasRefillDetails>? gasRefillDetails; // Now nullable
  Uint8List? localNurseSignature; // Now nullable
  Uint8List? localEngineerSignature; // Now nullable
  TimerModel? timer = TimerModel();
  TimerModel? gasRefillTimePicker;
  List<TimerModel>? timerModelList = [];
  List<GasRefillTimer>? gasRefillTimers = [];
  List<GenericAttachmentModel>? gasRefillAttachments;
  List<GasRefillContactPerson>? gasRefillContactPerson;
  int? statusValue;

  GasRefillModel.fromJson(dynamic json) {
    id = json['id'];
    gasRefillNo = json['gasRefillNo'];
    expectedDate = json['expectedDate'];
    expectedTime = json['expectedTime'];
    startDate = json['startDate'];
    startTime = json['startTime'];
    endDate = json['endDate'];
    endTime = json['endTime'];
    comment = json['comment'];
    techComment = json['techComment'];
    workingHours = json['workingHours'];
    extensionNo = json['extensionNo'];
    employeeId = json['employeeId'];
    name = json['name'];
    createdDate = json['createdDate'];
    if (json['gasRefillTimers'] != null) {
      gasRefillTimers = <GasRefillTimer>[];
      json['gasRefillTimers'].forEach((v) {
        gasRefillTimers?.add(GasRefillTimer.fromJson(v));
      });
      workingHours = json['gasRefillTimers'].fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item['endDate']).difference(DateTime.parse(item['startDate'])).inSeconds) ?? 0;
    }
    if (json['gasRefillAttachments'] != null) {
      gasRefillAttachments = <GenericAttachmentModel>[];
      json['gasRefillAttachments'].forEach((v) {
        gasRefillAttachments!.add(GenericAttachmentModel.fromGasRefillJson(v));
      });
    }
    if (json['gasRefillContactPerson'] != null) {
      gasRefillContactPerson = [];
      json['gasRefillContactPerson'].forEach((v) {
        gasRefillContactPerson?.add(GasRefillContactPerson.fromJson(v));
      });
    }

    engSignature = json['engSignature'];
    nurseSignature = json['nurseSignature'];
    site = json['site'] != null ? Site.fromJson(json['site']) : null;
    building = json['building'] != null ? Building.fromJson(json['building']) : null;
    floor = json['floor'] != null ? Floor.fromJson(json['floor']) : null;
    department = json['department'] != null ? Department.fromJson(json['department']) : null;
    mapSite = json['site'] != null ? MappedSite.fromJson(json['site']) : null;
    mappedBuilding = mapSite?.buildings?.firstWhere((element) => element.identifier == building?.identifier, orElse: () => MappedBuilding());
    mappedFloor = mappedBuilding?.floors?.firstWhere((element) => element.identifier == floor?.identifier, orElse: () => MappedFloor());
    mappedDepartment = mappedFloor?.departments?.firstWhere((element) => element.identifier == department?.identifier, orElse: () => MappedDepartment());
    assignedEmployee = json['assignedEmployee'] != null ? AssignedEmployee.fromJson(json['assignedEmployee']) : null;
    status = json['status'] != null ? Lookup.fromJson(json['status']) : null;
    if (json['gasRefillDetails'] != null) {
      gasRefillDetails = [];
      json['gasRefillDetails'].forEach((v) {
        gasRefillDetails!.add(GasRefillDetails.fromJson(v)); // Use '!' since gasRefillDetails is initialized here
      });
    }
  }

  Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};

    map['id'] = id ?? 0;
    map['gasTypeId'] = gasRefillDetails?[0].gasType?.id;
    map['cylinderTypeId'] = gasRefillDetails?[0].cylinderType?.id;
    map['cylinderSizeId'] = gasRefillDetails?[0].cylinderSize?.id;
    map['requestedQty'] = gasRefillDetails?[0].requestedQty;
    if (mapSite != null) {
      map['siteId'] = mapSite?.id; // Use '?.' for null safety
    }
    if (mappedBuilding != null) {
      map['buildingId'] = mappedBuilding?.clientBuildingId; // Use '?.' for null safety
    }
    if (mappedFloor != null) {
      map['floorId'] = mappedFloor?.clientFloorId; // Use '?.' for null safety
    }
    if (mappedDepartment != null) {
      map['departmentId'] = mappedDepartment?.departmentId; // Use '?.' for null safety
    }
    map['comment'] = comment;

    if (gasRefillAttachments != null) {
      map['gasRefillAttachments'] = gasRefillAttachments?.map((v) => v.toGasRefillJson() ?? {}).toList();
    }

    //older code.....
    // map['gasRefillNo'] = "GR-${DateTime.now().toString().split(" ").first}";
    // map['expectedTime'] = expectedTime;
    //
    // map['startDate'] = startDate;
    // map['startTime'] = startTime;
    // map['endDate'] = endDate;
    // map['endTime'] = endTime;
    // map['engSignature'] = engSignature;
    // map['nurseSignature'] = nurseSignature;
    // map['workingHours'] = workingHours;
    // map['extensionNo'] = extensionNo;
    // map['employeeId'] = employeeId;
    // map['name'] = name;
    // map['createdDate'] = createdDate;
    // map['comment'] = comment;
    // if (site != null) {
    //   map['site'] = site?.toJson(addBuildings: false); // Use '?.' for null safety
    // }
    // if (building != null) {
    //   map['building'] = building?.toJson(addFloor: false); // Use '?.' for null safety
    // }
    // if (floor != null) {
    //   map['floor'] = floor?.toJson(addDepartments: false); // Use '?.' for null safety
    // }
    // if (department != null) {
    //   map['department'] = department?.toJson(); // Use '?.' for null safety
    // }
    // if (assignedEmployee != null) {
    //   map['assignedEmployee'] = assignedEmployee?.toJson(); // Use '?.' for null safety
    // }
    // if (status != null) {
    //   map['status'] = status?.toJson(); // Use '?.' for null safety
    // }
    // if (gasRefillDetails != null) {
    //   map['gasRefillDetails'] = gasRefillDetails!.map((v) => v.toJson()).toList(); // Use '!' since gasRefillDetails could be null
    // }

    return map;
  }

  Map<String, dynamic> toUpdateEngineerPayload({required int status}) {
    final map = <String, dynamic>{};
    map['id'] = id ?? 0;
    map['deliveredQty'] = gasRefillDetails?[0].deliverdQty;
    map['statusValue'] = status;
    map['techComment'] = techComment;
    if (gasRefillTimers != null) {
      map['gasRefillTimers'] = gasRefillTimers?.map((v) => v.toJson()).toList();
    }
    if (gasRefillContactPerson != null) {
      map['gasRefillContactPerson'] = gasRefillContactPerson?.map((v) => v?.toJson() ?? {}).toList();
    }

    return map;
  }

  bool validate(BuildContext context) {
    if (site == null) {
      Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.destinationSite}");
      return false;
    } else if (building == null) {
      Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.building}");
      return false;
    } else if (floor == null) {
      Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.floor}");
      return false;
    } else if (department == null) {
      Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.department}");
      return false;
    }
    return true;
  }

  fromGasRefillModel(GasRefillModel model) {
    id = model.id;
    //userId = model.userId;
    site = model.site;
    gasRefillNo = model.gasRefillNo;
    status = Lookup.fromStatus(model.status);
    gasRefillDetails = model.gasRefillDetails;
    building = model.building;
    floor = model.floor;
    department = model.department;
    startDate = model.startDate;
    endDate = model.endDate;
    expectedDate = model.expectedDate;
    comment = model.comment;
    assignedEmployee = model.assignedEmployee;
    localEngineerSignature = model.localEngineerSignature;
    localNurseSignature = model.localNurseSignature;
    engSignature = model.engSignature;
    nurseSignature = model.nurseSignature;
    workingHours = model.workingHours;
    extensionNo = model.extensionNo;
    employeeId = model.employeeId;
    name = model.name;
    techComment = model.techComment;
    gasRefillAttachments = model.gasRefillAttachments;
    createdDate = model.createdDate;
    workingHours = model.workingHours;
    gasRefillTimers = model.gasRefillTimers;
  }

  GasRefillModel copyWith({
    num? id, // Parameters are now nullable
    String? gasRefillNo,
    String? expectedDate,
    String? expectedTime,
    String? startDate,
    String? startTime,
    String? endDate,
    String? endTime,
    String? engSignature,
    String? nurseSignature,
    double? workingHours,
    num? extensionNo,
    num? employeeId,
    String? name,
    String? createdDate,
    Site? site,
    Building? building,
    Floor? floor,
    Department? department,
    AssignedEmployee? assignedEmployee,
    Lookup? status,
    String? comment,
    List<GasRefillDetails>? gasRefillDetails,
    List<GasRefillTimer>? gasRefillTimer,
    TimerModel? timer,
  }) =>
      GasRefillModel(
        id: id ?? this.id,
        gasRefillNo: gasRefillNo ?? this.gasRefillNo,
        expectedDate: expectedDate ?? this.expectedDate,
        expectedTime: expectedTime ?? this.expectedTime,
        startDate: startDate ?? this.startDate,
        startTime: startTime ?? this.startTime,
        endDate: endDate ?? this.endDate,
        endTime: endTime ?? this.endTime,
        engSignature: engSignature ?? this.engSignature,
        nurseSignature: nurseSignature ?? this.nurseSignature,
        workingHours: workingHours ?? this.workingHours,
        site: site ?? this.site,
        building: building ?? this.building,
        floor: floor ?? this.floor,
        department: department ?? this.department,
        assignedEmployee: assignedEmployee ?? this.assignedEmployee,
        status: status ?? this.status,
        comment: comment ?? this.comment,
        gasRefillDetails: gasRefillDetails ?? this.gasRefillDetails,
        timer: timer ?? this.timer,
        gasRefillTimers: gasRefillTimer ?? this.gasRefillTimers,
      );
}

class GasRefillDetails {
  GasRefillDetails({
    this.id,
    this.gasType,
    this.cylinderType,
    this.cylinderSize,
    this.requestedQty,
    this.deliverdQty,
    this.selectedForEditing,
  });

  GasRefillDetails.fromJson(dynamic json) {
    id = json['id'];
    gasType = json['gasType'] != null ? Lookup.fromJson(json['gasType']) : null;
    cylinderType = json['cylinderType'] != null ? Lookup.fromJson(json['cylinderType']) : null;
    cylinderSize = json['cylinderSize'] != null ? Lookup.fromJson(json['cylinderSize']) : null;
    requestedQty = json['requestedQty'];
    deliverdQty = json['deliverdQty'];
  }

  num? id; // Now nullable
  Lookup? gasType; // Now nullable
  Lookup? cylinderType; // Now nullable
  Lookup? cylinderSize; // Now nullable
  num? requestedQty; // Now nullable
  num? deliverdQty; // Now nullable
  bool? selectedForEditing; // Now nullable

  GasRefillDetails copyWith({
    num? id, // Parameters are now nullable
    Lookup? gasType,
    Lookup? cylinderType,
    Lookup? cylinderSize,
    num? requestedQty,
    num? deliverdQty,
    bool? selectedForEditing,
  }) =>
      GasRefillDetails(
        id: id ?? this.id,
        gasType: gasType ?? this.gasType,
        cylinderType: cylinderType ?? this.cylinderType,
        cylinderSize: cylinderSize ?? this.cylinderSize,
        requestedQty: requestedQty ?? this.requestedQty,
        deliverdQty: deliverdQty ?? this.deliverdQty,
        selectedForEditing: selectedForEditing ?? this.selectedForEditing,
      );

  Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};
    map['id'] = id ?? 0;
    if (gasType != null) {
      map['gasType'] = gasType?.toJson(); // Use '?.' for null safety
    }
    if (cylinderType != null) {
      map['cylinderType'] = cylinderType?.toJson(); // Use '?.' for null safety
    }
    if (cylinderSize != null) {
      map['cylinderSize'] = cylinderSize?.toJson(); // Use '?.' for null safety
    }
    map['requestedQty'] = requestedQty;
    map['deliverdQty'] = deliverdQty;
    return map;
  }

  bool validate(BuildContext context) {
    if (gasType == null) {
      Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.gasType}");
      return false;
    } else if (requestedQty == null) {
      Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.quantity}");
      return false;
    } else if (cylinderType == null) {
      Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.cylinderType}");
      return false;
    } else if (cylinderSize == null) {
      Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.cylinderSize}");
      return false;
    }
    return true;
  }
}

class GasRefillTimer {
  int? id;
  String? startDate;
  String? endDate;
  dynamic workingHours;

  GasRefillTimer({this.id, this.startDate, this.endDate, this.workingHours});

  GasRefillTimer.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    startDate = json['startDate'];
    endDate = json['endDate'];
    workingHours = json['workingHours'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['id'] = id;
    data['startDate'] = startDate;
    data['endDate'] = endDate;
    data['workingHours'] = workingHours;
    return data;
  }
}

// class GasRefillAttachments {
//   int? id;
//   num? gasRefillId;
//   String? attachmentName;
//   Lookup ? documentType;
//
//   GasRefillAttachments({this.id, this.attachmentName,this.documentType, this.gasRefillId});
//
//   GasRefillAttachments.fromJson(Map<String, dynamic> json) {
//     id = json['id'];
//     gasRefillId = json['gasRefillId'];
//     attachmentName = json['attachmentName'];
//     documentType = json['documentType'];
//   }
//
//   Map<String, dynamic> toJson() {
//     final Map<String, dynamic> data = <String, dynamic>{};
//     data['id'] = id;
//     data['gasRefillId'] = gasRefillId;
//     data['attachmentName'] = attachmentName;
//     data['documentTypeId'] = documentType?.id;
//     return data;
//   }
// }

class GasRefillContactPerson {
  int? id;
  int? gasRefillId;
  String? employeeId;
  String? employeeCode;
  String? name;
  String? email;
  String? mobilePhone;
  String? extension;

  GasRefillContactPerson({
    this.id,
    this.gasRefillId,
    this.employeeId,
    this.employeeCode,
    this.name,
    this.email,
    this.mobilePhone,
    this.extension,
  });

  factory GasRefillContactPerson.fromJson(Map<String, dynamic> json) {
    return GasRefillContactPerson(
      id: json['id'],
      gasRefillId: json['gasRefillId'],
      employeeId: json['employeeId'],
      employeeCode: json['employeeCode'],
      name: json['name'],
      email: json['email'],
      mobilePhone: json['mobilePhone'],
      extension: json['extension'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'gasRefillId': gasRefillId,
      'employeeId': employeeId,
      'employeeCode': employeeCode,
      'name': name,
      'email': email,
      'mobilePhone': mobilePhone,
      'extension': extension,
    };
  }
}
class AssignedEmployee {
  String? id;
  String? name;
  String? email;
  String? employeeId;
  int? languageId;
  String? extensionNo;
  String? phoneNumber;
  String? positionName;
  String? position;
  bool? isActive;

  AssignedEmployee(
      {this.id,
        this.name,
        this.email,
        this.employeeId,
        this.languageId,
        this.extensionNo,
        this.phoneNumber,
        this.positionName,
        this.position,
        this.isActive});

  AssignedEmployee.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    email = json['email'];
    employeeId = json['employeeId'];
    languageId = json['languageId'];
    extensionNo = json['extensionNo'];
    phoneNumber = json['phoneNumber'];
    positionName = json['positionName'];
    position = json['position'];
    isActive = json['isActive'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['email'] = this.email;
    data['employeeId'] = this.employeeId;
    data['languageId'] = this.languageId;
    data['extensionNo'] = this.extensionNo;
    data['phoneNumber'] = this.phoneNumber;
    data['positionName'] = this.positionName;
    data['position'] = this.position;
    data['isActive'] = this.isActive;
    return data;
  }
}
