import 'package:doctor_app_flutter/core/enum/filter_type.dart';
import 'package:doctor_app_flutter/core/enum/viewstate.dart';
import 'package:doctor_app_flutter/core/model/labs/LabOrderResult.dart';
import 'package:doctor_app_flutter/core/model/labs/lab_result.dart';
import 'package:doctor_app_flutter/core/model/labs/patient_lab_orders.dart';
import 'package:doctor_app_flutter/core/model/labs/patient_lab_special_result.dart';
import 'package:doctor_app_flutter/core/service/labs_service.dart';
import 'package:doctor_app_flutter/locator.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/util/dr_app_toast_msg.dart';

import 'base_view_model.dart';

class LabsViewModel extends BaseViewModel {
  FilterType filterType = FilterType.Clinic;
  LabsService _labsService = locator<LabsService>();

  List<LabOrderResult> get labOrdersResultsList =>
      _labsService.labOrdersResultsList;

  List<PatientLabOrdersList> _patientLabOrdersListClinic = List();
  List<PatientLabOrdersList> _patientLabOrdersListHospital = List();

  List<PatientLabOrdersList> get patientLabOrdersList =>
      filterType == FilterType.Clinic
          ? _patientLabOrdersListClinic
          : _patientLabOrdersListHospital;

  void getLabs(PatiantInformtion patient) async {
    setState(ViewState.Busy);
    await _labsService.getPatientLabOrdersList(patient, true);
    if (_labsService.hasError) {
      error = _labsService.error;
      setState(ViewState.Error);
    } else {
      _labsService.patientLabOrdersList.forEach((element) {
        List<PatientLabOrdersList> patientLabOrdersClinic =
            _patientLabOrdersListClinic
                .where((elementClinic) =>
                    elementClinic.filterName == element.clinicDescription)
                .toList();

        if (patientLabOrdersClinic.length != 0) {
          _patientLabOrdersListClinic[_patientLabOrdersListClinic
                  .indexOf(patientLabOrdersClinic[0])]
              .patientLabOrdersList
              .add(element);
        } else {
          _patientLabOrdersListClinic.add(PatientLabOrdersList(
              filterName: element.clinicDescription,
              patientDoctorAppointment: element));
        }

        //   doctor list sort via project
        List<PatientLabOrdersList> patientLabOrdersHospital =
            _patientLabOrdersListHospital
                .where(
                  (elementClinic) =>
                      elementClinic.filterName == element.projectName,
                )
                .toList();

        if (patientLabOrdersHospital.length != 0) {
          _patientLabOrdersListHospital[_patientLabOrdersListHospital
                  .indexOf(patientLabOrdersHospital[0])]
              .patientLabOrdersList
              .add(element);
        } else {
          _patientLabOrdersListHospital.add(PatientLabOrdersList(
              filterName: element.projectName,
              patientDoctorAppointment: element));
        }
      });

      setState(ViewState.Idle);
    }
  }

  setFilterType(FilterType filterType) {
    this.filterType = filterType;
    notifyListeners();
  }

  List<PatientLabSpecialResult> get patientLabSpecialResult =>
      _labsService.patientLabSpecialResult;

  List<LabResult> get labResultList => _labsService.labResultList;

  List<LabResultList> labResultLists = List();

  List<LabResultList> get labResultListsCoustom {
    return labResultLists;
  }

  getLaboratoryResult(
      {String projectID,
      int clinicID,
      String invoiceNo,
      String orderNo,
      PatiantInformtion patient,
      bool isInpatient}) async {
    setState(ViewState.Busy);
    await _labsService.getLaboratoryResult(
        invoiceNo: invoiceNo,
        orderNo: orderNo,
        projectID: projectID,
        clinicID: clinicID,
        patient: patient,
        isInpatient: isInpatient);
    if (_labsService.hasError) {
      error = _labsService.error;
      setState(ViewState.Error);
    } else {
      setState(ViewState.Idle);
    }
  }

  getPatientLabResult(
      {PatientLabOrders patientLabOrder, PatiantInformtion patient, bool isInpatient}) async {
    setState(ViewState.Busy);
    await _labsService.getPatientLabResult(
        patientLabOrder: patientLabOrder, patient: patient, isInpatient: isInpatient);
    if (_labsService.hasError) {
      error = _labsService.error;
      setState(ViewState.Error);
    } else {
      _labsService.labResultList.forEach((element) {
        List<LabResultList> patientLabOrdersClinic = labResultLists
            .where(
                (elementClinic) => elementClinic.filterName == element.testCode)
            .toList();

        if (patientLabOrdersClinic.length != 0) {
          var value =
              labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])]
                  .patientLabResultList
                  .where((e) =>
                      e.sampleCollectedOn == element.sampleCollectedOn &&
                      e.resultValue == element.resultValue)
                  .toList();
          if (value.isEmpty)
            labResultLists[labResultLists.indexOf(patientLabOrdersClinic[0])]
                .patientLabResultList
                .add(element);
        } else {
          labResultLists
              .add(LabResultList(filterName: element.testCode, lab: element));
        }
      });
      setState(ViewState.Idle);
    }
  }

  getPatientLabOrdersResults(
      {PatientLabOrders patientLabOrder,
      String procedure,
      PatiantInformtion patient}) async {
    setState(ViewState.Busy);
    await _labsService.getPatientLabOrdersResults(
        patientLabOrder: patientLabOrder,
        procedure: procedure,
        patient: patient);
    if (_labsService.hasError) {
      error = _labsService.error;
      setState(ViewState.Error);
    } else {
      bool isShouldClear = false;
      if (_labsService.labOrdersResultsList.length == 1) {
        labOrdersResultsList.forEach((element) {
          if (element.resultValue.contains('/') ||
              element.resultValue.contains('*') ||
              element.resultValue.isEmpty) isShouldClear = true;
        });
      }
      if (isShouldClear) _labsService.labOrdersResultsList.clear();
      setState(ViewState.Idle);
    }
  }

  sendLabReportEmail({PatientLabOrders patientLabOrder, String mes}) async {
    await _labsService.sendLabReportEmail(patientLabOrder: patientLabOrder);
    if (_labsService.hasError) {
      error = _labsService.error;
    } else
      DrAppToastMsg.showSuccesToast(mes);
  }
}
