package com.gh.gamecenter.message.view.concern;

import android.content.Context;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;

import androidx.recyclerview.widget.RecyclerView.ViewHolder;

import com.therouter.TheRouter;
import com.gh.gamecenter.common.callback.OnListClickListener;
import com.gh.gamecenter.common.callback.OnRequestCallBackListener;
import com.gh.gamecenter.common.constant.ItemViewType;
import com.gh.gamecenter.common.constant.RouteConsts;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.common.retrofit.ObservableUtil;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.viewholder.FooterViewHolder;
import com.gh.gamecenter.core.provider.ICommentManagerProvider;
import com.gh.gamecenter.core.provider.IConcernArticleUtilsProvider;
import com.gh.gamecenter.core.provider.IConcernGiftPackUtilsProvider;
import com.gh.gamecenter.core.provider.ILibaoUtilsProvider;
import com.gh.gamecenter.core.provider.IVisitManagerProvider;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.feature.entity.CommentnumEntity;
import com.gh.gamecenter.feature.entity.ConcernEntity;
import com.gh.gamecenter.feature.entity.LibaoStatusEntity;
import com.gh.gamecenter.feature.entity.MeEntity;
import com.gh.gamecenter.feature.entity.UserDataLibaoEntity;
import com.gh.gamecenter.feature.entity.ViewsEntity;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.message.retrofit.RetrofitManager;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.Utils;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;

/**
 * Created by khy on 2016/8/15.
 * 资讯-关注-数据适配器
 */
class ConcernAdapter extends BaseRecyclerAdapter<ViewHolder> {

    private OnRequestCallBackListener listener;
    private OnListClickListener mListListener;

    private OnConcernContentEventListener contentEventListener;

    private List<ConcernEntity> concernList;

    private List<LibaoStatusEntity> libaoStatusList;

    private int itemCount;
    private int skipPosition;

    private boolean isLoading;
    private boolean isOver;
    private boolean isNetworkError;

    private int mPage;

    ConcernAdapter(Context context, OnRequestCallBackListener listener, OnListClickListener mistListener, OnConcernContentEventListener articleEventListener) {
        super(context);
        this.listener = listener;
        this.mListListener = mistListener;
        this.contentEventListener = articleEventListener;

        concernList = new ArrayList<>();
        libaoStatusList = new ArrayList<>();

        itemCount = 0;
        skipPosition = -1;
        mPage = 1;

        isNetworkError = false;
        isOver = false;
        isLoading = false;
        addList();
    }

