import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:hmg_patient_app_new/core/app_state.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
import 'package:hmg_patient_app_new/features/inpatient_services/inpatient_services_repo.dart';
import 'package:hmg_patient_app_new/features/inpatient_services/models/get_admission_info_response_model.dart';
import 'package:hmg_patient_app_new/features/inpatient_services/models/get_admission_request_info_response_model.dart';
import 'package:hmg_patient_app_new/features/inpatient_services/models/get_general_instructions_response_model.dart';
import 'package:hmg_patient_app_new/features/inpatient_services/models/get_inpatient_advance_history_response_model.dart';
import 'package:hmg_patient_app_new/features/inpatient_services/models/get_inpatient_advance_requests_response_model.dart';
import 'package:hmg_patient_app_new/features/inpatient_services/models/get_medical_instructions_response_model.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:hmg_patient_app_new/services/navigation_service.dart';
import 'package:hmg_patient_app_new/widgets/common_bottom_sheet.dart';
import 'package:hmg_patient_app_new/widgets/loader/bottomsheet_loader.dart';

import '../../generated/locale_keys.g.dart';

class InpatientServicesViewModel extends ChangeNotifier {
  InpatientServicesRepo inpatientServicesRepo;
  ErrorHandlerService errorHandlerService;
  AppState appState;

  GetAdmissionInfoResponseModel? getAdmissionInfoResponseModel;
  GetAdmissionRequestInfoResponseModel? getAdmissionRequestInfoResponseModel;
  InPatientAdvanceResponseModel? inPatientAdvanceResponseModel;
  InPatientAdvanceHistoryResponseModel? inPatientAdvanceHistoryResponseModel;

  bool isAdmitted = false;
  bool hasAdmissionRequest = false;
  bool isGeneralInstructionsLoading = true;
  bool isMedicalInstructionsLoading = true;
  bool isAdvancePaymentHistoryLoading = true;

  bool hasDischargeMedicationOrder = false;

  List<GetGeneralInstructions> getGeneralInstructionsList = [];
  List<GetMedicalInstructions> getMedicalInstructionsList = [];

  int advancePaymentSelectedTabIndex = 0;

  InpatientServicesViewModel({required this.inpatientServicesRepo, required this.errorHandlerService, required this.appState});

  initInPatientServices() {
    isAdmitted = false;
    hasAdmissionRequest = false;
    isGeneralInstructionsLoading = true;
    isMedicalInstructionsLoading = true;
    hasDischargeMedicationOrder = false;
    advancePaymentSelectedTabIndex = 0;
    isAdvancePaymentHistoryLoading = true;
    notifyListeners();
  }

  void onTabChanged(int index) {
    advancePaymentSelectedTabIndex = index;
    if (index == 1) {
      getInPatientAdvancePaymentHistory(
          projectID: isAdmitted ? getAdmissionInfoResponseModel!.projectID! : getAdmissionRequestInfoResponseModel!.projectId!,
          admissionNo: isAdmitted ? getAdmissionInfoResponseModel!.admissionNo! : 0,
          admissionReqNo: isAdmitted ? getAdmissionInfoResponseModel!.admissionRequestNo! : getAdmissionRequestInfoResponseModel!.admissionRequestNo!);
    }
    notifyListeners();
  }

