import 'package:doctor_app_flutter/client/base_app_client.dart';
import 'package:doctor_app_flutter/config/config.dart';
import 'package:doctor_app_flutter/config/shared_pref_kay.dart';
import 'package:doctor_app_flutter/core/model/note/CreateNoteModel.dart';
import 'package:doctor_app_flutter/core/model/note/note_model.dart';
import 'package:doctor_app_flutter/core/model/note/update_note_model.dart';
import 'package:doctor_app_flutter/core/service/base/base_service.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/prescription/prescription_report.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/vital_sign/vital_sign_res_model.dart';

class PatientService extends BaseService {
  List<VitalSignResModel> _patientVitalSignList = [];
  List<VitalSignResModel> patientVitalSignOrderdSubList = [];

  List<VitalSignResModel> get patientVitalSignList => _patientVitalSignList;

  List<LabOrdersResModel> _patientLabResultOrdersList = [];

  List<LabOrdersResModel> get patientLabResultOrdersList =>
      _patientLabResultOrdersList;

  List<PrescriptionResModel> get patientPrescriptionsList =>
      _patientPrescriptionsList;
  List<PrescriptionResModel> _patientPrescriptionsList = [];

  List<PrescriptionReportForInPatient> get prescriptionReportForInPatientList =>
      _prescriptionReportForInPatientList;
  List<PrescriptionReportForInPatient> _prescriptionReportForInPatientList = [];

  List<RadiologyResModel> _patientRadiologyList = [];

  List<RadiologyResModel> get patientRadiologyList => _patientRadiologyList;

  List<PrescriptionReport> _prescriptionReport = [];

  List<PrescriptionReport> get prescriptionReport => _prescriptionReport;

  List<LabResult> _labResultList = [];

  List<LabResult> get labResultList => _labResultList;

  // TODO: replace var with model
  List<NoteModel> _patientProgressNoteList = [];

  List<NoteModel> get patientProgressNoteList => _patientProgressNoteList;

  // TODO: replace var with model
  var _insuranceApporvalsList = [];

  get insuranceApporvalsList => _insuranceApporvalsList;

  // TODO: replace var with model
  var _doctorsList = [];

  var _arrivedList = [];

  get arrivedList => _arrivedList;

  get doctorsList => _doctorsList;

  // TODO: replace var with model
  var _clinicsList = [];

  get clinicsList => _clinicsList;

  // TODO: replace var with model
  var _referalFrequancyList = [];

  get referalFrequancyList => _referalFrequancyList;

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