    // 加载数据
    public void addList() {
        if (isLoading) {
            return;
        }

        if (TextUtils.isEmpty(UserManager.getInstance().getToken())) {
            isLoading = true;
            listener.loadEmpty();
            return;
        }
        isLoading = true;
        notifyItemChanged(getItemCount() - 1);
        RetrofitManager.Companion.getInstance().getApi()
                .getZiXunConcern(UserManager.getInstance().getUserId(), mPage)
                .map(list -> removeDuplicateData(concernList, list))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Response<List<ConcernEntity>>() {
                    @Override
                    public void onResponse(List<ConcernEntity> response) {
                        if (response.size() != 0) {
                            concernList.addAll(response);
                            itemCount += response.size();
                            notifyItemRangeInserted(concernList.size() - response.size(), response.size());

                            getLibaoStatus(response);
                            getNewsViews(response);
                            getNewsCommentnum(response);

                        } else {
                            isOver = true;
                            if (getItemCount() > 0) {
                                notifyItemChanged(getItemCount() - 1);
                            } else {
                                notifyDataSetChanged();
                            }

                        }

                        if (mPage == 1 && listener != null) {
                            if (concernList.isEmpty()) {
                                listener.loadEmpty();
                            } else {
                                listener.loadDone();
                            }
                        }

                        isLoading = false;
                        mPage++;
                    }

                    @Override
                    public void onFailure(HttpException e) {
                        isLoading = false;

                        // 网络错误
                        if (mPage == 1) {
                            if (listener != null) {
                                listener.loadError();
                            }
                        } else {
                            Utils.toast(mContext, com.gh.gamecenter.feature.R.string.loading_failed_hint);
                            isNetworkError = true;
                            notifyItemChanged(getItemCount() - 1);
                        }
                    }
                });
    }

    // 去除重复数据
    private static List<ConcernEntity> removeDuplicateData(List<ConcernEntity> sourceList, List<ConcernEntity> rawList) {
        if (sourceList == null || sourceList.isEmpty()
                || rawList == null || rawList.isEmpty()) {
            return rawList;
        }
        String id;
        for (int i = 0; i < rawList.size(); i++) {
            id = rawList.get(i).getId();
            for (ConcernEntity concernEntity : sourceList) {
                if (id.equals(concernEntity.getId())) {
                    rawList.remove(i);
                    i--;
                    break;
                }
            }
        }
        return rawList;
    }

    //获取礼包状态
    private void getLibaoStatus(List<ConcernEntity> response) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0, size = response.size(); i < size; i++) {
            if ("libao".equals(response.get(i).getType())) {
                builder.append(response.get(i).getId());
                builder.append("-");
            }
        }
        if (builder.length() == 0) return;
        builder.deleteCharAt(builder.length() - 1);
        String ids = builder.toString();

        ILibaoUtilsProvider libaoUtilsProvider = TheRouter.get(ILibaoUtilsProvider.class);
        libaoUtilsProvider.getLibaoStatus(ids, list -> {
            libaoStatusList.addAll((List<LibaoStatusEntity>) list);
            notifyItemRangeChanged(0, getItemCount());
            return null;
        }, null);
    }

    // 获取新闻阅读量
    private void getNewsViews(final List<ConcernEntity> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        ObservableUtil.computation(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) {
                StringBuilder builder = new StringBuilder();
                for (int i = 0, size = list.size(); i < size; i++) {
                    builder.append(list.get(i).getId());
                    builder.append("-");
                }
                builder.deleteCharAt(builder.length() - 1);
                String ids = builder.toString();
                IVisitManagerProvider visitManagerProvider = TheRouter.get(IVisitManagerProvider.class);
                if (visitManagerProvider != null) {
                    visitManagerProvider.addUrl(ids);
                }
                emitter.onNext(ids);
                emitter.onComplete();
            }

        }, new Consumer<String>() {
            @Override
            public void accept(String s) {
                RetrofitManager.Companion.getInstance().getApi()
                        .getArticlesVisits(UrlFilterUtils.getFilterQuery("article_ids", s))
                        .map((Function<List<ViewsEntity>, String>) list1 -> {
                            for (ViewsEntity viewsEntity : list1) {
                                for (ConcernEntity concernEntity : concernList) {
                                    if (viewsEntity.getId().equals(concernEntity.getId())) {
                                        concernEntity.setViews(viewsEntity.getViews());
                                        break;
                                    }
                                }
                            }
                            return "";
                        })
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Response<String>() {
                            @Override
                            public void onResponse(String response) {
                                notifyItemRangeChanged(0, getItemCount());
                            }
                        });
            }
        });
    }

    // 获取新闻评论数
    public void getNewsCommentnum(final List<ConcernEntity> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        ObservableUtil.computation(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) {
                StringBuilder builder = new StringBuilder();
                for (int i = 0, size = list.size(); i < size; i++) {
                    builder.append(list.get(i).getId());
                    builder.append("-");
                }
                builder.deleteCharAt(builder.length() - 1);
                ICommentManagerProvider commentManager = TheRouter.get(ICommentManagerProvider.class);
                if (commentManager != null) {
                    commentManager.addUrl(builder.toString());
                }
                emitter.onNext(builder.toString());
                emitter.onComplete();
            }
        }, new Consumer<String>() {
            @Override
            public void accept(String ids) throws Exception {
                RetrofitManager.Companion.getInstance().getApi()
                        .getNewsCommentnum(ids, Utils.getTime(mContext))
                        .map(new Function<List<CommentnumEntity>, String>() {
                            @Override
                            public String apply(List<CommentnumEntity> list) {
                                for (CommentnumEntity commentnumEntity : list) {
                                    for (ConcernEntity concernEntity : concernList) {
                                        if (commentnumEntity.getId().equals(concernEntity.getId())) {
                                            concernEntity.setCommentnum(commentnumEntity.getNum());
                                            break;
                                        }
                                    }
                                }
                                return "";
                            }
                        })
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Response<String>() {
                            @Override
                            public void onResponse(String response) {
                                notifyItemRangeChanged(0, getItemCount());
                            }
                        });
            }
        });
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case ItemViewType.NEWS_DIGEST:
                IConcernGiftPackUtilsProvider giftPackUtilsProvider = TheRouter.get(IConcernGiftPackUtilsProvider.class);
                if (giftPackUtilsProvider != null) {
                    return new ConcernGiftPackViewHolder(giftPackUtilsProvider.createBinding(parent), giftPackUtilsProvider, contentEventListener);
                } else {
                    View view = mLayoutInflater.inflate(com.gh.gamecenter.common.R.layout.refresh_footerview, parent, false);
                    return new FooterViewHolder(view);
                }
            case ItemViewType.GAME_ARTICLE:
                IConcernArticleUtilsProvider concernContentUtilsProvider =TheRouter.get(IConcernArticleUtilsProvider.class);
                if (concernContentUtilsProvider != null) {
                    return new ConcernArticleViewHolder(concernContentUtilsProvider.createArticleBinding(parent), concernContentUtilsProvider, contentEventListener);
                }
            default:
                View view = mLayoutInflater.inflate(com.gh.gamecenter.common.R.layout.refresh_footerview, parent, false);
                return new FooterViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if (holder instanceof ConcernGiftPackViewHolder) {
            initNewsDigestViewHolder((ConcernGiftPackViewHolder) holder, position);
        } else if (holder instanceof FooterViewHolder) {
            initFooterViewHolder((FooterViewHolder) holder);
        } else if (holder instanceof ConcernArticleViewHolder) {
            initArticleConcernViewHolder((ConcernArticleViewHolder) holder, position);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (position == concernList.size()) {
            return ItemViewType.LOADING;
        } else {
            ConcernEntity item = concernList.get(position);
            if ("libao".equals(item.getType())) {
                return ItemViewType.NEWS_DIGEST;
            } else {
                return ItemViewType.GAME_ARTICLE;
            }

        }
    }

    @Override
    public int getItemCount() {
        if (itemCount == 0) {
            return 0;
        }
        return itemCount + 1;
    }

    private void initArticleConcernViewHolder(ConcernArticleViewHolder holder, int position) {
        IConcernArticleUtilsProvider concernContentUtilsProvider = TheRouter.get(IConcernArticleUtilsProvider.class);
        if (concernContentUtilsProvider == null) {
            return;
        }
        final ConcernEntity concernEntity = concernList.get(position);
        holder.bind(concernEntity, position);
    }

    private void initNewsDigestViewHolder(final ConcernGiftPackViewHolder viewHolder, int position) {
        final ConcernEntity concernEntity = concernList.get(position);
        viewHolder.bind(concernEntity, position);
        viewHolder.setClickData(concernEntity);

        for (LibaoStatusEntity libaoStatusEntity : libaoStatusList) {
            if (TextUtils.isEmpty(libaoStatusEntity.getBeforeStatus())) {
                libaoStatusEntity.setBeforeStatus(libaoStatusEntity.getStatus());
            }
            if (libaoStatusEntity.getId().equals(concernEntity.getId())) {
                MeEntity userData = concernEntity.getMe();
                if (userData != null && userData.getUserDataLibaoList() != null && userData.getUserDataLibaoList().size() > 0) {
                    List<UserDataLibaoEntity> userDataLibaoList = userData.getUserDataLibaoList();
                    UserDataLibaoEntity userDataLibaoEntity = userDataLibaoList.get(userDataLibaoList.size() - 1);
                    libaoStatusEntity.setBeforeStatus(libaoStatusEntity.getStatus());
                    libaoStatusEntity.setCode(userDataLibaoEntity.getCode());
                }
            }
        }


    }

    private void initFooterViewHolder(FooterViewHolder viewHolder) {
        viewHolder.initItemPadding();
        viewHolder.initFooterViewHolder(isLoading, isNetworkError, isOver, v -> {
            if (isNetworkError) {
                isNetworkError = false;
                notifyItemChanged(getItemCount() - 1);
                addList();
            }
        });
    }

    // 统计新闻阅读量
    public void statNewsViews(final ConcernEntity concernEntity, final int position) {
        RetrofitManager.Companion.getInstance().getApi().postArticleVisit(concernEntity.getId())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new JSONObjectResponse() {
                    @Override
                    public void onResponse(JSONObject response) {
                        if (response.length() != 0) {
                            try {
                                if ("success".equals(response.getString("status"))) {
                                    concernEntity.setViews(concernEntity.getViews() + 1);

                                    notifyItemChanged(position);

                                    // 更新okhttp缓存数据
                                    IVisitManagerProvider visitManagerProvider = TheRouter.get(IVisitManagerProvider.class);
                                    if (visitManagerProvider != null && concernEntity.getId() != null) {
                                        visitManagerProvider.updateOkhttpCache(mContext, concernEntity.getId());
                                    }
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
    }


    public int getConcernListSize() {
        return concernList.size();
    }

    public ConcernEntity getSkipEntity() {
        if (skipPosition != -1) {
            return concernList.get(skipPosition);
        }
        return null;
    }

    public List<ConcernEntity> getConcernList() {
        return concernList;
    }

    public List<LibaoStatusEntity> getLibaoStatusList() {
        return libaoStatusList;
    }

    public boolean isNetworkError() {
        return isNetworkError;
    }

    public void setNetworkError(boolean networkError) {
        isNetworkError = networkError;
    }

    public boolean isOver() {
        return isOver;
    }

    public boolean isLoading() {
        return isLoading;
    }

    public int getSkipPosition() {
        return skipPosition;
    }

    public void setSkipPosition(int skipPosition) {
        this.skipPosition = skipPosition;
    }


}
