package com.app.simplitend.caregiverdashboard.mvvm;

import android.content.Context;

import androidx.annotation.NonNull;

import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.apputils.RetrofitHelper;
import com.app.simplitend.articles.ArticleContracts;
import com.app.simplitend.articles.ArticlePresenter;
import com.app.simplitend.caregiverdashboard.mvvm.models.GeoFenceDetails;
import com.app.simplitend.welcome.welcomecg.mvvm.CareGiverData;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;

import java.util.Map;

import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class CgHomeRepository {

    private static CgHomeRepository cgHomeRepository;

    private final CgDashboardApiService dash_apiService;

    private CgHomeRepository() {
        dash_apiService = RetrofitHelper.getRetrofit().create(CgDashboardApiService.class);
    }

    public static synchronized CgHomeRepository getHomeRepository() {
        if (cgHomeRepository == null) {
            cgHomeRepository = new CgHomeRepository();
        }

        return cgHomeRepository;
    }

    public void getDefaultArticle(Context context,  @NonNull ArticleContracts.GetArticleCallback getArticleCallback) {
        ArticlePresenter articlePresenter = ArticlePresenter.getArticlePresenter();
        articlePresenter.getDefaultArticle("Bearer " + AppUtil.getCgToken(context), getArticleCallback);
    }

    public void getGeoFenceDetails(String p_id,
                                   String cg_xid,
                                   @NonNull String token,
                                   @NonNull CgHomeContracts.GetGeoFenceCallback getGeoFenceCallback) {

        dash_apiService.getGeofenceDetails(p_id, cg_xid, token)
                .enqueue(new Callback<CallResponse<GeoFenceDetails>>() {
                    @Override
                    public void onResponse(Call<CallResponse<GeoFenceDetails>> call, Response<CallResponse<GeoFenceDetails>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200) {
                                getGeoFenceCallback.onGeofenceDetailsFetchFailed(new Exception(), response.body().message);
                                return;
                            }

                            if (response.body().result == null) {
                                getGeoFenceCallback.onGeofenceDetailsFetched(new GeoFenceDetails());
                            } else {
                                getGeoFenceCallback.onGeofenceDetailsFetched(response.body().result);
                            }
                        } else {
                            getGeoFenceCallback.onGeofenceDetailsFetchFailed(new Exception(), "Couldn't load GeoFence.");
                        }
                    }

                    @Override
                    public void onFailure(Call<CallResponse<GeoFenceDetails>> call, Throwable t) {
                        getGeoFenceCallback.onGeofenceDetailsFetchFailed(new Exception(), "Couldn't load GeoFence.");
                    }
                });

    }

    public void saveGeoFenceDetails(@NonNull GeoFenceDetails geoFenceDetails,
                                    @NonNull String token,
                                    @NonNull CgHomeContracts.SaveGeoFenceCallback geoFenceCallback) {

        dash_apiService.saveGeoFenceDetails(geoFenceDetails, token)
                .enqueue(new Callback<CallResponse<GeoFenceDetails>>() {
                    @Override
                    public void onResponse(Call<CallResponse<GeoFenceDetails>> call, Response<CallResponse<GeoFenceDetails>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200 || response.body().result == null) {
                                geoFenceCallback.onGeofenceDetailsSaveFailed(new Exception(), response.body().message);
                                return;
                            }

                            geoFenceCallback.onGeofenceDetailsSaved(response.body().result);
                        } else {
                            geoFenceCallback.onGeofenceDetailsSaveFailed(new Exception(), "Please try again later.");
                        }
                    }

                    @Override
                    public void onFailure(Call<CallResponse<GeoFenceDetails>> call, Throwable t) {
                        geoFenceCallback.onGeofenceDetailsSaveFailed(new Exception(), "Please try again later.");
                    }
                });

    }

    public void updateCaregiverData(int cg_xid,
                                    Map<String, RequestBody> body,
                                    MultipartBody.Part photo,
                                    @NonNull String token,
                                    @NonNull CgHomeContracts.UpdateCaregiverDataCallback updateCaregiverDataCallback) {
        dash_apiService.updateCaregiverData(cg_xid, body, photo, token)
                .enqueue(new Callback<CallResponse<CareGiverData>>() {
                    @Override
                    public void onResponse(Call<CallResponse<CareGiverData>> call, Response<CallResponse<CareGiverData>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200 || response.body().result == null) {
                                updateCaregiverDataCallback.onCaregiverDateUpdateFailed(new Exception(), response.body().message);
                                return;
                            }

                            updateCaregiverDataCallback.onCaregiverDataUpdated(response.body().result);
                        } else {
                            updateCaregiverDataCallback.onCaregiverDateUpdateFailed(new Exception(), "Please try again later.");
                        }
                    }

                    @Override
                    public void onFailure(Call<CallResponse<CareGiverData>> call, Throwable t) {
                        updateCaregiverDataCallback.onCaregiverDateUpdateFailed(new Exception(), "Please try again later.");
                    }
                });
    }

    public void updatePatientData(int patient_xid,
                                  Map<String, RequestBody> body,
                                  MultipartBody.Part photo,
                                  String token,
                                  @NonNull CgHomeContracts.UpdatePatientDataCallback patientDataCallback) {
        dash_apiService.updatePatientData(patient_xid, body, photo, token)
                .enqueue(new Callback<CallResponse<PatientData>>() {
                    @Override
                    public void onResponse(Call<CallResponse<PatientData>> call, Response<CallResponse<PatientData>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200 || response.body().result == null) {
                                patientDataCallback.onPatientDataUpdateFailed(new Exception(), response.body().message);
                                return;
                            }

                            patientDataCallback.onPatientDataUpdated(response.body().result);
                        } else {
                            patientDataCallback.onPatientDataUpdateFailed(new Exception(), "Please try again later.");
                        }
                    }

                    @Override
                    public void onFailure(Call<CallResponse<PatientData>> call, Throwable t) {
                        patientDataCallback.onPatientDataUpdateFailed(new Exception(), "Please try again later.");
                    }
                });
    }

    public void updatePatientAddress(int pat_id,
                                     Map<String, String> body,
                                     @NonNull String token,
                                     @NonNull CgHomeContracts.UpdatePatientAddressCallback patientAddressCallback) {
        dash_apiService.updatePatientAddress(pat_id, body, token)
                .enqueue(new Callback<CallResponse<PatientData>>() {
                    @Override
                    public void onResponse(Call<CallResponse<PatientData>> call, Response<CallResponse<PatientData>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200 || response.body().result == null) {
                                patientAddressCallback.onPatientAddressUpdateFailed(new Exception(), response.body().message);
                                return;
                            }

                            patientAddressCallback.onPatientAddressUpdated(response.body().result);
                        } else {
                            patientAddressCallback.onPatientAddressUpdateFailed(new Exception(), "Please try again later.");
                        }
                    }

                    @Override
                    public void onFailure(Call<CallResponse<PatientData>> call, Throwable t) {
                        patientAddressCallback.onPatientAddressUpdateFailed(new Exception(), "Please try again later.");
                    }
                });
    }

    public void updateCgPassword(int cg_xid,
                                 Map<String, RequestBody> body,
                                 @NonNull String token,
                                 @NonNull CgHomeContracts.UpdateCgPasswordCallback passwordCallback) {

        dash_apiService.updateCgPassword(cg_xid, body, token)
                .enqueue(new Callback<CallResponse<CareGiverData>>() {
                    @Override
                    public void onResponse(Call<CallResponse<CareGiverData>> call, Response<CallResponse<CareGiverData>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200 || response.body().result == null) {
                                passwordCallback.onPasswordUpdateFailed(new Exception(), response.body().message);
                                return;
                            }

                            passwordCallback.onPasswordUpdated(response.body().result);
                        } else {
                            passwordCallback.onPasswordUpdateFailed(new Exception(), "Please try again later.");
                        }
                    }

                    @Override
                    public void onFailure(Call<CallResponse<CareGiverData>> call, Throwable t) {
                        passwordCallback.onPasswordUpdateFailed(new Exception(), "Please try again later.");
                    }
                });

    }

    public void signOut(String token,
                        @NonNull CgHomeContracts.SignOutCallback signOutCallback) {
        dash_apiService.signOut(token)
                .enqueue(new Callback<CallResponse<Object>>() {
                    @Override
                    public void onResponse(Call<CallResponse<Object>> call, Response<CallResponse<Object>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200) {
                                signOutCallback.onSignOutFailed(new Exception(), response.body().message);
                                return;
                            }

                            signOutCallback.onSignOutSuccess();
                        } else {
                            signOutCallback.onSignOutFailed(new Exception(), "Please try again later.");
                        }
                    }

                    @Override
                    public void onFailure(Call<CallResponse<Object>> call, Throwable t) {
                        signOutCallback.onSignOutFailed(new Exception(), "Please try again later.");
                    }
                });
    }

}
