package com.gh.gamecenter.news;

import android.content.Context;
import android.content.Intent;
import android.support.v4.util.ArrayMap;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.android.volley.NoConnectionError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.DiskBasedCache;
import com.gh.base.AppController;
import com.gh.common.constant.Config;
import com.gh.common.util.ConcernUtils;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DisplayUtils;
import com.gh.common.util.GzipUtils;
import com.gh.common.util.ImageUtils;
import com.gh.common.util.MD5Utils;
import com.gh.common.util.TokenUtils;
import com.gh.common.util.Utils;
import com.gh.common.view.CardLinearLayout;
import com.gh.gamecenter.NewsDetailActivity;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.FooterViewHolder;
import com.gh.gamecenter.db.info.ConcernInfo;
import com.gh.gamecenter.entity.ConcernEntity;
import com.gh.gamecenter.listener.OnCallBackListener;
import com.gh.gamecenter.manager.ConcernManager;
import com.gh.gamecenter.manager.DataCollectionManager;
import com.gh.gamecenter.volley.extended.JsonArrayExtendedRequest;
import com.gh.gamecenter.volley.extended.JsonObjectExtendedRequest;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * Created by khy on 2016/8/15.
 */
public class News4FragmentAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private News4Fragment fragment;
    private Context context;
    private OnCallBackListener listener;

    private List<ConcernEntity> concernList;
    private ArrayMap<String, Integer> viewsMap;
    private List<String> urlList;
    private List<String> gameIdList;

    private String key;
    private String ids;

    private boolean isNetworkError;
    private boolean isRemove;
    private boolean isLoading;

    public News4FragmentAdapter(News4Fragment fragment, boolean isLoad) {
        this.fragment = fragment;
        this.context = fragment.getActivity();
        this.listener = fragment;

        concernList = new ArrayList<>();

        viewsMap = new ArrayMap<>();
        urlList = new ArrayList<>();

        isNetworkError = false;
        isRemove = false;
        isLoading = false;

        init(isLoad);
    }

    public void init(boolean isLoad) {
        gameIdList = new ArrayList<>();

        ConcernManager concernManager = new ConcernManager(context);
        List<ConcernInfo> concernList = concernManager.getConcernGame();
        if (concernList == null || concernList.isEmpty()) {
            listener.loadEmpty();
            return;
        }

        for (ConcernInfo concernInfo : concernList) {
            gameIdList.add(concernInfo.getId());
        }

        // 对数据进行排序
        Collections.sort(gameIdList, new Comparator<String>() {
            @Override
            public int compare(String lhs, String rhs) {
                return lhs.compareTo(rhs);
            }
        });

        StringBuilder concernKey = new StringBuilder();
        StringBuilder gameIdPostData = new StringBuilder();
        for (int i = 0; i < gameIdList.size(); i++) {
            concernKey.append(gameIdList.get(i));
            if (i < 5) {
                gameIdPostData.append(gameIdList.get(i));
                gameIdPostData.append("-");
            }
        }
        key = MD5Utils.getContentMD5(concernKey.toString());
        ids = gameIdPostData.substring(0, gameIdPostData.length() - 1);

        if (isLoad) {
            loadDataByKey(0);
        }
    }

    public void loadDataByKey(final int offset) {
        if (isLoading) {
            return;
        }
        isLoading = true;
        String url = Config.HOST + "v2d0/zixun/guanzhu?key=" + key + "&limit=10&offset=" + offset;
        JsonArrayExtendedRequest request= new JsonArrayExtendedRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        isLoading = false;
                        Type listType = new TypeToken<ArrayList<ConcernEntity>>() {}.getType();
                        Gson gson = new Gson();
                        List<ConcernEntity> list = gson.fromJson(response.toString(), listType);
                        if (list != null && list.size() != 0) {
                            concernList.addAll(list);
                            if (!fragment.isHidden() && !fragment.isEverpause()) {
                                notifyItemRangeInserted(concernList.size() - list.size(), list.size());
                            }

                            getNewsViews(list, offset);
                        }

                        if (fragment.isHidden() || fragment.isEverpause()) {
                            notifyDataSetChanged();
                        }

                        if (list == null || list.isEmpty() || (offset == 0 && list.size() < 10)) {
                            isRemove = true;
                            notifyItemChanged(getItemCount() - 1);
                        }

                        if (listener != null) {
                            listener.loadDone();
                        }

                        if (concernList.size() == 0){
                            listener.loadEmpty();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        isLoading = false;
                        if (error.networkResponse != null
                                && error.networkResponse.statusCode == HttpStatus.SC_CONFLICT) {
                            loadDataByGameId(offset);
                            updateConcern();
                        } else {
                            // 无网络连接和访问超时
                            if (error.getClass().equals(NoConnectionError.class)
                                    || error.getClass().equals(TimeoutError.class)) {
                                if (offset == 0) {
                                    if (listener != null) {
                                        listener.loadError();
                                    }
                                } else {
                                    Toast.makeText(context, "加载失败，请检查网络状态",
                                            Toast.LENGTH_SHORT).show();
                                    isNetworkError = true;
                                    notifyItemChanged(getItemCount() - 1);
                                }
                            }
                        }
                    }
                });
        AppController.addToRequestQueue(request, News4Fragment.TAG);
    }

    public void loadDataByGameId(final int offset) {
        if (isLoading) {
            return;
        }
        isLoading = true;
        String url = Config.HOST + "v2d0/zixun/guanzhu?game_id=" + ids + "&limit=10&offset=" + offset;
        JsonArrayExtendedRequest request= new JsonArrayExtendedRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        isLoading = false;
                        Type listType = new TypeToken<ArrayList<ConcernEntity>>() {}.getType();
                        Gson gson = new Gson();
                        List<ConcernEntity> list = gson.fromJson(response.toString(), listType);
                        if (list != null && list.size() != 0) {
                            concernList.addAll(list);
                            if (!fragment.isHidden() && !fragment.isEverpause()) {
                                notifyItemRangeInserted(concernList.size() - list.size(), list.size());
                            }

                            getNewsViews(list, offset);
                        }

                        if (fragment.isHidden() || fragment.isEverpause()) {
                            notifyDataSetChanged();
                        }

                        if (list == null || list.isEmpty() || (offset == 0 && list.size() < 10)) {
                            isRemove = true;
                            notifyItemChanged(getItemCount() - 1);
                        }

                        if (listener != null) {
                            listener.loadDone();
                        }

                        if (concernList.size() == 0){
                            listener.loadEmpty();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        isLoading = false;
                        // 无网络连接和访问超时
                        if (error.getClass().equals(NoConnectionError.class)
                                || error.getClass().equals(TimeoutError.class)) {
                            if (offset == 0) {
                                if (listener != null) {
                                    listener.loadError();
                                }
                            } else {
                                Toast.makeText(context, "加载失败，请检查网络状态",
                                        Toast.LENGTH_SHORT).show();
                                isNetworkError = true;
                                notifyItemChanged(getItemCount() - 1);
                            }
                        }
                    }
                });
        AppController.addToRequestQueue(request, News4Fragment.TAG);
    }

    public void updateConcern() {
        String uuid = TokenUtils.getDeviceId(context);
        ConcernUtils.updateConcernData(Config.HOST + "v2d0/device/" + uuid + "/concern",
                new JSONArray(gameIdList),
                new ConcernUtils.DownJsonListener() {
                    @Override
                    public void downSucced(String str) {
                        Utils.log("更新设备游戏成功");
                    }

                    @Override
                    public void downFailed() {
                        Utils.log("更新设备游戏失败");
                    }
                });
    }

    private void getNewsViews(final List<ConcernEntity> list, final int start) {
        if (list == null || list.isEmpty()) {
            return;
        }
        StringBuilder ids = new StringBuilder();
        for (int i = 0, size = list.size(); i < size; i++) {
            ids.append(list.get(i).getId());
            ids.append("-");
        }
        final String url = "http://data.ghzhushou.com/v1d46/news/" + ids.substring(0, ids.length() - 1) + "/visit";
        if (!urlList.contains(url)) {
            urlList.add(url);
        }
        JsonArrayExtendedRequest request = new JsonArrayExtendedRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Utils.log("response = " + response);
                        try {
                            JSONObject jsonObject;
                            for (int i = 0, size = response.length(); i < size; i++) {
                                jsonObject = response.getJSONObject(i);
                                viewsMap.put(jsonObject.getString("id"), jsonObject.getInt("views"));
                            }
                            notifyItemRangeChanged(start, start + list.size() - 1);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }, null);
        AppController.addToRequestQueue(request, News4Fragment.TAG);
    }

    private void statNewsViews(final String news_id, final int position) {
        String url = "http://data.ghzhushou.com/news/stat?news_id=" + news_id;
        JsonObjectExtendedRequest request = new JsonObjectExtendedRequest(
                Request.Method.POST, url,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            if ("success".equals(response.getString("status"))) {
                                Integer views = viewsMap.get(news_id);
                                if (views == null) {
                                    views = 0;
                                }
                                views += 1;
                                viewsMap.put(news_id, views);
                                notifyItemChanged(position);

                                //修改volley缓存
                                modifyVolleyCache(news_id);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }, null);
        request.setShouldCache(false);
        AppController.addToRequestQueue(request, News4Fragment.TAG);
    }

    private static final String DEFAULT_CACHE_DIR = "volley";

    private void modifyVolleyCache(String id) {
        String key = null;
        for (int i = 0, size = urlList.size(); i < size; i++) {
            if (urlList.get(i).contains(id)) {
                key = urlList.get(i);
                break;
            }
        }
        if (key == null) {
            return;
        }
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
        DiskBasedCache cache = new DiskBasedCache(cacheDir);
        byte[] data = cache.getData(key);
        if (data != null) {
            try {
                JSONArray jsonArray = new JSONArray(new String(GzipUtils.decompressBytes(data)));
                JSONObject jsonObject;
                for (int i = 0, size = jsonArray.length(); i < size; i++) {
                    jsonObject = jsonArray.getJSONObject(i);
                    if (jsonObject.getString("id").equals(id)) {
                        jsonObject.put("views", jsonObject.getInt("views") + 1);
                        break;
                    }
                }
                Utils.log(jsonArray.toString());
                cache.modify(key, GzipUtils.compressBytes(jsonArray.toString().getBytes()));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            Utils.log("modifyVolleyCache is null");
        }
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == concernList.size()){
            View view = LayoutInflater.from(parent.getContext()).
                    inflate(R.layout.refresh_footerview, parent, false);
            return new FooterViewHolder(view);
        } else {
            View view = LayoutInflater.from(context).
                    inflate(R.layout.concern_rv_item, parent, false);
            return new NewsConcernViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof NewsConcernViewHolder) {
            initConcernViewHolder((NewsConcernViewHolder) holder, position);
        } else if (holder instanceof FooterViewHolder) {
            initFooterViewHolder((FooterViewHolder) holder);
        }
    }

    private void initFooterViewHolder(FooterViewHolder viewHolder) {
        if (isNetworkError) {
            viewHolder.footerview_progressbar.setVisibility(View.GONE);
            viewHolder.footerview_tv_loading.setText("加载失败，点击重试");
            viewHolder.itemView.setClickable(true);
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    isNetworkError = false;
                    notifyItemChanged(getItemCount() - 1);
                    loadDataByKey(concernList.size());
                }
            });

        } else if (isRemove) {
            viewHolder.footerview_progressbar.setVisibility(View.GONE);
            viewHolder.footerview_tv_loading.setText("加载完毕");
            viewHolder.itemView.setClickable(false);
        } else {
            viewHolder.footerview_progressbar.setVisibility(View.VISIBLE);
            viewHolder.footerview_tv_loading.setText("加载中...");
            viewHolder.itemView.setClickable(false);
        }
    }

    private void initConcernViewHolder(final NewsConcernViewHolder viewHolder, int position) {
        // 第一个
        if (position == 0) {
            ((CardLinearLayout) viewHolder.itemView).setmTop(DisplayUtils.dip2px(context, 8));
        } else {
            ((CardLinearLayout) viewHolder.itemView).setmTop(0);
        }

        // 最后一个
        if (position == concernList.size() - 1) {
            ((CardLinearLayout) viewHolder.itemView).setBottom(true);
        } else {
            ((CardLinearLayout) viewHolder.itemView).setBottom(false);
        }

        final ConcernEntity concernEntity = concernList.get(position);

        if (concernEntity.getImg().size() == 0) {
            viewHolder.contentPicLl.setVisibility(View.GONE);
        } else {
            viewHolder.contentPicLl.setVisibility(View.VISIBLE);
            addContentPic(context.getResources().getDisplayMetrics().widthPixels
                    - DisplayUtils.dip2px(context, 34), viewHolder.contentPicLl, concernEntity.getImg());
        }

        ImageUtils.getInstance(context).display(concernEntity.getGameIcon(), viewHolder.concernThumb);
        viewHolder.concernContent.setText(Html.fromHtml(concernEntity.getContent()));
        viewHolder.concernTitle.setText(concernEntity.getGameName());
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());

        try {
            long today = format.parse(format.format(new Date())).getTime();
            long day = Long.valueOf(concernEntity.getTime() + "000");
            if (day >= today && day < today + 86400 * 1000) {
                format.applyPattern("HH:mm");
                viewHolder.concerntTime.setText("今天 " + format.format(day));
            } else if (day >= today - 86400 * 1000 && day < today) {
                format.applyPattern("HH:mm");
                viewHolder.concerntTime.setText("昨天 " + format.format(day));
            } else {
                format.applyPattern("yyyy年MM月dd日 HH:mm");
                viewHolder.concerntTime.setText(format.format(day));
            }
        } catch (ParseException e) {
            e.printStackTrace();
            format.applyPattern("yyyy年MM月dd日 HH:mm");
            viewHolder.concerntTime.setText(format.format(Long.valueOf(concernEntity.getTime() + "000")));
        }

        Integer views = viewsMap.get(concernEntity.getId());
        if (views == null) {
            viewHolder.concernRead.setVisibility(View.GONE);
        } else {
            viewHolder.concernRead.setVisibility(View.VISIBLE);
            viewHolder.concernRead.setText("阅读  " + views);
        }

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Map<String, Object> kv = new HashMap<>();
                kv.put("名字", concernEntity.getTitle());
                kv.put("位置", String.valueOf(viewHolder.getPosition() + 1));
                DataUtils.onEvent(context, "点击", "资讯-关注", kv);

                Map<String, Object> map = new HashMap<>();
                map.put("location", "列表");
                map.put("page", "资讯-关注");
                map.put("news", concernEntity.getTitle());
                map.put("news_id", concernEntity.getId());
                DataCollectionManager.onEvent(context, "click-item", map);

                //统计阅读量
                statNewsViews(concernEntity.getId(), viewHolder.getPosition());

                Intent intent = new Intent(context, NewsDetailActivity.class);
                intent.putExtra("newsId", concernEntity.getId());
                intent.putExtra("entrance", "(资讯-关注)");
                context.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() {
        if (concernList.isEmpty()){
            return 0;
        }
        return concernList.size() + 1;
    }

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

    public boolean isNetworkError() {
        return isNetworkError;
    }

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

    public boolean isRemove() {
        return isRemove;
    }

    public boolean isLoading() {
        return isLoading;
    }

    private void addContentPic(int width, LinearLayout linearLayout, List<String> list) {
        int allSize = list.size();
        LinearLayout ll;
        ImageView imageView;
        int index = 0;
        linearLayout.removeAllViews();
        for (int i = 0; i < Math.ceil(list.size() / 3.0); i++) {
            switch (allSize % 3) {
                case 1:
                    ll = new LinearLayout(context);
                    ll.setOrientation(LinearLayout.HORIZONTAL);
                    ll.removeAllViews();
                    imageView = new ImageView(context);
                    imageView.setLayoutParams(new ViewGroup.LayoutParams(width, width / 2));
                    ImageUtils.getInstance(context).display(list.get(index), imageView, ImageView.ScaleType.CENTER_CROP);
                    ll.addView(imageView);
                    ll.setPadding(DisplayUtils.dip2px(context, 2), 0, DisplayUtils.dip2px(context, 2), DisplayUtils.dip2px(context, 4));
                    linearLayout.addView(ll);
                    allSize = allSize - 1;
                    index = index + 1;
                    break;
                case 2:
                    ll = new LinearLayout(context);
                    ll.setOrientation(LinearLayout.HORIZONTAL);
                    ll.removeAllViews();
                    for (int j = 0; j < list.size() % 3; j++) {
                        imageView = new ImageView(context);
                        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, width / 2 - DisplayUtils.dip2px(context, 4));
                        layoutParams.setMargins(DisplayUtils.dip2px(context, 2), 0, DisplayUtils.dip2px(context, 2), DisplayUtils.dip2px(context, 4));
                        layoutParams.weight = 1;
                        imageView.setLayoutParams(layoutParams);
                        ImageUtils.getInstance(context).display(list.get(index), imageView, ImageView.ScaleType.CENTER_CROP);
                        ll.addView(imageView);
                        index = index + 1;
                    }
                    linearLayout.addView(ll);
                    allSize = allSize - 2;

                    break;
                case 0:
                    ll = new LinearLayout(context);
                    ll.setOrientation(LinearLayout.HORIZONTAL);
                    ll.removeAllViews();
                    for (int j = 0; j < 3; j++) {
                        imageView = new ImageView(context);
                        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, width / 3 - DisplayUtils.dip2px(context, 4));
                        layoutParams.setMargins(DisplayUtils.dip2px(context, 2), 0, DisplayUtils.dip2px(context, 2), DisplayUtils.dip2px(context, 4));
                        layoutParams.weight = 1;
                        imageView.setLayoutParams(layoutParams);
                        ImageUtils.getInstance(context).display(list.get(index), imageView, ImageView.ScaleType.CENTER_CROP);
                        ll.addView(imageView);
                        index = index + 1;
                    }
                    linearLayout.addView(ll);
                    allSize = allSize - 3;
                    break;
            }
        }
    }

}
