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/SOAP/assessment/patient_previous_diagnosis.dart';
import 'package:doctor_app_flutter/core/model/diabetic_chart/GetDiabeticChartValuesRequestModel.dart';
import 'package:doctor_app_flutter/core/model/diabetic_chart/GetDiabeticChartValuesResponseModel.dart';
import 'package:doctor_app_flutter/core/model/diagnosis/GetDiagnosisForInPatientRequestModel.dart';
import 'package:doctor_app_flutter/core/model/diagnosis/GetDiagnosisForInPatientResponseModel.dart';
import 'package:doctor_app_flutter/core/model/doctor/doctor_profile_model.dart';
import 'package:doctor_app_flutter/core/model/note/CreateNoteModel.dart';
import 'package:doctor_app_flutter/core/model/note/GetNursingProgressNoteRequestModel.dart';
import 'package:doctor_app_flutter/core/model/note/GetNursingProgressNoteResposeModel.dart';
import 'package:doctor_app_flutter/core/model/note/note_model.dart';
import 'package:doctor_app_flutter/core/model/note/stp_master_list_req_model.dart';
import 'package:doctor_app_flutter/core/model/note/update_note_model.dart';
import 'package:doctor_app_flutter/core/model/patient/get_clinic_by_project_id_request.dart';
import 'package:doctor_app_flutter/core/model/patient/get_doctor_by_clinic_id_request.dart';
import 'package:doctor_app_flutter/core/model/patient/get_list_stp_referral_frequency_request.dart';
import 'package:doctor_app_flutter/core/model/patient/lab_orders/lab_orders_res_model.dart';
import 'package:doctor_app_flutter/core/model/patient/lab_result/lab_result.dart';
import 'package:doctor_app_flutter/core/model/patient/lab_result/lab_result_req_model.dart';
import 'package:doctor_app_flutter/core/model/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/core/model/patient/prescription/prescription_report.dart';
import 'package:doctor_app_flutter/core/model/patient/prescription/prescription_report_for_in_patient.dart';
import 'package:doctor_app_flutter/core/model/patient/prescription/prescription_res_model.dart';
import 'package:doctor_app_flutter/core/model/patient/radiology/radiology_res_model.dart';
import 'package:doctor_app_flutter/core/model/patient/refer_to_doctor_request.dart';
import 'package:doctor_app_flutter/core/model/patient/vital_sign/vital_sign_res_model.dart';
import 'package:doctor_app_flutter/core/model/patient_muse/PatientSearchRequestModel.dart';
import 'package:doctor_app_flutter/core/service/base/base_service.dart';
import 'package:flutter/material.dart';

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

  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;

  List<NoteModel> _patientProgressNoteList = [];

  List<NoteModel> get patientProgressNoteList => _patientProgressNoteList;

  List<GetNursingProgressNoteResposeModel> _patientNursingProgressNoteList = [];

  List<GetNursingProgressNoteResposeModel> get patientNursingProgressNoteList => _patientNursingProgressNoteList;

  List<GetDiagnosisForInPatientResponseModel> _diagnosisForInPatientList = [];

  List<GetDiagnosisForInPatientResponseModel> get diagnosisForInPatientList => _diagnosisForInPatientList;
  List<GetDiabeticChartValuesResponseModel> _diabeticChartValuesList = [];

  List<GetDiabeticChartValuesResponseModel> get diabeticChartValuesList => _diabeticChartValuesList;

  List<dynamic> stpMasterList = [];

  // 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 getInPatient(PatientSearchRequestModel requestModel, bool isMyInpatient) async {
    hasError = false;

    await getDoctorProfile();
    requestModel.loginDoctorID = doctorProfile!.doctorID;
    if (isMyInpatient) {
      requestModel.doctorID = doctorProfile!.doctorID;
    } else {
      requestModel.doctorID = 0;
    }

    await baseAppClient.post(
      GET_PATIENT_IN_PATIENT_LIST,
      onSuccess: (dynamic response, int statusCode) {
        inPatientList.clear();
        myInPatientList.clear();

        response['List_MyInPatient'].forEach((v) {
          PatiantInformtion patient = PatiantInformtion.fromJson(v);
          inPatientList.add(patient);
          if (patient.doctorId == doctorProfile!.doctorID) {
            myInPatientList.add(patient);
          }
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: requestModel.toJson(),
    );
  }

  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(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_IN_PATIENT_ORDERS,
      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 getVidaPlusProgressNote(patient) async {
    hasError = false;

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

  Future updatePatientProgressNote(UpdateNoteReqModel req) async {
    hasError = false;
    var request = req.toJson();


    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<String, dynamic>? 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(),
    );
  }

  Future getNursingProgressNote(GetNursingProgressNoteRequestModel getNursingProgressNoteRequestModel) async {
    hasError = false;

    await baseAppClient.post(
      NURSING_PROGRESS_NOTE,
      onSuccess: (dynamic response, int statusCode) {
        _patientNursingProgressNoteList = [];
        response['List_NursingProgressNote'].forEach((v) {
          _patientNursingProgressNoteList.add(GetNursingProgressNoteResposeModel.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: getNursingProgressNoteRequestModel.toJson(),
    );
  }

  Future getDiagnosisForInPatient(GetDiagnosisForInPatientRequestModel getDiagnosisForInPatientRequestModel) async {
    hasError = false;

    await baseAppClient.post(
      GET_DIAGNOSIS_FOR_IN_PATIENT,
      onSuccess: (dynamic response, int statusCode) {
        _diagnosisForInPatientList = [];
        response['List_DiagnosisForInPatient'].forEach((v) {
          _diagnosisForInPatientList.add(GetDiagnosisForInPatientResponseModel.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: getDiagnosisForInPatientRequestModel.toJson(),
    );
  }


  getDiagnosis(PatiantInformtion patient) async {
    Map<String, dynamic> request = {
      // "hospitalGroupId": 105,
      // "hospitalId": 313,
      // "patientId": 70023498,
      // "patientPomrId": 9907,
      // "startRow": 0,
      // "endRow": 10,
      // "isSelected": true,
      // "ProjectID": 313
      "hospitalGroupId": await sharedPref.getString(DOCTOR_SETUP_ID),
      "hospitalId": patient.projectId,
      "patientId": patient.patientId,
      "patientPomrId": patient.pomrId,
      "startRow": 0,
      "endRow": 1000000,
      "ProjectID": patient.projectId
    };
    List<dynamic> dynamicResponse = [];
    hasError = false;
    await baseAppClient.post(GET_LIST_OF_DIAGNOSIS,
        onSuccess: (dynamic response, int statusCode) {
          _diagnosisForInPatientList.clear();
          dynamicResponse = response['ListDiagnosisDetailsSearch']['resultData'];

          response['ListDiagnosisDetailsSearch']['resultData'].forEach((v) =>
              _diagnosisForInPatientList.add(GetDiagnosisForInPatientResponseModel.fromJsonForVidaPlus(v)));
        }, onFailure: (String error, int statusCode) {
          _diagnosisForInPatientList.clear();
          hasError = true;
          super.error = error;
        }, body: request);
    return dynamicResponse;
  }

  Future getDiabeticChartValues(GetDiabeticChartValuesRequestModel getDiabeticChartValuesRequestModel) async {
    hasError = false;

    await baseAppClient.post(
      GET_DIABETIC_CHART_VALUES,
      onSuccess: (dynamic response, int statusCode) {
        _diabeticChartValuesList = [];
        response['List_DiabeticChartValues'].forEach((v) {
          _diabeticChartValuesList.add(GetDiabeticChartValuesResponseModel.fromJson(v));
        });
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: getDiabeticChartValuesRequestModel.toJson(),
    );
  }

  Future getStpMasterList(StpMasterListRequestModel stpMasterListRequestModel) async {
    hasError = false;

    await baseAppClient.post(
      GET_STP_MASTER_LIST,
      onSuccess: (dynamic response, int statusCode) {
        stpMasterList = [];
        stpMasterList = response['List_STPMasterList'];
      },
      onFailure: (String error, int statusCode) {
        hasError = true;
        super.error = error;
      },
      body: stpMasterListRequestModel.toJson(),
    );
  }

  Future<bool> getPatientCondition() async {
    Map<String, dynamic> request = {};
    var success = false;

    await baseAppClient.post(GET_PATIENT_CLINIC,
        onSuccess: (dynamic response, int statusCode) {
          stpMasterList = [];

          response['ListPatientConditionProgress']['resultData'].forEach((v) =>
              v['PATIENT_CONDITION'].forEach((item) {
                stpMasterList.add({
                  "ParameterCode": int.tryParse(item['code']),
                  "Description": item['name'],
                });
              }));
          success = false;
        }, onFailure: (String error, int statusCode) {
          success = false;
          hasError = true;
          super.error = error;
        }, body: request);

    return success;
  }

  Future<bool> createProgressNote(
      CreateNoteModel data,
      PatiantInformtion patient,
      ) async {
    var profile = await getDoctorProfile();

    Map<String, dynamic> request = {
      "planNote": data.notes,
      "PatientMRN": patient.patientMRN,
      "EpisodeID": patient.pomrId,
      "CreatedByName": patient.doctorName,
      "CreatedBy": patient.doctorId,
      "Speciality": patient.clinicId,
      "ProgressNotesTypes": "DOCTOR_NOTE",
      "PatientCondition": data.conditionId,
      "ProjectID": patient.projectId,
      "VisitType": data.visitType
    };
    var success = false;
    await baseAppClient.post(CREATE_PROGRESS_NOTE,
        onSuccess: (dynamic response, int statusCode) {
          if (response['ListCreateProgressNote'] != null) {
            // DrAppToastMsg.showSuccesToast(
            //     response['ListCreateProgressNote']['message']);
            success = true;
          }
        }, onFailure: (String error, int statusCode) {
          success = false;
          hasError = true;
          super.error = error;
        }, body: request);

    return success;
  }
}
