import 'package:doctor_app_flutter/core/enum/view_state.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/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/update_note_model.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/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/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/patient/patient_service.dart';
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';

import '../../config/shared_pref_kay.dart';
import '../../locator.dart';
import '../model/note/stp_master_list_req_model.dart';
import '../model/note/stp_master_list_res_model.dart';
import 'base_view_model.dart';

class PatientViewModel extends BaseViewModel {
  PatientService _patientService = locator<PatientService>();

  List<PatiantInformtion> get inPatientList => _patientService.inPatientList;

  List<VitalSignResModel> get patientVitalSignList =>
      _patientService.patientVitalSignList;

  List<VitalSignResModel> get patientVitalSignOrderdSubList =>
      _patientService.patientVitalSignOrderdSubList;

  List<LabOrdersResModel> get patientLabResultOrdersList =>
      _patientService.patientLabResultOrdersList;

  List<PrescriptionResModel> get patientPrescriptionsList =>
      _patientService.patientPrescriptionsList;

  List<PrescriptionReportForInPatient> get prescriptionReportForInPatientList =>
      _patientService.prescriptionReportForInPatientList;

  List<PrescriptionReport> get prescriptionReport =>
      _patientService.prescriptionReport;

  List<RadiologyResModel> get patientRadiologyList =>
      _patientService.patientRadiologyList;

  List<LabResult> get labResultList => _patientService.labResultList;

  get insuranceApporvalsList => _patientService.insuranceApporvalsList;

  List<NoteModel> get patientProgressNoteList =>
      _patientService.patientProgressNoteList;

  List<GetNursingProgressNoteResposeModel> get patientNursingProgressNoteList =>
      _patientService.patientNursingProgressNoteList;

  List<GetDiagnosisForInPatientResponseModel> get diagnosisForInPatientList =>
      _patientService.diagnosisForInPatientList;

  List<GetDiabeticChartValuesResponseModel> get diabeticChartValuesList =>
      _patientService.diabeticChartValuesList;

  List<dynamic> get clinicsList => _patientService.clinicsList;

  List<dynamic> get doctorsList => _patientService.doctorsList;

  List<dynamic> get referralFrequencyList =>
      _patientService.referalFrequancyList;

  List<dynamic> get stpMasterList =>
      _patientService.stpMasterList;

  Future getPatientList(patient, patientType,
      {bool isBusyLocal = false, isView}) async {
    var localRes;
    if (isBusyLocal) {
      setState(ViewState.BusyLocal);
    } else {
      setState(ViewState.Busy);
    }
    localRes = await _patientService.getPatientList(patient, patientType,
        isView: isView);

    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else {
      setState(ViewState.Idle);
    }
    return localRes;
  }

