package com.vpn.fastestvpnservice.retrofit;

import android.content.Context;
import android.view.View;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.vpn.fastestvpnservice.R;
import com.vpn.fastestvpnservice.application.App;
import com.vpn.fastestvpnservice.helpers.BasePreferenceHelper;
import com.vpn.fastestvpnservice.helpers.UIHelper;
import com.vpn.fastestvpnservice.utils.CheckInternetConnection;

import java.lang.reflect.Type;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;


public class RetrofitNetworkHandling<T> implements Callback<T> {

    private final Context context;
    private View view;
    private final ResponseCallback<T> listener;

    public RetrofitNetworkHandling(ResponseCallback<T> listener) {
        this.context = App.getApplication();
        this.listener = listener;
    }

    public RetrofitNetworkHandling(View view, ResponseCallback<T> listener) {
        this.context = App.getApplication();
        this.view = view;
        this.listener = listener;
    }

    @Override
    public void onResponse(Call<T> call, Response<T> response) {
        //TODO mainactivity- check this loading finish for possible exceptions

        if (!CheckInternetConnection.getInternetConnection(context).isConnectedToInternet()) {
            UIHelper.showToast(R.string.chk_internet_connectivity);
            return;
        }

        if (response.headers().get("auth-token") != null && !response.headers().get("auth-token").equals("")) {
            BasePreferenceHelper prefHelper = new BasePreferenceHelper(context.getApplicationContext());
//            prefHelper.putAccessToken(response.headers().get("auth-token"));
        }

        if (view != null) {
            view.setEnabled(true);
        }

        switch (response.code()) {
            case HttpURLConnection.HTTP_OK:
            case HttpURLConnection.HTTP_ACCEPTED:
                /**In Successful Response**/
                listener.onSuccess(call, response.body());
                break;

            case HttpURLConnection.HTTP_UNAUTHORIZED:

                //Session Timeout
                try {
                    if (context != null) {
                        WebResponse errorResponse = new WebResponse();
                        errorResponse.setMessage("Session Time Out");
                        listener.onFail(call, (T) errorResponse);
                        //UIHelper.showToast(((WebResponse) response.body()).getMessage());
                        //((MainActivity) context).getFragmentNavigator().clearAllFragments();
                        // ((MainActivity)context).addDockableFragment(LoginFragment.newInstance());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                break;
            case HttpURLConnection.HTTP_FORBIDDEN:
                /**In Authentication **/
                try {

                    final String string = response.errorBody().string();
                    Type collectionType = new TypeToken<WebResponse<T>>() {
                    }.getType();

                    final WebResponse<T> o = new Gson().fromJson(string, collectionType);
                    listener.onFail(call, (T) o);


                } catch (Exception e) {
                    e.printStackTrace();
                    WebResponse errorResponse = new WebResponse();
//                    errorResponse.setMessage("Please try again...");
                    listener.onError(call, (T) errorResponse);
                }

                break;

            default:
                /**In Authentication **/
                try {
                    listener.onFail(call, (T) response);

                } catch (Exception e) {
                    e.printStackTrace();

                    WebResponse errorResponse = new WebResponse();
                    errorResponse.setMessage("Please try again...");
                    listener.onError(call, (T) errorResponse);
                }
                break;
        }
    }

    @Override
    public void onFailure(Call<T> call, Throwable t) {
        t.printStackTrace();

        if (!CheckInternetConnection.getInternetConnection(context).isConnectedToInternet()) {
            UIHelper.showToast(R.string.chk_internet_connectivity);
            return;
        }

        WebResponse errorResponse = new WebResponse();
//        errorResponse.setMessage("Please try again...");

        try {
            if (context != null) {
                //Todo UI Action If Needed

                if (view != null) {
                    view.setEnabled(true);
                }
                listener.onFail(call, (T) errorResponse);
            }

        } catch (ClassCastException cce) {
            cce.printStackTrace();
            //listener.onError(call, (T) errorResponse);
        }

        //Log.e("Retrofit Connection Error ",arg0.getMessage()+"");
        if (t.getCause() instanceof SocketTimeoutException) {
            UIHelper.showToast("Connection Timeout");
        } else if (t.getCause() instanceof ConnectException) {
//            UIHelper.showToast("No Internet Connection");
        } else if (t.getCause() instanceof UnknownHostException) {
//            UIHelper.showToast("Check internet connection or try again!");
        } else {
//            UIHelper.showLongToastInCenter(context, "Problem occurred");
        }
    }


    public interface ResponseCallback<T> {
        void onSuccess(Call<T> call, T response);

        void onFail(Call<T> call, T response);

        void onError(Call<T> call, T response);


    }
}