package com.app.simplitend.caregiverdashboard.activities;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;

import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.CaregiverDataCache;
import com.app.simplitend.apputils.EditTextErrorRemover;
import com.app.simplitend.apputils.PatientDataCache;
import com.app.simplitend.apputils.RetrofitHelper;
import com.app.simplitend.apputils.TextUtils;
import com.app.simplitend.caregiverdashboard.mvvm.CaregiverMainViewModel;
import com.app.simplitend.caregiverdashboard.mvvm.CgHomeContracts;
import com.app.simplitend.databinding.ActivityPersonalInfoBinding;
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;
import com.bumptech.glide.Glide;
import com.github.dhaval2404.imagepicker.ImagePicker;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import com.skydoves.powerspinner.OnSpinnerItemSelectedListener;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

public class EditProfileInfoActivity extends AppCompatActivity implements
        CgHomeContracts.UpdateCaregiverDataCallback, CgHomeContracts.UpdatePatientDataCallback {

    private static final String TAG = "PatientProfileInfoActiv";
    // view binding
    protected ActivityPersonalInfoBinding binding;
    private CaregiverMainViewModel viewModel;
    private ProgressDialog progressDialog;
    private DatePickerDialog datePickerDialog;
    private ArrayList<String> countryCodeList;
    private PatientData patientData;
    private CareGiverData careGiverData;
    private ArrayList<String> countryList;
    private HashMap<String, ArrayList<String>> country_N_states_map;
    private Uri selectedImageUri;
    private ActivityResultLauncher<Intent> imageSelector;

    /*
        There are total three ways to enter this activity

        1. From the caregiver side to edit patient profile
            where, IS_CAREGIVER value is not passed.
            thus, default value of isCaregiver is false

        2. From the caregiver side to update Caregivers profile
            where, IS_CAREGIVER value is passed as true.
            thus, to update the caregiver data

        In both above cases use the bearer token from the caregiver side

        3. From patient side to update Patients profile
            where, IS_FROM_PATIENT value is passed as true
     */

    public static final String IS_CAREGIVER = "is_caregiver";
    public static final String IS_FROM_PATIENT = "from_patient";

    private boolean isCaregiver, isFromPatient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityPersonalInfoBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        viewModel = new ViewModelProvider(this).get(CaregiverMainViewModel.class);
        progressDialog = new ProgressDialog(this);

        Intent intent = getIntent();
        if (intent != null){
            isCaregiver = intent.getBooleanExtra(IS_CAREGIVER, false);
            isFromPatient = intent.getBooleanExtra(IS_FROM_PATIENT, false);
        }

        if (isCaregiver){
            // no address for caregiver
            binding.addressView.setVisibility(View.GONE);
        }

        initViews();

        clickEvents();

        if (isFromPatient){
            // intent from patient side
            // thus, fetching the patient cache
            PatientDataCache.getPatientData(this, (patientData1 -> {
                this.patientData = patientData1;

                setDetails();
            }), true);
        }else{
            // other possible intent is from caregiver side
            // thus, fetching caregiver cache
            CaregiverDataCache.getCaregiverData(this, (careGiverData -> {
                if (careGiverData == null) return;

                this.patientData = careGiverData.patientDetails;
                this.careGiverData = careGiverData;

                setDetails();
            }), true);
        }
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        final Configuration configuration = new Configuration(newBase.getResources().getConfiguration());
        configuration.fontScale = Math.min(configuration.fontScale, 1.1f);
        applyOverrideConfiguration(configuration);
        super.attachBaseContext(newBase);
    }

    private void setDetails() {
        if (isCaregiver){
            // load caregiver data
            if (careGiverData == null){
                Toast.makeText(this, "Couldn't load your data.", Toast.LENGTH_SHORT).show();
                return;
            }

            binding.name.setText(careGiverData.first_name);
            binding.dob.setText(formatDateToMMddYYYY("yyyy-MM-dd", careGiverData.date_of_birth));
            binding.contactNumber.setText(careGiverData.phone_number);
            binding.email.setText(careGiverData.email);
            binding.email.setEnabled(false);

            if (careGiverData.profile_photo != null){
                Glide.with(this)
                        .load(RetrofitHelper.IMAGE_BASE_URL + careGiverData.profile_photo)
                        .placeholder(android.R.color.darker_gray)
                        .error(R.drawable.caregiver_img)
                        .into(binding.image);
            }
        }else{
            if (patientData == null) {
                Toast.makeText(this, "Couldn't load patient data.", Toast.LENGTH_SHORT).show();
                return;
            }

            // load patient data
            if (patientData.profile_photo != null){
                Glide.with(this)
                        .load(RetrofitHelper.IMAGE_BASE_URL + patientData.profile_photo)
                        .placeholder(android.R.color.darker_gray)
                        .error(R.drawable.caregiver_img)
                        .into(binding.image);
            }

            binding.name.setText(patientData.first_name);
            binding.dob.setText(formatDateToMMddYYYY("yyyy-MM-dd", patientData.date_of_birth));
            binding.contactNumber.setText(patientData.phone_number);
            binding.email.setText(patientData.email);

            binding.street.setText(patientData.address_line1);
            binding.town.setText(patientData.city);
            binding.zipCode.setText(patientData.post_code);

            String country = patientData.country;
            String state = patientData.state;
            if (!countryList.contains(country)){
                countryList.add(country);
                ArrayList<String> states = new ArrayList<>();
                states.add(state);
                country_N_states_map.put(country, states);
            }

            try {
                binding.countrySpinner.selectItemByIndex(countryList.indexOf(country));
                binding.stateSpinner.selectItemByIndex(country_N_states_map.get(country).indexOf(state));
            } catch (Exception e) {
                // do nothing
            }
        }


    }

    private void initViews() {

        loadCountriesAndStates();

        // date picker dialog
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 18);

        datePickerDialog = new DatePickerDialog(this,
                (datePicker, year, month, dayOfMonth) -> {
                    setDOB(year, month, dayOfMonth);

                    binding.contactNumber.requestFocus();

                    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

                }, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
        datePickerDialog.getDatePicker().setMaxDate(calendar.getTimeInMillis());
        datePickerDialog.setTitle("Select a date");
        datePickerDialog.setMessage("Note: Click on the date, month or year to edit manually");

        // creating this view model here as it contains the fetching code
        countryCodeList = AppUtil.loadCountryCodeDropDown(this);

        binding.countryCodes.setLifecycleOwner(this);
        binding.countryCodes.setItems(countryCodeList);
        if (!countryCodeList.contains("+1")) {
            countryCodeList.add("+1");
        }
        binding.countryCodes.selectItemByIndex(countryCodeList.indexOf("+1"));
        binding.countryCodes.setDismissWhenNotifiedItemSelected(true);
        binding.countryCodes.setIsFocusable(true);

        setPhoneNumberInputFilter();

        setFocusManager();

        inputFieldFocusManage();

        imageSelector = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
                        //Image Uri will not be null for RESULT_OK
                        selectedImageUri = result.getData().getData();

                        binding.image.setImageURI(null);
                        binding.image.setImageURI(selectedImageUri);

                    } else if (result.getResultCode() == ImagePicker.RESULT_ERROR) {
                        Toast.makeText(this, ImagePicker.getError(result.getData()), Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(this, "Task Cancelled", Toast.LENGTH_SHORT).show();
                    }
                });

        binding.name.addTextChangedListener(TextUtils.LEADING_SPACE_WATCHER);
        binding.email.addTextChangedListener(TextUtils.LEADING_SPACE_WATCHER);
        binding.street.addTextChangedListener(TextUtils.LEADING_SPACE_WATCHER);

        new EditTextErrorRemover(binding.name, binding.email, binding.contactNumber, binding.street);

    }

    private void clickEvents() {
        binding.save.setOnClickListener(v -> {
            if (allCgOkay()) {
                AppUtil.closeKeyboard(this);
                AppUtil.showSOSDecision(this,
                        getString(R.string.make_changes),
                        getString(R.string.yes),
                        getString(R.string.no),
                        yes -> {
                            if (isFromPatient){
                                updatePatientData();
                            }else{
                                updateCareGiverData();
                            }
                        }, no -> {

                        });
            }
        });

        binding.dob.setOnClickListener(v -> {
            pickDate();
        });

        binding.backBtn.setOnClickListener(v -> {
            onBackPressed();
        });

        binding.image.setOnClickListener(v -> {

            ImagePicker.with(this)
                    .cropSquare()
                    .maxResultSize(500, 500)
                    .galleryOnly()
                    .createIntent(intent -> {
                        imageSelector.launch(intent);
                        return null;
                    });

        });

        binding.countryCodes.setOnClickListener(v -> {
            AppUtil.closeKeyboard(this);
            binding.countryCodes.showOrDismiss();
        });
    }

    private boolean allCgOkay() {

        binding.name.setError(null);
        binding.dob.setError(null);
        binding.contactNumber.setError(null);
        binding.email.setError(null);

        boolean allOkay = true;

        if (binding.name.getText().toString().trim().isEmpty()) {
            binding.name.setError("Required");
            allOkay = false;
        }else if (binding.name.getText().toString().trim().length() < 2){
            binding.name.setError("Minimum 2 characters");
            allOkay = false;
        }

        if (binding.dob.getText().toString().trim().isEmpty()) {
            binding.dob.setError("Required");
            allOkay = false;
        }

        if (binding.contactNumber.getText().toString().trim().isEmpty() ||
                binding.contactNumber.getText().toString().trim().length() < 10) {
            binding.contactNumber.setError("Invalid");
            allOkay = false;
        } else if (binding.countryCodes.getSelectedIndex() == -1 ||
                binding.countryCodes.getSelectedIndex() >= countryCodeList.size()) {
            allOkay = false;
            Toast.makeText(this, "Select a country code.", Toast.LENGTH_SHORT).show();
        } else {
            // validating phone number
            try {
                Phonenumber.PhoneNumber phone_number = PhoneNumberUtil.getInstance().parse(countryCodeList.get(binding.countryCodes.getSelectedIndex()) +
                        binding.contactNumber.getText().toString(), "US");

                if (!PhoneNumberUtil.getInstance().isValidNumber(phone_number)) {
                    binding.contactNumber.setError("Invalid phone number");
                    allOkay = false;
                }
            } catch (NumberParseException e) {
                // do nothing as we couldn't validate phone number
            }
        }

        if (binding.email.getText().toString().trim().isEmpty()) {
            binding.email.setError("Required");
            allOkay = false;
        } else if (!Patterns.EMAIL_ADDRESS.matcher(binding.email.getText().toString()).matches()) {
            binding.email.setError("Invalid email");
            allOkay = false;
        }

        return allOkay;
    }

    private void updateCareGiverData() {
        if (careGiverData == null || careGiverData.patientDetails == null) return;

        progressDialog.setTitle("Please wait...");
        progressDialog.setMessage("while we update your data.");
        progressDialog.setCancelable(false);
        progressDialog.show();

        Map<String, RequestBody> body = new HashMap<>();

        RequestBody user_first_name = RequestBody.create(binding.name.getText().toString().trim(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("full_name", user_first_name);

        String country_code;
        if (binding.countryCodes.getSelectedIndex() == -1 ||
            binding.countryCodes.getSelectedIndex() >= countryCodeList.size()){
            country_code = "+1";
        }else{
            country_code = countryCodeList.get(binding.countryCodes.getSelectedIndex());
        }
        RequestBody contact_number_part = RequestBody.create(country_code+binding.contactNumber.getText().toString(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("contact_number", contact_number_part);

        RequestBody email_part = RequestBody.create(binding.email.getText().toString().trim(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("email", email_part);

        RequestBody dob_part = RequestBody.create(binding.dob.getText().toString(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("date_of_birth", dob_part);

        MultipartBody.Part filePart = null;

        if (selectedImageUri != null) {
            RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), new File(selectedImageUri.getPath()));
            filePart = MultipartBody.Part.createFormData("photo",
                    "img_" + System.currentTimeMillis()
                    , requestFile);
        }

        if (isCaregiver){
            viewModel.updateCaregiverData(careGiverData.caregiver_xid,
                    body, filePart, "Bearer " + AppUtil.getCgToken(this),
                    this);
        }else{
            RequestBody street_part = RequestBody.create(binding.street.getText().toString().trim(), MediaType.parse("text/plain;charset=utf-8"));
            body.put("street", street_part);

            viewModel.updatePatientData(careGiverData.patientId,
                    body, filePart, "Bearer " + AppUtil.getCgToken(this),
                    this);
        }

    }

    private void updatePatientData() {
        if (patientData == null) return;

        progressDialog.setTitle("Please wait...");
        progressDialog.setMessage("while we update your data.");
        progressDialog.setCancelable(false);
        progressDialog.show();

        Map<String, RequestBody> body = new HashMap<>();

        RequestBody user_first_name = RequestBody.create(binding.name.getText().toString().trim(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("full_name", user_first_name);

        String country_code;
        if (binding.countryCodes.getSelectedIndex() == -1 ||
                binding.countryCodes.getSelectedIndex() >= countryCodeList.size()){
            country_code = "+1";
        }else{
            country_code = countryCodeList.get(binding.countryCodes.getSelectedIndex());
        }
        RequestBody contact_number_part = RequestBody.create(country_code+binding.contactNumber.getText().toString(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("contact_number", contact_number_part);

        RequestBody email_part = RequestBody.create(binding.email.getText().toString().trim(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("email", email_part);

        RequestBody dob_part = RequestBody.create(binding.dob.getText().toString(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("date_of_birth", dob_part);

        MultipartBody.Part filePart = null;

        if (selectedImageUri != null) {
            RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), new File(selectedImageUri.getPath()));
            filePart = MultipartBody.Part.createFormData("photo",
                    "img_" + System.currentTimeMillis()
                    , requestFile);
        }

        RequestBody street_part = RequestBody.create(binding.street.getText().toString().trim(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("street", street_part);

        viewModel.updatePatientData(patientData.patientId,
                body, filePart, "Bearer " + AppUtil.getPatientToken(this),
                this);

    }

    private void setDOB(int year, int month, int dayOfMonth) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);

        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy", Locale.getDefault());

        String selected_time = sdf.format(cal.getTime());
        binding.dob.setText(selected_time);
    }

    // This adds textChangeListener to all the EditTexts available to remove error if available
    private void setPhoneNumberInputFilter() {
        // phone number formatting
        // to deal with input pasting in the edit text
        InputFilter phoneFilter = (charSequence, i, i1, spanned, i2, i3) -> {
            String phone_number_str = charSequence.toString();

            String country_code;

            if (binding.countryCodes.getSelectedIndex() == -1) {
                country_code = "+1";
            } else {
                country_code = countryCodeList.get(binding.countryCodes.getSelectedIndex());
            }

            try {
                PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
                Phonenumber.PhoneNumber phoneNumber = phoneNumberUtil.parse(charSequence, "US");

                phone_number_str = String.valueOf(phoneNumber.getNationalNumber());
                country_code = "+" + phoneNumber.getCountryCode();
            } catch (Exception e) {
                // nothing
            }

            if (!countryCodeList.contains(country_code)) {
                countryCodeList.add(country_code);
            }

            binding.countryCodes.selectItemByIndex(countryCodeList.indexOf(country_code));

            if (phone_number_str.length() > 10) {
                // pasted number length is greater than 10
                return phone_number_str.substring(0, 10);
            }

            String total_phone_number = binding.contactNumber.getText().toString() + phone_number_str;

            if (total_phone_number.length() > 10) {
                // max length should be 10
                return "";
            } else {
                return phone_number_str;
            }
        };

        binding.contactNumber.setFilters(new InputFilter[]{phoneFilter});

    }

    private void setFocusManager() {
        binding.name.setOnEditorActionListener((textView, i, keyEvent) -> {
            AppUtil.closeKeyboard(this);
            binding.name.clearFocus();

            pickDate();
            return true;
        });
    }

    private void pickDate() {

        if (datePickerDialog == null) return;

        datePickerDialog.show();

    }

    public String formatDateToMMddYYYY(String inputFormat, String input_date) {
        SimpleDateFormat out_sdf = new SimpleDateFormat("MM-dd-yyyy", Locale.getDefault());
        SimpleDateFormat in_sdf = new SimpleDateFormat(inputFormat, Locale.getDefault());

        try {
            Date date = in_sdf.parse(input_date);
            input_date = out_sdf.format(date);

            // setting it to datepickerdialog
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            if (datePickerDialog != null) {
                datePickerDialog.getDatePicker().updateDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
            }
        } catch (Exception e) {
            // do nothing
            return input_date;
        }

        return input_date;
    }

    private void inputFieldFocusManage() {

        binding.town.setOnEditorActionListener((textView, i, keyEvent) -> {
            AppUtil.closeKeyboard(this);
            binding.town.clearFocus();
            binding.stateSpinner.show();
            return true;
        });

        binding.zipCode.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (editable.toString().length() == 6){
                    binding.zipCode.clearFocus();
                    AppUtil.closeKeyboard(EditProfileInfoActivity.this);
                }
            }
        });

    }

    private void loadCountriesAndStates() {

        countryList = new ArrayList<>();

        country_N_states_map = new HashMap<>();

        try {

            String country_n_states_str = readCountryNStates(this);

            JSONArray country_n_states = new JSONObject(country_n_states_str).getJSONArray("countries");

            Log.d(TAG, "loadCountriesAndStates: " + country_n_states);

            for (int i = 0; i < country_n_states.length(); i++) {

                String country = country_n_states.getJSONObject(i).getString("country");
                countryList.add(country);

                JSONArray states = country_n_states.getJSONObject(i).getJSONArray("states");

                ArrayList<String> stateList = new ArrayList<>();

                for (int j = 0; j < states.length(); j++) {
                    stateList.add(states.getString(j));
                }

                country_N_states_map.put(country, stateList);
            }

        } catch (Exception e) {

            Log.e(TAG, "load country and states: ", e);
        }

        Log.d(TAG, "loadCountriesAndStates: " + countryList);

        binding.stateSpinner.setLifecycleOwner(this);
        binding.countrySpinner.setLifecycleOwner(this);

        binding.countrySpinner.setItems(countryList);


        // selecting United States country as by default
//        if (countryList.contains(UNITED_STATES)){
//            binding.countrySpinner.selectItemByIndex(countryList.indexOf(UNITED_STATES));
//
//            if (country_N_states_map.containsKey(UNITED_STATES))
//            {
//                binding.stateSpinner.setItems(country_N_states_map.get(UNITED_STATES));
//            }
//        }

        binding.stateSpinner.setDismissWhenNotifiedItemSelected(true);
        binding.countrySpinner.setDismissWhenNotifiedItemSelected(true);

        binding.stateSpinner.setIsFocusable(true);
        binding.countrySpinner.setIsFocusable(true);

        binding.countrySpinner.setOnSpinnerItemSelectedListener((OnSpinnerItemSelectedListener<String>) (i, s, i1, t1) -> {

            binding.countrySpinner.setError(null);

            ArrayList<String> stateList;

            if (country_N_states_map.containsKey(t1) && country_N_states_map.get(t1) != null) {
                stateList = country_N_states_map.get(t1);
            } else {
                stateList = new ArrayList<>();
            }

            if (stateList != null) {
                binding.stateSpinner.setItems(stateList);
                binding.stateSpinner.clearSelectedItem();
            }
        });

        binding.stateSpinner.setOnSpinnerItemSelectedListener((OnSpinnerItemSelectedListener<String>) (i, s, i1, t1) -> {
            binding.stateSpinner.setError(null);
            binding.zipCode.requestFocus();
        });

    }

    public String readCountryNStates(Context context) throws IOException {
        StringBuilder returnString = new StringBuilder();

        InputStream fIn = context.getResources().openRawResource(R.raw.country_n_states);
        InputStreamReader isr = new InputStreamReader(fIn);
        BufferedReader input = new BufferedReader(isr);

        String line = "";

        while ((line = input.readLine()) != null) {
            returnString.append(line);
        }

        try {
            isr.close();

            if (fIn != null) fIn.close();

            input.close();

        } catch (Exception e) {
            Log.e(TAG, "readCountryNStates: ", e);
        }

        return returnString.toString();
    }

    // update caregiver data callback
    @Override
    public void onCaregiverDataUpdated(@NonNull CareGiverData careGiverData) {
        binding.image.requestFocus();
        progressDialog.dismiss();

        AppUtil.showAnimateDBS(this,
                getString(R.string.changes_successful), R.raw.done_anim_primary,
                3600, v3 -> {
                    // here v3 is null
                    CaregiverDataCache.setCareGiverData(careGiverData);
                    Toast.makeText(this, "Data updated.", Toast.LENGTH_SHORT).show();
                    onBackPressed();
                });
    }

    @Override
    public void onCaregiverDateUpdateFailed(Throwable throwable, String message) {
        progressDialog.dismiss();
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

    // update patient details callback
    @Override
    public void onPatientDataUpdated(@NonNull PatientData patient) {
        progressDialog.dismiss();

        AppUtil.showAnimateDBS(this,
                getString(R.string.changes_successful), R.raw.done_anim_primary,
                3600, v3 -> {
                    // here v3 is null
                    if (!isFromPatient && this.careGiverData != null){
                        this.careGiverData.patientDetails = patient;
                        CaregiverDataCache.setCareGiverData(careGiverData);
                    }else{
                        if (this.patientData != null) patient.patientId = this.patientData.patientId;

                        PatientDataCache.setPatientData(patient);
                    }

                    Toast.makeText(this, "Data updated.", Toast.LENGTH_SHORT).show();
                    onBackPressed();
                });
    }

    @Override
    public void onPatientDataUpdateFailed(Throwable throwable, String message) {
        progressDialog.dismiss();
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
}