package com.seatel.mobilehall.ui.base.adapter;

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

import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.android.volley.NoConnectionError;
import com.android.volley.Response;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.seatel.mobilehall.R;
import com.seatel.mobilehall.data.network.SeatelJSONObjectRequest;
import com.seatel.mobilehall.util.customview.ErrorHandleView;

import org.json.JSONObject;

import java.util.HashMap;


/**
 * Created by Danny on 1/25/2018.
 */

public abstract class BaseCartAdapter extends RecyclerView.Adapter {

    private Context context;
    private final ErrorHandleView errorHandleView;
    private int offset = 0;
    private boolean isLoadingData;
    private boolean isDone;
    private OnDataResponse onDataResponse;
    private RecyclerView mRecyclerView;

    public BaseCartAdapter(Context context, ErrorHandleView errorHandleView) {
        setContext(context);
        this.errorHandleView = errorHandleView;
    }

    public BaseCartAdapter(Context context, ErrorHandleView errorHandleView, RecyclerView recyclerView, final SwipeRefreshLayout swipeRefreshLayout) {
        this(context, errorHandleView);
        if (swipeRefreshLayout != null) {
            swipeRefreshLayout.setColorSchemeColors(ContextCompat.getColor(context, R.color.colorPrimary));
            swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    setOffset(0);
                    onRequestData(onDataResponse);
                    swipeRefreshLayout.setRefreshing(false);
                }
            });
        }
        mRecyclerView = recyclerView;
        if (recyclerView != null) {
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    int lastVisibleItem;
                    lastVisibleItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition();
                    if (!isLoadingData && lastVisibleItem > getItemCount() - 5 && !isDone) {
                        setOffset(getItemCount());
                        onRequestData(onDataResponse);
                    }
                }
            });
        }
    }


    public void onReloadData() {
        setOffset(0);
        onRequestData(onDataResponse);
    }

    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    public int getOffset() {
        return offset;
    }

    public void setOffset(int offset) {
        this.offset = offset;
    }


    /**
     * call this function need to override getUrlRequestFunctionName()
     */
    public void onRequestData(final OnDataResponse onDataResponse) {
        this.onDataResponse = onDataResponse;
        setDone(false);
        isLoadingData = true;
        if (errorHandleView != null)
            errorHandleView.setViewMode(ErrorHandleView.Mode.LOADING);
        new SeatelJSONObjectRequest(getContext()) {
            @Override
            public String getFunctionName() {
                return getUrlRequestFunctionName();
            }

            @Override
            public void onGetUrlParams(RequestParams requestParams) {
                requestParams.put("limit", getLimit());
                requestParams.put("offset", offset);
                HashMap<String, String> tmpParams = new HashMap<>();
                getRequestParams(tmpParams);
                for (String key : tmpParams.keySet()) {
                    requestParams.put(key, tmpParams.get(key));
                }
                super.onGetUrlParams(requestParams);
            }
        }.setOnErrorListener(new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                isLoadingData = false;
                setDone(true);
                if (errorHandleView != null) {
                    if (mRecyclerView != null) {
                        mRecyclerView.setVisibility(View.INVISIBLE);
                    }
                    if (error instanceof NoConnectionError)
                        errorHandleView.setViewMode(ErrorHandleView.Mode.NO_INTERNET);
                    else if (error instanceof TimeoutError)
                        errorHandleView.setViewMode(ErrorHandleView.Mode.TIME_OUT);
                    else {
                        if (offset == 0) {
                            errorHandleView.setErrorMessage(context.getString(R.string.no_item_on_my_cart));
                            errorHandleView.setViewMode(ErrorHandleView.Mode.NO_DATA);
                        } else errorHandleView.setVisibility(View.GONE);
                    }
                } else {
                    if (offset == 0) {
                        errorHandleView.setErrorMessage(context.getString(R.string.no_item_on_my_cart));
                        errorHandleView.setViewMode(ErrorHandleView.Mode.NO_DATA);
                    } else errorHandleView.setVisibility(View.GONE);

                }
            }
        }).execute(new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                isLoadingData = false;
                onDataResponse.onResponse(response);
                if (errorHandleView != null)
                    if (getItemCount() == 0 && isDone) {
                        errorHandleView.setErrorMessage(context.getString(R.string.no_item_on_my_cart));
                        errorHandleView.setViewMode(ErrorHandleView.Mode.NO_DATA);
                    } else {
                        if (mRecyclerView != null) {
                            mRecyclerView.setVisibility(View.VISIBLE);
                        }
                        errorHandleView.setVisibility(View.GONE);
                    }
            }
        });
    }

    public abstract String getUrlRequestFunctionName();

    public void getRequestParams(HashMap<String, String> params) {
    }

    /**
     * if your adapter need load more data you need to call this function to true when data response < getLimit()
     *
     * @param done if true not load data anymore
     */
    public void setDone(boolean done) {
        isDone = done;
    }

    public int getLimit() {
        return 20;
    }

    public interface OnDataResponse {
        void onResponse(JSONObject onResponse);
    }
}