  Future<dynamic> getPatientList(patient, patientType, {isView}) async {
    hasError = false;
    int val = int.parse(patientType);
    var url;
    if (isView == false && patientType == '1') {
      url = PRM_SEARCH_PATIENT;
    } else {
      url = GET_PATIENT + SERVICES_PATIANT[val];
    }
    dynamic localRes;
    await baseAppClient.post(
      url,
      onSuccess: (dynamic response, int statusCode) {
        localRes = response;
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: val == 7
          ? patient
          : {
              "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,
              "SearchType": patient.Searchtype,
              "MobileNo": patient.MobileNo,
              "IdentificationNo": patient.IdentificationNo
            },
    );

    return Future.value(localRes);
  }

  Future getLabResultOrders(patient) async {
    hasError = false;
    await baseAppClient.post(
      GET_PATIENT_LAB_OREDERS,
      onSuccess: (dynamic response, int statusCode) {
        _patientLabResultOrdersList = [];
        response['List_GetLabOreders'].forEach((v) {
          _patientLabResultOrdersList.add(new LabOrdersResModel.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: patient,
    );
  }

  Future getOutPatientPrescriptions(patient) async {
    hasError = false;
    await baseAppClient.post(
      GET_PRESCRIPTION,
      onSuccess: (dynamic response, int statusCode) {
        _patientPrescriptionsList = [];
        response['PatientPrescriptionList'].forEach((v) {
          _patientPrescriptionsList.add(new PrescriptionResModel.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: patient,
    );
  }

  Future getInPatientPrescriptions(patient) async {
    hasError = false;
    await baseAppClient.post(
      GET_PRESCRIPTION_REPORT_FOR_IN_PATIENT,
      onSuccess: (dynamic response, int statusCode) {
        _prescriptionReportForInPatientList = [];
        response['List_PrescriptionReportForInPatient'].forEach((v) {
          prescriptionReportForInPatientList
              .add(PrescriptionReportForInPatient.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: patient,
    );
  }

  Future getPrescriptionReport(prescriptionReqModel) async {
    hasError = false;
    await baseAppClient.post(
      GET_PRESCRIPTION_REPORT,
      onSuccess: (dynamic response, int statusCode) {
        _prescriptionReport = [];
        response['ListPRM'].forEach((v) {
          _prescriptionReport.add(PrescriptionReport.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: prescriptionReqModel,
    );
  }

  Future getPatientRadiology(patient) async {
    hasError = false;
    await baseAppClient.post(
      GET_RADIOLOGY,
      onSuccess: (dynamic response, int statusCode) {
        _patientRadiologyList = [];
        response['List_GetRadOreders'].forEach((v) {
          _patientRadiologyList.add(new RadiologyResModel.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: patient,
    );
  }

  Future getLabResult(LabOrdersResModel labOrdersResModel) async {
    hasError = false;

    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) {
        _labResultList = [];
        response['List_GetLabNormal'].forEach((v) {
          _labResultList.add(new LabResult.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: requestLabResult.toJson(),
    );
  }

  Future getPatientInsuranceApprovals(patient) async {
    hasError = false;

    await baseAppClient.post(
      PATIENT_INSURANCE_APPROVALS_URL,
      onSuccess: (dynamic response, int statusCode) {
        _insuranceApporvalsList = [];
        _insuranceApporvalsList = response['List_ApprovalMain_InPatient'];
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: patient,
    );
  }

  Future getPatientProgressNote(patient) async {
    hasError = false;

    await baseAppClient.post(
      PATIENT_PROGRESS_NOTE_URL,
      onSuccess: (dynamic response, int statusCode) {
        _patientProgressNoteList = [];
        // _patientProgressNoteList =
        response['List_GetPregressNoteForInPatient'].forEach((v) {
          _patientProgressNoteList.add(new NoteModel.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: patient,
    );
  }

  Future updatePatientProgressNote(UpdateNoteReqModel req) async {
    hasError = false;

    await baseAppClient.post(
      UPDATE_PROGRESS_NOTE_FOR_INPATIENT,
      onSuccess: (dynamic response, int statusCode) {
        print("ok");
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: req.toJson(),
    );
  }

  Future createPatientProgressNote(CreateNoteModel req) async {
    hasError = false;

    await baseAppClient.post(
      CREATE_PROGRESS_NOTE_FOR_INPATIENT,
      onSuccess: (dynamic response, int statusCode) {
        print("ok");
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: req.toJson(),
    );
  }

  Future getClinicsList() async {
    hasError = false;

    await baseAppClient.post(
      PATIENT_GET_CLINIC_BY_PROJECT_URL,
      onSuccess: (dynamic response, int statusCode) {
        _clinicsList = [];
        _clinicsList = response['List_Clinic_All'];
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: _clinicByProjectIdRequest.toJson(),
    );
  }

  Future getReferralFrequancyList() async {
    hasError = false;

    await baseAppClient.post(
      PATIENT_GET_LIST_REFERAL_URL,
      onSuccess: (dynamic response, int statusCode) {
        _referalFrequancyList = [];
        _referalFrequancyList = response['list_STPReferralFrequency'];
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: _referralFrequencyRequest.toJson(),
    );
  }

  Future getDoctorsList(int clinicId) async {
    hasError = false;
    _doctorsByClinicIdRequest.clinicID = clinicId;
    await baseAppClient.post(
      PATIENT_GET_DOCTOR_BY_CLINIC_URL,
      onSuccess: (dynamic response, int statusCode) {
        _doctorsList = [];
        _doctorsList = response['List_Doctors_All'];
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: _doctorsByClinicIdRequest.toJson(),
    );
  }

  // TODO send the total model insted of each parameter
  Future referToDoctor(
      {String selectedDoctorID,
      String selectedClinicID,
      int admissionNo,
      String extension,
      String priority,
      String frequency,
      String referringDoctorRemarks,
      int patientID,
      int patientTypeID,
      String roomID,
      int projectID}) async {
    hasError = false;
    // TODO Change it to use it when we implement authentication user
    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,
    );
    await baseAppClient.post(
      PATIENT_PROGRESS_NOTE_URL,
      onSuccess: (dynamic response, int statusCode) {},
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: _referToDoctorRequest.toJson(),
    );
  }

  Future getArrivedList() async {
    hasError = false;

    await baseAppClient.post(
      ARRIVED_PATIENT_URL,
      onSuccess: (dynamic response, int statusCode) {
        _arrivedList = [];
        _arrivedList = response['"patientArrivalList": '];
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: _doctorsByClinicIdRequest.toJson(),
    );
  }
}
