import 'package:diplomaticquarterapp/core/enum/filter_type.dart';
import 'package:diplomaticquarterapp/core/enum/viewstate.dart';
import 'package:diplomaticquarterapp/core/model/labs/LabOrderResult.dart';
import 'package:diplomaticquarterapp/core/model/labs/lab_result.dart';
import 'package:diplomaticquarterapp/core/model/labs/patient_lab_orders.dart';
import 'package:diplomaticquarterapp/core/model/labs/patient_lab_special_result.dart';
import 'package:diplomaticquarterapp/core/service/medical/labs_service.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart';

import '../../../locator.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<TimeSeriesSales2> timeSeries = [];

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

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

  void getLabs() async {
    if (authenticatedUserObject.isLogin) {
      setState(ViewState.Busy);
      await _labsService.getPatientLabOrdersList();
      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 ?? element.projectName, 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 ?? element.clinicDescription, 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();

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

  getPatientLabResult({PatientLabOrders patientLabOrder}) async {
    setState(ViewState.Busy);
    await _labsService.getPatientLabResult(patientLabOrder: patientLabOrder);
    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}) async {
    setState(ViewState.Busy);
    await _labsService.getPatientLabOrdersResults(patientLabOrder: patientLabOrder, procedure: procedure);
    if (_labsService.hasError) {
      error = _labsService.error;
      setState(ViewState.Error);
    } else {
      /// commented out based on PAP-304
      // 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();

      _labsService.labOrdersResultsList.forEach((element) {
        try {
          timeSeries.add(new TimeSeriesSales2(DateUtil.convertStringToDate(element.verifiedOnDateTime), double.parse(element.resultValue)));
        } catch (e) {}
      });
      setState(ViewState.Idle);
    }
  }

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