  Future<void> checkIfIsInPatient({Function(dynamic)? onSuccess, Function(String)? onError}) async {
    final result = await inpatientServicesRepo.checkIfIsInPatient();

    result.fold(
      (failure) async {
        notifyListeners();
      },
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          isAdmitted = apiResponse.data['isAdmitted'];
          hasAdmissionRequest = apiResponse.data['hasAdmissionRequests'];
          if (isAdmitted) {
            if (apiResponse.data['PatientAdmittedInformation'].length != 0) {
              getAdmissionInfoResponseModel = GetAdmissionInfoResponseModel.fromJson(apiResponse.data['PatientAdmittedInformation'][0]);
              appState.setIsPatientAdmitted(true);
              appState.setHasAdmissionRequest(false);
            }
          }
          if (hasAdmissionRequest) {
            if (apiResponse.data['MedicalInstruction'].length != 0) {
              getAdmissionRequestInfoResponseModel = GetAdmissionRequestInfoResponseModel.fromJson(apiResponse.data['MedicalInstruction'][0]);
              appState.setIsPatientAdmitted(false);
              appState.setHasAdmissionRequest(true);
            }
          }
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<void> getGeneralInstructions({required int projectID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
    isGeneralInstructionsLoading = true;
    getGeneralInstructionsList.clear();
    notifyListeners();

    final result = await inpatientServicesRepo.getGeneralInstructions(projectID: projectID);

    result.fold(
      (failure) async {
        isGeneralInstructionsLoading = false;
        notifyListeners();
      },
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          isGeneralInstructionsLoading = false;
          getGeneralInstructionsList = apiResponse.data!;
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<void> getMedicalInstructions({required int projectID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
    isMedicalInstructionsLoading = true;
    getMedicalInstructionsList.clear();
    notifyListeners();

    final result = await inpatientServicesRepo.getMedicalInstructions(projectID: projectID);

    result.fold(
      (failure) async {
        isMedicalInstructionsLoading = false;
        notifyListeners();
      },
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          isMedicalInstructionsLoading = false;
          getMedicalInstructionsList = apiResponse.data!;
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<void> checkDischargeMedications({required GetAdmissionInfoResponseModel getAdmissionInfoResponseModel, Function(dynamic)? onSuccess, Function(String)? onError}) async {
    LoaderBottomSheet.showLoader();
    final result = await inpatientServicesRepo.getDischargeMedicationOrder(getAdmissionInfoResponseModel: getAdmissionInfoResponseModel);

    result.fold(
      (failure) async {
        LoaderBottomSheet.hideLoader();
        if (onError != null) {
          onError(failure.message.toString());
        }
      },
      (apiResponse) async {
        if (apiResponse.messageStatus == 2) {
          LoaderBottomSheet.hideLoader();
          if (onError != null) {
            onError("You don't have any discharge medication orders yet.");
          }
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          if (apiResponse.data["PatientHasDischargeMedicineList"].length != 0) {
            hasDischargeMedicationOrder = true;

            await insertInPatientOrder(
                getAdmissionInfoResponseModel: getAdmissionInfoResponseModel,
                typeID: 1,
                patientName: "${appState.getAuthenticatedUser()!.firstName!} ${appState.getAuthenticatedUser()!.lastName!}",
                patientNameAR: "${appState.getAuthenticatedUser()!.firstNameN!} ${appState.getAuthenticatedUser()!.lastNameN!}",
                patientMobileNo: appState.getAuthenticatedUser()!.mobileNumber!,
                comments: "I need my medicines",
                onSuccess: (val) {
                  LoaderBottomSheet.hideLoader();
                  showCommonBottomSheetWithoutHeight(GetIt.instance<NavigationService>().navigatorKey.currentContext!,
                      child: Utils.getSuccessWidget(loadingText: LocaleKeys.requestSubmittedSuccessfully.tr()).paddingSymmetrical(0.h, 24.h),
                      callBackFunc: () {},
                      isFullScreen: false,
                      isCloseButtonVisible: false,
                      isAutoDismiss: true);
                });
          }
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<void> insertInPatientOrder(
      {required GetAdmissionInfoResponseModel getAdmissionInfoResponseModel,
      required int typeID,
      required String patientName,
      required String patientNameAR,
      required String patientMobileNo,
      required String comments,
      Function(dynamic)? onSuccess,
      Function(String)? onError}) async {
    final result = await inpatientServicesRepo.insertInPatientOrder(
        getAdmissionInfoResponseModel: getAdmissionInfoResponseModel, typeID: typeID, patientName: patientName, patientNameAR: patientNameAR, patientMobileNo: patientMobileNo, comments: comments);

    result.fold(
      (failure) async {
        if (onError != null) {
          onError(failure.message.toString());
        }
      },
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<void> getInPatientAdvancePaymentRequests({required int projectID, required int admissionNo, required int admissionReqNo, Function(dynamic)? onSuccess, Function(String)? onError}) async {
    final result = await inpatientServicesRepo.getInPatientAdvancePaymentRequests(projectID: projectID, admissionNo: admissionNo, admissionReqNo: admissionReqNo);

    result.fold(
      (failure) async {
        notifyListeners();
      },
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          if (apiResponse.data['responseInpatient'] != null &&
              apiResponse.data['responseInpatient']['responseInpatientAdvanceInfo'] != null &&
              apiResponse.data['responseInpatient']['responseInpatientAdvanceInfo'].length != 0) {
            inPatientAdvanceResponseModel = InPatientAdvanceResponseModel.fromJson(apiResponse.data["responseInpatient"]);
            if (onSuccess != null) {
              onSuccess(apiResponse);
            }
          } else {
            // if (onSuccess != null) {
            //   onSuccess(apiResponse);
            // }

            if (onError != null) {
              onError(LocaleKeys.noAdvancePaymentRequestsFound.tr());
            }
          }
          notifyListeners();
        }
      },
    );
  }

  Future<void> getInPatientAdvancePaymentHistory({required int projectID, required int admissionNo, required int admissionReqNo, Function(dynamic)? onSuccess, Function(String)? onError}) async {
    isAdvancePaymentHistoryLoading = true;
    notifyListeners();

    final result = await inpatientServicesRepo.getInPatientAdvancePaymentPaid(projectID: projectID, admissionNo: admissionNo, admissionReqNo: admissionReqNo);

    result.fold(
      (failure) async {
        isAdvancePaymentHistoryLoading = false;
        notifyListeners();
      },
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          isAdvancePaymentHistoryLoading = false;
          if (apiResponse.data['responseInpatient'] != null &&
              apiResponse.data['responseInpatient']['responseInpatientAdvanceInfo'] != null &&
              apiResponse.data['responseInpatient']['responseInpatientAdvanceInfo'].length != 0) {
            inPatientAdvanceHistoryResponseModel = InPatientAdvanceHistoryResponseModel.fromJson(apiResponse.data["responseInpatient"]);
            if (onSuccess != null) {
              onSuccess(apiResponse);
            }
          } else {
            if (onError != null) {
              onError(LocaleKeys.noAdvancePaymentRequestsFound.tr());
            }
          }
          notifyListeners();
        }
      },
    );
  }
}
