import 'dart:convert';

import 'package:doctor_app_flutter/client/app_client.dart';
import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:doctor_app_flutter/models/doctor/doctor_profile_model.dart';
import 'package:doctor_app_flutter/models/patient/get_clinic_by_project_id_request.dart';
import 'package:doctor_app_flutter/models/patient/get_doctor_by_clinic_id_request.dart';
import 'package:doctor_app_flutter/models/patient/get_list_stp_referral_frequency_request.dart';
import 'package:doctor_app_flutter/models/patient/lab_orders/lab_orders_res_model.dart';
import 'package:doctor_app_flutter/models/patient/lab_result/lab_result.dart';
import 'package:doctor_app_flutter/models/patient/lab_result/lab_result_req_model.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/models/patient/prescription/prescription_report_for_in_patient.dart';
import 'package:doctor_app_flutter/models/patient/prescription/prescription_res_model.dart';
import 'package:doctor_app_flutter/models/patient/radiology/radiology_res_model.dart';
import 'package:doctor_app_flutter/models/patient/refer_to_doctor_request.dart';
import 'package:doctor_app_flutter/models/patient/prescription/prescription_report.dart';
import 'package:doctor_app_flutter/util/dr_app_shared_pref.dart';
import 'package:flutter/cupertino.dart';

import '../config/config.dart';
import '../models/patient/lab_orders/lab_orders_res_model.dart';
import '../models/patient/patiant_info_model.dart';
import '../models/patient/patient_model.dart';
import '../models/patient/prescription/prescription_res_model.dart';
import '../models/patient/radiology/radiology_res_model.dart';
import '../models/patient/vital_sign/vital_sign_res_model.dart';
import '../util/helpers.dart';

Helpers helpers = Helpers();
DrAppSharedPreferances sharedPref = new DrAppSharedPreferances();

class PatientsProvider with ChangeNotifier {
  bool isLoading = false;
  bool isError = false;
  String error = '';
  List<VitalSignResModel> patientVitalSignList = [];
  List<VitalSignResModel> patientVitalSignOrderdSubList = [];
  List<LabOrdersResModel> patientLabResultOrdersList = [];
  List<PrescriptionResModel> patientPrescriptionsList = [];
  List<RadiologyResModel> patientRadiologyList = [];
  List<PrescriptionReportForInPatient> prescriptionReportForInPatientList = [];
  List<PrescriptionReport> prescriptionReport = [];

  /*@author: ibrahe albitar
 *@Date:2/6/2020
 *@desc:   getPatientPrescriptions
 */

  List<LabResult> labResultList = [];

  var patientProgressNoteList = [];
  var insuranceApporvalsList = [];

  var doctorsList = [];
  var clinicsList = [];
  var referalFrequancyList = [];

  DoctorsByClinicIdRequest _doctorsByClinicIdRequest =
  DoctorsByClinicIdRequest();
  STPReferralFrequencyRequest _referralFrequencyRequest =
  STPReferralFrequencyRequest();
  ClinicByProjectIdRequest _clinicByProjectIdRequest =
  ClinicByProjectIdRequest();
  ReferToDoctorRequest _referToDoctorRequest;

  PatiantInformtion _selectedPatient;

  Future<dynamic> getPatientList(PatientModel patient, patientType) async {
    int val = int.parse(patientType);

    try {
      dynamic localRes;
      await BaseAppClient.post(GET_PATIENT + SERVICES_PATIANT[val],
          onSuccess: (dynamic response, int statusCode) {
            localRes = response;
          }, onFailure: (String error, int statusCode) {
            throw error;
          }, body: {
            "ProjectID": patient.ProjectID,
            "ClinicID": patient.ClinicID,
            "DoctorID": patient.DoctorID,
            "FirstName": patient.FirstName,
            "MiddleName": patient.MiddleName,
            "LastName": patient.LastName,
            "PatientMobileNumber": patient.PatientMobileNumber,
            "PatientIdentificationID": patient.PatientIdentificationID,
            "PatientID": patient.PatientID,
            "From": patient.From,
            "To": patient.To,
            "LanguageID": patient.LanguageID,
            "stamp": patient.stamp,
            "IPAdress": patient.IPAdress,
            "VersionID": patient.VersionID,
            "Channel": patient.Channel,
            "TokenID": patient.TokenID,
            "SessionID": patient.SessionID,
            "IsLoginForDoctorApp": patient.IsLoginForDoctorApp,
            "PatientOutSA": patient.PatientOutSA
          });

      return Future.value(localRes);
    } catch (error) {
      print(error);
      throw error;
    }
  }

