import 'dart:convert';

import 'device/device.dart';
import 'lookup.dart';
import 'part.dart';
import 'timer_model.dart';

class ServiceReport {
  String? id;
  String? operatingHours;
  DateTime? visitDate;
  DateTime? endDate;
  Lookup? serviceType;
  Lookup? callLastSituation;
  Lookup? status;
  Lookup? type;
  Lookup? reason;
  String? faultDescription;
  String? workPreformed;
  String? travelingHours;
  String? invoiceNumber;
  String? invoiceCode;
  List<Part>? parts;
  String? image;
  Device? device;
  String? quantity;
  String? jobSheetNumber;
  TimerModel? timer;

  ServiceReport({
    this.id,
    this.visitDate,
    this.endDate,
    this.serviceType,
    this.status,
    this.type,
    this.faultDescription,
    this.travelingHours,
    this.parts,
    this.workPreformed,
    this.reason,
    this.operatingHours,
    this.callLastSituation,
    this.jobSheetNumber,
    this.image,
    this.device,
    this.invoiceCode,
    this.invoiceNumber,
    this.quantity = "1",
    this.timer,
  });

  Map<String, String> toMap() {
    Map<String, String> _map = {};
    if (id != null) _map["id"] = id ?? "";
    if (visitDate != null) _map["visit_date"] = ((visitDate?.millisecondsSinceEpoch ?? 0) ~/ 1000).toString();
    if (serviceType != null) _map["service_type"] = serviceType?.id.toString() ?? "";
    if (status != null) _map["status"] = status?.id.toString() ?? "";
    if (type != null) _map["service_report_type"] = type?.id.toString() ?? "";
    if (faultDescription != null && (faultDescription?.isNotEmpty ?? false)) _map["fault_description"] = faultDescription ?? "";
    //if(workHours != null && workHours.isNotEmpty) _map["working_hours"] = workHours;
    if (timer != null) {
      _map["start_time"] = ((timer?.startAt?.millisecondsSinceEpoch ?? 0) / 1000).toStringAsFixed(0);
      _map["end_time"] = ((timer?.endAt ?? DateTime.now()).millisecondsSinceEpoch / 1000).toStringAsFixed(0);
      _map["working_hours"] = ((timer?.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5);
    }
    if (travelingHours != null && (travelingHours?.isNotEmpty ?? false)) _map["traveling_hours"] = travelingHours ?? "";
    if (workPreformed != null && (workPreformed?.isNotEmpty ?? false)) _map["work_performed"] = workPreformed ?? "";
    if (jobSheetNumber != null && (jobSheetNumber?.isNotEmpty ?? false)) _map["job_sheet_no"] = jobSheetNumber ?? "";
    if (parts != null && (parts?.isNotEmpty ?? false)) {
      Map<String, int> _partsMap = {};
      parts?.forEach((part) {
        if ((part.id?.isNotEmpty ?? false)) {
          _partsMap[part?.id ?? ""] = part.quantity;
        }
      });
      _map["parts"] = json.encode(_partsMap);
    }
    if (device?.id != null && device?.id != null) _map["eq_id"] = device?.id ?? "";
    if (quantity != null && (quantity?.isNotEmpty ?? false)) _map["qty"] = quantity ?? "";
    if (endDate != null) _map["end_date"] = ((endDate?.millisecondsSinceEpoch ?? 0) ~/ 1000).toString();
    if (reason != null) _map["reasons"] = reason?.id.toString() ?? "";
    if (operatingHours != null && (operatingHours?.isNotEmpty ?? false)) _map["operation_hours"] = operatingHours ?? "";
    if (callLastSituation != null) _map["call_last_situtation"] = callLastSituation?.id.toString() ?? "";
    if (image != null) _map["image"] = image ?? "";
    if (invoiceCode != null) _map["invoice_no"] = invoiceCode ?? "";
    if (invoiceNumber != null) _map["invoice_code"] = invoiceNumber ?? "";
    return _map;
  }

  bool validate() {
    if (visitDate == null) return false;
    if (serviceType == null) return false;
    if (status == null) return false;
    if (type == null) return false;
    if (callLastSituation == null) return false;
    if (callLastSituation?.id == 12) {
      if (invoiceCode != null || invoiceCode?.isEmpty == true) return false;
      if (invoiceNumber != null || invoiceNumber?.isEmpty == true) return false;
    }
    if (parts == null) return false;
    //if(endDate == null) return false;
    //if(reason == null) return false;
    if ((device?.id == null || (device?.id?.isEmpty ?? false)) && type?.id != 1) return false;
    //if(quantity == null || quantity.isEmpty) return false;
    //if(image == null) return false;
    return true;
  }

  factory ServiceReport.fromJson(Map<String, dynamic> parsedJson, String id) {
    List<Part> _parts = [];
    if (parsedJson["parts"] != null) {
      if (parsedJson["parts"][0]["id"] != null) {
        List partsList = parsedJson["parts"];
        _parts = partsList.map((e) => Part.fromJson(e)).toList();
      }
    }
    return ServiceReport(
        id: id,
        serviceType: Lookup.fromJson(parsedJson["service_type"]),
        callLastSituation: Lookup.fromJson(parsedJson["call_last_situtation"]),
        reason: Lookup.fromJson(parsedJson["reasons"]),
        status: Lookup.fromJson(parsedJson["service_report_status"]),
        type: Lookup.fromJson(parsedJson["service_report_type"]),
        faultDescription: parsedJson["fault_description"],
        endDate: getDate(parsedJson["end_date"]),
        invoiceCode: parsedJson["invoice_code"],
        invoiceNumber: parsedJson["invoice_no"],
        jobSheetNumber: parsedJson["job_sheet_no"],
        operatingHours: parsedJson["operation_hours"],
        parts: _parts,
        quantity: parsedJson["nid"],
        travelingHours: parsedJson["traveling_hours"],
        visitDate: getDate(parsedJson["visit_date"]),
        //workHours: parsedJson["working_hours"],
        timer: TimerModel(durationInSecond: (int.tryParse(parsedJson["working_hours"] ?? "") ?? 0) * 60 * 60),
        workPreformed: parsedJson["work_performed"],
        device: parsedJson["eq_nid"] == null ? null : Device(id: parsedJson["eq_nid"], serialNumber: parsedJson["eq_serial"]));
  }

  static getDate(String date) {
    return date == null || date.isEmpty ? null : DateTime.fromMillisecondsSinceEpoch((int.tryParse(date) ?? 0) * 1000);
  }
}
