import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/pantry/calibration_tools.dart';
import 'package:test_sa/models/pantry/pm_kit.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart';
import 'package:test_sa/models/timer_model.dart';

class Pentry {
  Lookup ppmVisitStatus;
  Lookup status;
  TimerModel timer;
  DateTime actualVisitDate;
  DateTime expectedVisitDate;
  String travelingHours;
  String image;
  File imageFile;
  // List<Contact> contacts;
  List<PPMCheckList> ppmCheckLists;
  List<CalibrationTool> calibrationTools;
  List<PMKit> pmKits;
  String signatureNurse;
  String signatureEngineer;
  Uint8List localNurseSignature;
  Uint8List localEngineerSignature;

  Pentry(
      {this.travelingHours,
      this.timer,
      this.status,
      this.ppmVisitStatus,
      this.actualVisitDate,
      this.expectedVisitDate,
      this.image,
      this.imageFile,
      // this.contacts,
      this.ppmCheckLists,
      this.calibrationTools,
      this.pmKits,
      this.signatureNurse,
      this.signatureEngineer,
      this.localNurseSignature,
      this.localEngineerSignature});

  bool validate() {
    if (actualVisitDate == null) return false;
    if (expectedVisitDate == null) return false;
    if (timer == null && timer.endAt != null) return false;
    if (ppmVisitStatus == null) return false;
    //if(status == null) return false;

    return true;
  }

  Map<String, dynamic> toMap(int visitId) {
    Map<String, dynamic> map = {};
    map["visitStatusId"] = ppmVisitStatus?.id.toString();
    if (status != null) map["deviceStatusId"] = status?.id.toString();
    if (travelingHours != null) map["travelingHours"] = travelingHours;
    //if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync());
    map["actualDate"] = actualVisitDate.toIso8601String();
    map["expectedDate"] = expectedVisitDate.toIso8601String();
    if (timer != null) {
      map["startDate"] = timer.startAt.toIso8601String();
      map["endDate"] = timer.endAt?.toIso8601String() ?? DateTime.now().toIso8601String();
      map["workingHours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5);
    }
    if (imageFile != null) {
      map["vAttachments"] = [
        {"attachmentName": (imageFile.path.split("/").last + base64Encode(imageFile.readAsBytesSync()))}
      ];
    }
    map["travelingHours"] = travelingHours;
    // if(contacts?.isNotEmpty == true) {
    //   for(int i = 0;i<contacts.length;i++){
    //     contacts[i].toMap().forEach((key, value) {
    //       body["contacts[$i].$key"] = value;
    //     });
    //   }
    // }
    map["vChecklists"] = ppmCheckLists.map((e) => e.toMap(visitId)).toList();
    map["vCalibrationTools"] = calibrationTools.map((e) => e.toMap(visitId)).toList();
    map["vKits"] = pmKits.map((e) => e.toMap(visitId)).toList();
    map["nurseSignature"] = "${DateTime.now().toIso8601String()}.png|$signatureNurse";
    map["engSignature"] = "${DateTime.now().toIso8601String()}.png|$signatureEngineer";
    return map;
  }

  factory Pentry.fromMap(Map<String, dynamic> map) {
    // List<Contact> contacts = [];
    // if(map['contacts'] != null){
    //   contacts =(map['contacts'] as List<dynamic>)
    //       .map((e) => Contact.fromMap(e as Map<String, dynamic>))
    //       .toList();
    // }

    List<PMKit> pmKits = [];
    if (map['vKits'] != null) {
      pmKits = (map['vKits'] as List<dynamic>).map((e) => PMKit.fromMap(e as Map<String, dynamic>)).toList();
    }

    List<PPMCheckList> ppmCheckLists = [];
    if (map['vChecklists'] != null) {
      ppmCheckLists = (map['vChecklists'] as List<dynamic>).map((e) => PPMCheckList.fromMap(e as Map<String, dynamic>)).toList();
    }

    List<CalibrationTool> calibrationTools = [];
    if (map['vCalibrationTools'] != null) {
      calibrationTools = (map['vCalibrationTools'] as List<dynamic>).map((e) => CalibrationTool.fromMap(e as Map<String, dynamic>)).toList();
    }
    return Pentry(
      status: Lookup(id: map["taskStatusId"], name: map["taskStatusName"]),
      ppmVisitStatus: Lookup(id: map["visitStatusId"], name: map["visitStatusName"]),
      actualVisitDate: DateTime.tryParse(map["actualDate"] ?? ""),
      expectedVisitDate: DateTime.tryParse(map["expectedDate"] ?? ""),
      travelingHours: map["travelingHours"],
      timer: TimerModel(
        startAt: DateTime.tryParse(map["startDate"] ?? ""),
        endAt: DateTime.tryParse(map["endDate"] ?? ""),
        durationInSecond: (int.tryParse(map["workingHours"] ?? "") ?? 0) * 60 * 60,
        stopped: map["workingHours"] == null ? null : true,
      ),
      // contacts: contacts,
      ppmCheckLists: ppmCheckLists,
      calibrationTools: calibrationTools,
      pmKits: pmKits,
      signatureNurse: URLs.getFileUrl(map["nurseSignature"]),
      signatureEngineer: URLs.getFileUrl(map["engSignature"]),
    );
  }

  Pentry copyWith({
    Lookup ppmVisitStatus,
    Lookup status,
    TimerModel timer,
    DateTime actualVisitDate,
    DateTime expectedVisitDate,
    String travelingHours,
    String image,
    File imageFile,
    List<PPMCheckList> ppmCheckLists,
    List<CalibrationTool> calibrationTools,
    List<PMKit> pmKits,
    String signatureNurse,
    String signatureEngineer,
  }) {
    return Pentry(
        ppmVisitStatus: ppmVisitStatus ?? this.ppmVisitStatus,
        status: status ?? this.status,
        timer: timer ?? this.timer,
        actualVisitDate: actualVisitDate ?? this.actualVisitDate,
        expectedVisitDate: expectedVisitDate ?? this.expectedVisitDate,
        travelingHours: travelingHours ?? this.travelingHours,
        image: image ?? this.image,
        imageFile: imageFile ?? this.imageFile,
        ppmCheckLists: ppmCheckLists ?? this.ppmCheckLists?.map((e) => e.copyWith())?.toList(),
        calibrationTools: calibrationTools ?? this.calibrationTools?.map((e) => e.copyWith())?.toList(),
        pmKits: pmKits ?? this.pmKits.map((e) => e.copyWith()).toList(),
        signatureNurse: signatureNurse ?? this.signatureNurse,
        signatureEngineer: signatureEngineer ?? this.signatureEngineer);
  }
}