  setBasicData() {
    isLoading = true;
    isError = false;
    error = '';
    notifyListeners();
  }

/*
 *@author: Elham Rababah
 *@Date:27/4/2020
 *@param: patient
 *@return:
 *@desc:   getPatientVitalSign
 */
  getPatientVitalSign(patient) async {
    setBasicData();

    try {
      await BaseAppClient.post(GET_PATIENT_VITAL_SIGN,
          onSuccess: (dynamic response, int statusCode) {
            patientVitalSignList = [];
            response['List_DoctorPatientVitalSign'].forEach((v) {
              patientVitalSignList.add(new VitalSignResModel.fromJson(v));
            });

            if (patientVitalSignList.length > 0) {
              List<VitalSignResModel> patientVitalSignOrderdSubListTemp = [];
              patientVitalSignOrderdSubListTemp = patientVitalSignList;
              patientVitalSignOrderdSubListTemp
                  .sort((VitalSignResModel a, VitalSignResModel b) {
                return b.vitalSignDate.microsecondsSinceEpoch -
                    a.vitalSignDate.microsecondsSinceEpoch;
              });
              patientVitalSignOrderdSubList.clear();
              int length = patientVitalSignOrderdSubListTemp.length >= 20
                  ? 20
                  : patientVitalSignOrderdSubListTemp.length;
              for (int x = 0; x < length; x++) {
                patientVitalSignOrderdSubList
                    .add(patientVitalSignOrderdSubListTemp[x]);
              }
            }
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: patient);
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

/*@author: Elham Rababah
 *@Date:27/4/2020
 *@param: patient
 *@return:
 *@desc:   getLabResult Orders
 */
  getLabResultOrders(patient) async {
    // isLoading = true;
    // notifyListeners();
    setBasicData();

    try {
      await BaseAppClient.post(GET_PATIENT_LAB_OREDERS,
          onSuccess: (dynamic response, int statusCode) {
            patientLabResultOrdersList = [];
            response['List_GetLabOreders'].forEach((v) {
              patientLabResultOrdersList.add(new LabOrdersResModel.fromJson(v));
            });
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: patient);
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

/*@author: Elham Rababah
 *@Date:3/5/2020
 *@param: patient
 *@return:
 *@desc:   geOutPatientPrescriptions
 */
  getOutPatientPrescriptions(patient) async {
    setBasicData();
    try {
      await BaseAppClient.post(GET_PRESCRIPTION,
          onSuccess: (dynamic response, int statusCode) {
            patientPrescriptionsList = [];
            response['PatientPrescriptionList'].forEach((v) {
              patientPrescriptionsList.add(new PrescriptionResModel.fromJson(v));
            });
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: patient);
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

  /*@author: Mohammad Aljammal
 *@Date:4/6/2020
 *@param: patient
 *@return:
 *@desc:   getInPatientPrescriptions
 */
  getInPatientPrescriptions(patient) async {
    setBasicData();
    try {
      prescriptionReportForInPatientList = [];
      notifyListeners();
      await BaseAppClient.post(GET_PRESCRIPTION_REPORT_FOR_IN_PATIENT,
          onSuccess: (dynamic response, int statusCode) {
            response['List_PrescriptionReportForInPatient'].forEach((v) {
              prescriptionReportForInPatientList
                  .add(PrescriptionReportForInPatient.fromJson(v));
            });
            isError = false;
            isLoading = false;
          }, onFailure: (String error, int statusCode) {
        isError = true;
        isLoading = false;
        this.error = error;
      }, body: patient);
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

  getPrescriptionReport(prescriptionReqModel) async {
    prescriptionReport = [];
    isLoading = true;
    isError = false;
    error = "";
    notifyListeners();
    await BaseAppClient.post(GET_PRESCRIPTION_REPORT,
        onSuccess: (dynamic response, int statusCode) {
          response['ListPRM'].forEach((v) {
            prescriptionReport.add(PrescriptionReport.fromJson(v));
          });
          isError = false;
          isLoading = false;
        }, onFailure: (String error, int statusCode) {
          isError = true;
          isLoading = false;
          this.error = error;
        }, body: prescriptionReqModel);
    notifyListeners();
  }

  /*@author: Elham Rababah
 *@Date:12/5/2020
 *@param: patient
 *@return:
 *@desc:   getPatientRadiology
 */
  handelCatchErrorCase(err) {
    isLoading = false;
    isError = true;
    error = helpers.generateContactAdminMsg(err);
    notifyListeners();
    throw err;
  }

/*@author: Elham Rababah
 *@Date:3/5/2020
 *@param: patient
 *@return:
 *@desc:   getPatientRadiology
 */
  getPatientRadiology(patient) async {
    // isLoading = true;
    // notifyListeners();
    setBasicData();
    try {
      await BaseAppClient.post(GET_RADIOLOGY,
          onSuccess: (dynamic response, int statusCode) {
            patientRadiologyList = [];
            response['List_GetRadOreders'].forEach((v) {
              patientRadiologyList.add(new RadiologyResModel.fromJson(v));
            });
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: patient);
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

  getLabResult(LabOrdersResModel labOrdersResModel) async {
    labResultList.clear();
    isLoading = true;
    notifyListeners();
    RequestLabResult requestLabResult = RequestLabResult();
    requestLabResult.sessionID = labOrdersResModel.setupID;
    requestLabResult.orderNo = labOrdersResModel.orderNo;
    requestLabResult.invoiceNo = labOrdersResModel.invoiceNo;
    requestLabResult.patientTypeID = labOrdersResModel.patientType;
    await BaseAppClient.post(GET_PATIENT_LAB_RESULTS,
        onSuccess: (dynamic response, int statusCode) {
          isError = false;
          isLoading = false;
          response['List_GetLabNormal'].forEach((v) {
            labResultList.add(new LabResult.fromJson(v));
          });
        }, onFailure: (String error, int statusCode) {
          isError = true;
          isLoading = false;
          this.error = error;
        }, body: requestLabResult.toJson());
    notifyListeners();
  }

  getPatientInsuranceApprovals(patient) async {
    setBasicData();
    try {
      await BaseAppClient.post(PATIENT_INSURANCE_APPROVALS_URL,
          onSuccess: (dynamic response, int statusCode) {
            insuranceApporvalsList = response['List_ApprovalMain_InPatient'];
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: patient);
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

/*@author: ibrahe albitar
 *@Date:2/6/2020
 *@desc:   getPatientProgressNote
 */
  getPatientProgressNote(patient) async {
    setBasicData();
    try {
      await BaseAppClient.post(PATIENT_PROGRESS_NOTE_URL,
          onSuccess: (dynamic response, int statusCode) {
            patientProgressNoteList = response['List_GetPregressNoteForInPatient'];
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: patient);
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

  /*@author: ibrahem albitar
 *@Date:3/6/2020
 *@desc:   getDoctorsList
 */
  getDoctorsList(String clinicId) async {
    setBasicData();
    try {
      _doctorsByClinicIdRequest.clinicID = clinicId;
      await BaseAppClient.post(PATIENT_GET_DOCTOR_BY_CLINIC_URL,
          onSuccess: (dynamic response, int statusCode) {
            doctorsList = response['List_Doctors_All'];
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: _doctorsByClinicIdRequest.toJson());
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

  List getDoctorNameList() {
    var doctorNamelist =
    doctorsList.map((value) => value['DoctorName'].toString()).toList();
    return doctorNamelist;
  }

  /*@author: ibrahem albitar
    *@Date:3/6/2020
    *@desc:   getClinicsList
    */
  getClinicsList() async {
    setBasicData();
    try {
      await BaseAppClient.post(PATIENT_GET_CLINIC_BY_PROJECT_URL,
          onSuccess: (dynamic response, int statusCode) {
            clinicsList = response['List_Clinic_All'];
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: _clinicByProjectIdRequest.toJson());
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

  List getClinicNameList() {
    var clinicsNameslist = clinicsList
        .map((value) => value['ClinicDescription'].toString())
        .toList();
    return clinicsNameslist;
  }

  /*@author: ibrahem albitar
    *@Date:3/6/2020
    *@desc:   getReferralFrequancyList
    */
  getReferralFrequancyList() async {
    setBasicData();
    try {
      await BaseAppClient.post(PATIENT_GET_LIST_REFERAL_URL,
          onSuccess: (dynamic response, int statusCode) {
            referalFrequancyList = response['list_STPReferralFrequency'];
            isLoading = false;
            isError = false;
            this.error = '';
          }, onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          }, body: _referralFrequencyRequest.toJson());
      notifyListeners();
    } catch (err) {
      handelCatchErrorCase(err);
    }
  }

  List getReferralNamesList() {
    var referralNamesList = referalFrequancyList
        .map((value) => value['Description'].toString())
        .toList();
    return referralNamesList;
  }

  /*@author: ibrahem albitar
    *@Date:3/6/2020
    *@desc:   referToDoctor
    */
 referToDoctor(context,
      {String selectedDoctorID,
        String selectedClinicID,
        int admissionNo,
        String extension,
        String priority,
        String frequency,
        String referringDoctorRemarks,
        int patientID,
        int patientTypeID,
        String roomID,
        int projectID}) async {
    setBasicData();
    try {
      String token = await sharedPref.getString(TOKEN);
      Map profile = await sharedPref.getObj(DOCTOR_PROFILE);
      DoctorProfileModel doctorProfile =
      new DoctorProfileModel.fromJson(profile);
      int doctorID = doctorProfile.doctorID;
      int clinicId = doctorProfile.clinicID;
      _referToDoctorRequest = ReferToDoctorRequest(
          projectID: projectID,
          admissionNo: admissionNo,
          roomID: roomID,
          referralClinic: selectedClinicID.toString(),
          referralDoctor: selectedDoctorID.toString(),
          createdBy: doctorID,
          editedBy: doctorID,
          patientID: patientID,
          patientTypeID: patientTypeID,
          referringClinic: clinicId,
          referringDoctor: doctorID,
          referringDoctorRemarks: referringDoctorRemarks,
          priority: priority,
          frequency: frequency,
          extension: extension,
          tokenID: token);
      await BaseAppClient.post(PATIENT_REFER_TO_DOCTOR_URL,
          onSuccess: (dynamic response, int statusCode) {
          //  print('Done : \n $res');
            Navigator.pop(context);
          },
          onFailure: (String error, int statusCode) {
            isLoading = false;
            isError = true;
            this.error = error;
          },
          body: _referToDoctorRequest.toJson());
      notifyListeners();

    } catch (err) {
      handelCatchErrorCase(err);
    }
  }
}
