package com.app.simplitend.cg_subscription.mvp;

import androidx.annotation.NonNull;

import com.app.simplitend.apputils.RetrofitHelper;
import com.app.simplitend.cg_subscription.SubscriptionPlan;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.CallResponse;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

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

public class SubscriptionPresenter {

    private static SubscriptionPresenter presenter;

    private final SubscriptionApiService apiService;

    private SubscriptionPresenter() {
        apiService = RetrofitHelper.getRetrofit().create(SubscriptionApiService.class);
    }

    public static synchronized SubscriptionPresenter getPresenter() {
        if (presenter == null) {
            presenter = new SubscriptionPresenter();
        }

        return presenter;
    }

    public void getSubscriptionPlans(@NonNull String token, @NonNull SubscriptionContracts.GetSubPlansCallback subPlansCallback) {
        apiService.getSubscriptionPlans(token)
                .enqueue(new Callback<CallResponse<ArrayList<SubscriptionPlan>>>() {
                    @Override
                    public void onResponse(Call<CallResponse<ArrayList<SubscriptionPlan>>> call, Response<CallResponse<ArrayList<SubscriptionPlan>>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200 || response.body().result == null) {
                                subPlansCallback.onSubsFetchFailed(new Exception(), response.body().message);
                                return;
                            }

                            subPlansCallback.onSubscriptionFetched(response.body().result);
                        } else {
                            subPlansCallback.onSubsFetchFailed(new Exception(), "Please try again later.");
                        }
                    }

                    @Override
                    public void onFailure(Call<CallResponse<ArrayList<SubscriptionPlan>>> call, Throwable t) {
                        subPlansCallback.onSubsFetchFailed(new Exception(), "Please try again later.");
                    }
                });
    }

    public void getPaymentCred(@NonNull String token,
                               Map<String, RequestBody> body,
                               @NonNull SubscriptionContracts.PaySubscriptionCallback paySubscriptionCallback) {

        apiService.paySubscription(token, body)
                .enqueue(new Callback<CallResponse<SubscriptionCredentials>>() {
                    @Override
                    public void onResponse(Call<CallResponse<SubscriptionCredentials>> call, Response<CallResponse<SubscriptionCredentials>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200 || response.body().result == null) {
                                paySubscriptionCallback.onPaymentCredFetchFailed(new Exception(), response.body().message);
                                return;
                            }

                            paySubscriptionCallback.onPaymentCredFetched(response.body().result);
                        } else {
                            paySubscriptionCallback.onPaymentCredFetchFailed(new Exception(), "Please try again later.");
                        }
                    }

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

    }

    public void createSubscription(Map<String, RequestBody> bodyMap,
                                   @NonNull String token,
                                   @NonNull SubscriptionContracts.CreateSubscriptionCallback createSubscriptionCallback) {
        apiService.createSubscription(token, bodyMap)
                .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) {
                                createSubscriptionCallback.onSubscriptionCreateFailed(new Exception(), response.body().message);
                                return;
                            }

                            createSubscriptionCallback.onSubscriptionCreated();
                        } else {
                            createSubscriptionCallback.onSubscriptionCreateFailed(new Exception(), "Please try again later.");
                        }
                    }

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

    public void getCurrentSubscriptionPlan(long c_id,
                                           @NonNull String token,
                                           @NonNull SubscriptionContracts.GetCurrentPlanCallback callback) {
        apiService.getCurrentPlan(c_id, token)
                .enqueue(new Callback<CallResponse<CurrentPlan>>() {
                    @Override
                    public void onResponse(Call<CallResponse<CurrentPlan>> call, Response<CallResponse<CurrentPlan>> response) {
                        if (response.body() != null) {
                            if (response.body().status != 200 || response.body().error_code == 1 || response.body().result == null) {
                                callback.failedCurrentPlan(new Exception(), response.body().message);
                                return;
                            }

                            callback.currentPlan(response.body().result);
                        } else {
                            callback.failedCurrentPlan(new Exception(), "Please try again later.");
                        }
                    }

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

    public void cancelSubscription(@NonNull String subscriptionId,
                                   String token,
                                   @NonNull SubscriptionContracts.CancelSubscriptionCallback callback) {

        Map<String, String> body = new HashMap<>();
        body.put("subscription_id", subscriptionId);

        apiService.cancelSubscription(body,
                "Bearer " + token).enqueue(new Callback<CallResponse<CurrentPlan>>() {
            @Override
            public void onResponse(Call<CallResponse<CurrentPlan>> call, Response<CallResponse<CurrentPlan>> response) {
                if (response.body() != null) {
                    if (response.body().status != 200 || response.body().error_code == 1 || response.body().result == null) {
                        callback.subscriptionCancelFailed(new Exception(), response.body().message);
                        return;
                    }

                    callback.subscriptionCancelled(response.body().result);
                } else {
                    callback.subscriptionCancelFailed(new Exception(), "Please try again later.");
                }
            }

            @Override
            public void onFailure(Call<CallResponse<CurrentPlan>> call, Throwable t) {
                callback.subscriptionCancelFailed(new Exception(), t.getLocalizedMessage());
            }
        });

    }

}