  Future getLabResultOrders(patient) async {
    setState(ViewState.Busy);
    await _patientService.getLabResultOrders(patient);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getInPatientPrescriptions(patient) async {
    setState(ViewState.Busy);
    await _patientService.getInPatientPrescriptions(patient);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getPrescriptionReport(patient) async {
    setState(ViewState.Busy);
    await _patientService.getPrescriptionReport(patient);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getPatientRadiology(patient) async {
    setState(ViewState.Busy);
    await _patientService.getPatientRadiology(patient);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getLabResult(LabOrdersResModel labOrdersResModel) async {
    setState(ViewState.Busy);
    await _patientService.getLabResult(labOrdersResModel);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getPatientInsuranceApprovals(patient) async {
    setState(ViewState.Busy);
    await _patientService.getPatientInsuranceApprovals(patient);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getPatientProgressNote(patientRequest,PatiantInformtion patient,
      {bool isLocalBusy = false, bool isVidaPlus = false}) async {
    if (isLocalBusy) {
      setState(ViewState.BusyLocal);
    } else {
      setState(ViewState.Busy);
    }
    if (isVidaPlus) {
      Map<String, dynamic> request = {
        "hospitalGroupId": await sharedPref.getString(DOCTOR_SETUP_ID),
        "hospitalId": patient.projectId,
        "patientId": patient.patientId,
        "patientPomrId": patient.pomrId,
        "endRow": 10000, // because no information is provided for the end row
        "startRow": 0,
        "ProjectID": patient.projectId,
        "VisitType": patientRequest["VisitType"]
      };
      await _patientService.getVidaPlusProgressNote(request);
    } else {
      await _patientService.getPatientProgressNote(patientRequest);
    }
    if (_patientService.hasError) {
      error = _patientService.error;
      if (isLocalBusy) {
        setState(ViewState.ErrorLocal);
      } else {
        setState(ViewState.Error);
      }
    } else
      setState(ViewState.Idle);
  }

  Future updatePatientProgressNote(UpdateNoteReqModel req) async {

    setState(ViewState.BusyLocal);
    await _patientService.updatePatientProgressNote(req);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future createPatientProgressNote(CreateNoteModel req, PatiantInformtion patient,
      {bool isVidaPlus = false}) async {
    setState(ViewState.BusyLocal);
    if (isVidaPlus) {
      await _patientService.createProgressNote(req, patient);
    } else {
      await _patientService.createPatientProgressNote(req);
    }
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future getClinicsList() async {
    setState(ViewState.Busy);
    await _patientService.getClinicsList();
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else {
      {
        await getReferralFrequancyList();
        setState(ViewState.Idle);
      }
    }
  }

  Future getDoctorsList(int clinicId) async {
    setState(ViewState.BusyLocal);
    await _patientService.getDoctorsList(clinicId);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.ErrorLocal);
    } else {
      {
        await getReferralFrequancyList();
        setState(ViewState.Idle);
      }
    }
  }

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

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

  Future getReferralFrequancyList() async {
    setState(ViewState.Busy);
    await _patientService.getReferralFrequancyList();
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

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

  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 {
    setState(ViewState.BusyLocal);
    await _patientService.referToDoctor(
        selectedClinicID: selectedClinicID,
        selectedDoctorID: selectedDoctorID,
        admissionNo: admissionNo,
        extension: extension,
        priority: priority,
        frequency: frequency,
        referringDoctorRemarks: referringDoctorRemarks,
        patientID: patientID,
        patientTypeID: patientTypeID,
        roomID: roomID,
        projectID: projectID);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }

  Future getArrivedList() async {
    setState(ViewState.Busy);
    await _patientService.getArrivedList();
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.Error);
    } else
      setState(ViewState.Idle);
  }

  Future getInPatientList(PatientSearchRequestModel requestModel,
      {bool isMyInpatient = false}) async {
    await getDoctorProfile();
    setState(ViewState.Busy);

    await _patientService.getInPatient(requestModel, false);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.ErrorLocal);
    } else {
      // setDefaultInPatientList();
      setState(ViewState.Idle);
    }
  }

  Future getNursingProgressNote(
      GetNursingProgressNoteRequestModel requestModel) async {
    await getDoctorProfile();
    setState(ViewState.Busy);

    await _patientService.getNursingProgressNote(requestModel);
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.ErrorLocal);
    } else {
      setState(ViewState.Idle);
    }
  }

  Future getDiagnosisForInPatient(
      GetDiagnosisForInPatientRequestModel requestModel, bool isVidaPlusProject, PatiantInformtion patient) async {
    await getDoctorProfile();
    setState(ViewState.Busy);

    if(isVidaPlusProject){
      await _patientService.getDiagnosis(patient);

    }else {
      await _patientService.getDiagnosisForInPatient(requestModel);
    }
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.ErrorLocal);
    } else {
      setState(ViewState.Idle);
    }
  }

  Future getDiabeticChartValues(PatiantInformtion patient, int resultType,
      {bool isLocalBusy = false, bool isVidaPlusProject = false}) async {
    await getDoctorProfile();
    if (isLocalBusy)
      setState(ViewState.BusyLocal);
    else
      setState(ViewState.Busy);

    GetDiabeticChartValuesRequestModel requestModel =
        GetDiabeticChartValuesRequestModel(
            patientID: patient.patientId,
            admissionNo:isVidaPlusProject? patient.admissionID ?? -1 : int.parse(patient.admissionNo!),
            patientTypeID: 1,
            resultType: resultType,
            );
    await _patientService.getDiabeticChartValues(requestModel);
    if (_patientService.hasError) {
      error = _patientService.error;
      if (isLocalBusy)
        setState(ViewState.ErrorLocal);
      else
        setState(ViewState.Error);
    } else {
      setState(ViewState.Idle);
    }
  }

  Future getStpMasterList({bool isLocalBusy = false}) async {
    if (isLocalBusy)
      setState(ViewState.BusyLocal);
    else
      setState(ViewState.Busy);

    StpMasterListRequestModel requestModel = StpMasterListRequestModel(
        isDentalAllowedBackend: false,
        languageID: 1,
        projectID: 15,
        parameterGroup: 7,
        parameterType: 362);

    await _patientService.getStpMasterList(requestModel);

    if (_patientService.hasError) {
      error = _patientService.error;
      if (isLocalBusy)
        setState(ViewState.ErrorLocal);
      else
        setState(ViewState.ErrorLocal);
    } else {
      setState(ViewState.Idle);
    }
  }

  void getProgressNoteCondition() async {
    setState(ViewState.BusyLocal);
    await _patientService.getPatientCondition();
    if (_patientService.hasError) {
      error = _patientService.error;
      setState(ViewState.ErrorLocal);
    } else
      setState(ViewState.Idle);
  }
}
