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/model/procedure/categories_procedure.dart';
import 'package:doctor_app_flutter/core/model/procedure/get_ordered_procedure_model.dart';
import 'package:doctor_app_flutter/core/model/procedure/post_procedure_req_model.dart';
import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_model.dart';
import 'package:doctor_app_flutter/core/model/procedure/procedure_valadate_request_model.dart';
import 'package:doctor_app_flutter/core/model/procedure/update_procedure_request_model.dart';
import 'package:doctor_app_flutter/core/model/radiology/final_radiology.dart';
import 'package:doctor_app_flutter/core/service/labs_service.dart';
import 'package:doctor_app_flutter/core/service/procedure_service.dart';
import 'package:doctor_app_flutter/core/service/radiology_service.dart';
import 'package:doctor_app_flutter/core/viewModel/base_view_model.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 'package:flutter/cupertino.dart';

class ProcedureViewModel extends BaseViewModel {
  FilterType filterType = FilterType.Clinic;
  bool hasError = false;
  ProcedureService _procedureService = locator<ProcedureService>();
  List<GetOrderedProcedureModel> get procedureList =>
      _procedureService.procedureList;
  List<ProcedureValadteModel> get valadteProcedureList =>
      _procedureService.valadteProcedureList;
  List<CategoriseProcedureModel> get categoriesList =>
      _procedureService.categoriesList;
  List<dynamic> get categoryList => _procedureService.categoryList;
  RadiologyService _radiologyService = locator<RadiologyService>();
  LabsService _labsService = locator<LabsService>();
  List<FinalRadiologyList> _finalRadiologyListClinic = List();
  List<FinalRadiologyList> _finalRadiologyListHospital = List();
  List<FinalRadiologyList> get finalRadiologyList =>
      filterType == FilterType.Clinic
          ? _finalRadiologyListClinic
          : _finalRadiologyListHospital;

  List<FinalRadiology> get radiologyList =>
      _radiologyService.finalRadiologyList;

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

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

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

  Future getProcedure({int mrn,String patientType}) async {
    hasError = false;
    //_insuranceCardService.clearInsuranceCard();
    setState(ViewState.Busy);
    await _procedureService.getProcedure(mrn: mrn);
    if (_procedureService.hasError) {
      error = _procedureService.error;
      if(patientType=="7")
        setState(ViewState.ErrorLocal);
      else
        setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getProcedureCategory({String categoryName, String categoryID}) async {
    hasError = false;
    //_insuranceCardService.clearInsuranceCard();
    setState(ViewState.Busy);
    await _procedureService.getProcedureCategory(
        categoryName: categoryName, categoryID: categoryID);
    if (_procedureService.hasError) {
      error = _procedureService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future getCategory() async {
    hasError = false;
    //_insuranceCardService.clearInsuranceCard();
    setState(ViewState.Busy);
    await _procedureService.getCategory();
    if (_procedureService.hasError) {
      error = _procedureService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future postProcedure(
      PostProcedureReqModel postProcedureReqModel, int mrn) async {
    hasError = false;
    //_insuranceCardService.clearInsuranceCard();
    setState(ViewState.Busy);
    await _procedureService.postProcedure(postProcedureReqModel);
    if (_procedureService.hasError) {
      error = _procedureService.error;
      setState(ViewState.ErrorLocal);
    } else {
      await getProcedure(mrn: mrn);
      setState(ViewState.Idle);
    }
  }

  Future valadteProcedure(
      ProcedureValadteRequestModel procedureValadteRequestModel) async {
    hasError = false;
    //_insuranceCardService.clearInsuranceCard();
    setState(ViewState.Busy);
    await _procedureService.valadteProcedure(procedureValadteRequestModel);
    if (_procedureService.hasError) {
      error = _procedureService.error;
      setState(ViewState.ErrorLocal);
    } else {
      setState(ViewState.Idle);
    }
  }

  Future updateProcedure(
      {UpdateProcedureRequestModel updateProcedureRequestModel,
      int mrn}) async {
    hasError = false;
    //_insuranceCardService.clearInsuranceCard();
    setState(ViewState.Busy);
    await _procedureService.updateProcedure(updateProcedureRequestModel);
    if (_procedureService.hasError) {
      error = _procedureService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
    //await getProcedure(mrn: mrn);

  }

  void getPatientRadOrders(PatiantInformtion patient,{String patientType, bool isInPatient = false}) async {
    setState(ViewState.Busy);
    await _radiologyService.getPatientRadOrders(patient, isInPatient:isInPatient);
    if (_radiologyService.hasError) {
      error = _radiologyService.error;
      if(patientType=="7")
        setState(ViewState.ErrorLocal);
      else
        setState(ViewState.Error);
    } else {
      _radiologyService.finalRadiologyList.forEach((element) {
        List<FinalRadiologyList> finalRadiologyListClinic =
            _finalRadiologyListClinic
                .where((elementClinic) =>
                    elementClinic.filterName == element.clinicDescription)
                .toList();

        if (finalRadiologyListClinic.length != 0) {
          _finalRadiologyListClinic[
                  finalRadiologyListClinic.indexOf(finalRadiologyListClinic[0])]
              .finalRadiologyList
              .add(element);
        } else {
          _finalRadiologyListClinic.add(FinalRadiologyList(
              filterName: element.clinicDescription, finalRadiology: element));
        }

        //   FinalRadiologyList list sort via project
        List<FinalRadiologyList> finalRadiologyListHospital =
            _finalRadiologyListHospital
                .where(
                  (elementClinic) =>
                      elementClinic.filterName == element.projectName,
                )
                .toList();

        if (finalRadiologyListHospital.length != 0) {
          _finalRadiologyListHospital[finalRadiologyListHospital
                  .indexOf(finalRadiologyListHospital[0])]
              .finalRadiologyList
              .add(element);
        } else {
          _finalRadiologyListHospital.add(FinalRadiologyList(
              filterName: element.projectName, finalRadiology: element));
        }
      });

      setState(ViewState.Idle);
    }
  }

  String get radImageURL => _radiologyService.url;

  getRadImageURL(
      {int invoiceNo,
      int lineItem,
      int projectId,
      @required PatiantInformtion patient}) async {
    setState(ViewState.Busy);
    await _radiologyService.getRadImageURL(
        invoiceNo: invoiceNo,
        lineItem: lineItem,
        projectId: projectId,
        patient: patient);
    if (_radiologyService.hasError) {
      error = _radiologyService.error;
      setState(ViewState.Error);
    } else
      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;
  }

  void getLabs(PatiantInformtion patient, {bool isInpatient = false}) async {
    setState(ViewState.Busy);
    await _labsService.getPatientLabOrdersList(patient, isInpatient);
    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);
    }
  }

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

  getPatientLabResult(
      {PatientLabOrders patientLabOrder, PatiantInformtion patient}) async {
    setState(ViewState.Busy);
    await _labsService.getPatientLabResult(
        patientLabOrder: patientLabOrder, patient: patient);
    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);
  }
}
