package com.yiyuanliu.flipgank.adapter;

import android.content.Context;
import android.support.design.widget.BottomSheetDialog;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.yiyuanliu.flipgank.R;
import com.yiyuanliu.flipgank.activity.GankViewActivity;
import com.yiyuanliu.flipgank.data.DataManager;
import com.yiyuanliu.flipgank.data.GankItem;
import com.yiyuanliu.flipgank.view.GankItemView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import butterknife.BindView;
import butterknife.BindViews;
import butterknife.ButterKnife;

/**
 * Created by YiyuanLiu on 2016/12/17.
 */
public class GankAdapter extends RecyclerView.Adapter implements GankItemView.Listener {

    private static final String TAG = "GankAdapter";

    private List<Page> pageList = new ArrayList<>();
    private List<GankItem> gankItems = new ArrayList<>();

    private Listener mListener;
    private Context mContext;
    private boolean mHasMore = true;

    public GankAdapter(Context context,Listener listener) {
        mListener = listener;
        mContext = context;
    }

    public void setHasMore(boolean hasMore) {
        if (mHasMore == hasMore) {
            return;
        }
        mHasMore = hasMore;
        notifyItemChanged(getItemCount() - 1);
    }

    public void clear() {
        int size = pageList.size();
        pageList.clear();
        gankItems.clear();
        notifyItemRangeRemoved(0, size);
    }

    public void addData(List<GankItem> gankItemList) {
        gankItemList.addAll(gankItems);
        gankItems.clear();

        FirstPage bigImagePage = FirstPage.gen(gankItemList);
        if (bigImagePage != null) {
            pageList.add(bigImagePage);
            notifyItemInserted(pageList.size() - 1);
        }

        while (gankItemList.size() / 4 != 0) {
            NormalPage normal = NormalPage.gen(gankItemList);
            pageList.add(normal);
            notifyItemInserted(pageList.size() - 1);
        }

        if (gankItemList.size() != 0) {
            gankItems.addAll(gankItemList);
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.d(TAG, "create view holder " + viewType);

        if (viewType == Page.TYPE_BIG_IMAGE) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.page_first, parent, false);
            return new FirstPageVh(view);
        }

        if (viewType == Page.TYPE_NORMAL) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.page_normal, parent, false);
            return new NormalVh(view);
        }

        if (viewType == 0) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.page_loading, parent, false);
            return new LoadingVh(view);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int type = getItemViewType(position);

        if (type == Page.TYPE_BIG_IMAGE) {
            FirstPageVh imageVh = (FirstPageVh) holder;
            imageVh.bind(pageList.get(position));
        }

        if (type == Page.TYPE_NORMAL) {
            NormalVh normalVh = (NormalVh) holder;
            normalVh.bind(pageList.get(position));
        }

        if (type == 0) {
            LoadingVh loadingVh = (LoadingVh) holder;
            ((LoadingVh) holder).bind(mHasMore);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (position < pageList.size()) {
            return pageList.get(position).getType();
        } else {
            return 0;
        }
    }

    @Override
    public int getItemCount() {
        return pageList.size() + 1;
    }

    public int getDataCount() {
        return pageList.size();
    }

    @Override
    public void open(GankItem gankItem) {
        GankViewActivity.startActivity(mContext, gankItem);
    }

    @Override
    public void showBottomSheet(GankItem gankItem) {
        BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(mContext);
        GankItemView gankItemView = (GankItemView) LayoutInflater.from(mContext).inflate(R.layout.bottom_sheet, null, false);
        gankItemView.bind(gankItem, GankAdapter.this);
        bottomSheetDialog.setContentView((View) gankItemView);
        bottomSheetDialog.show();
    }

    @Override
    public void like(GankItem gankItem) {
        if (gankItem.like) {
            mListener.showInfo("已喜欢");
        } else {
            mListener.showInfo("取消喜欢");
        }

        DataManager.getInstance(mContext).updateLike(gankItem);
    }

    class LoadingVh extends RecyclerView.ViewHolder {

        @BindView(R.id.loading)
        ProgressBar loading;
        @BindView(R.id.text)
        TextView textView;

        LoadingVh(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        void bind(boolean hasMore) {
            if (hasMore) {
                loading.setVisibility(View.VISIBLE);
                textView.setText("加载中...");
            } else {
                loading.setVisibility(View.GONE);
                textView.setText("没有更多内容");
            }
        }
    }

    class FirstPageVh extends RecyclerView.ViewHolder {

        @BindViews({R.id.item_head, R.id.item1})
        GankItemView[] items;

        FirstPageVh(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        void bind(Page page) {
            for (int i = 0;i < page.getSize() && i < items.length;i ++) {
                items[i].bind(page.items[i], GankAdapter.this);
            }
        }
    }

    class NormalVh extends RecyclerView.ViewHolder {
        @BindViews({R.id.item1, R.id.item2, R.id.item3, R.id.item4})
        GankItemView items[];

        NormalVh(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        void bind(Page page) {
            for (int i = 0;i < page.getSize() && i < items.length;i ++) {
                items[i].bind(page.items[i], GankAdapter.this);
            }
        }
    }

    private abstract static class Page {
        static final int TYPE_BIG_IMAGE = 1;
        static final int TYPE_NORMAL = 2;

        GankItem[] items;

        abstract int getType();
        abstract int getSize();
    }

    /**
     * 通常为某天信息的第一页
     * 样式为上方一个大图片，下方一个内容
     *
     */
    private static class FirstPage extends Page {
        static FirstPage gen(List<GankItem> gankItemList) {
            GankItem imageItem = null;

            if (gankItemList == null || gankItemList.size() <= 1) {
                return null;
            }

            Iterator<GankItem> gankItemIterator = gankItemList.iterator();
            while (gankItemIterator.hasNext()) {
                GankItem item = gankItemIterator.next();
                if (item.type.equals("福利")) {
                    imageItem = item;
                    gankItemIterator.remove();
                    break;
                }
            }

            if (imageItem == null) {
                return null;
            }

            int count = 2;
            int i = 1;
            GankItem[] items = new GankItem[count];
            items[0] = imageItem;

            gankItemIterator = gankItemList.iterator();
            while (gankItemIterator.hasNext() && count > i) {
                GankItem item = gankItemIterator.next();
                items[i] = item;
                i ++;
                gankItemIterator.remove();
            }

            FirstPage bigImagePage = new FirstPage();
            bigImagePage.items = items;
            return bigImagePage;
        }

        @Override int getSize() {
            return items == null ? 0 : items.length;
        }

        @Override int getType() {
            return TYPE_BIG_IMAGE;
        }
    }

    /**
     * 这是通常形式的 page
     * 样式为四个内容竖直排列
     */
    private static class NormalPage extends Page {
        static NormalPage gen(List<GankItem> gankItemList) {
            if (gankItemList == null || gankItemList.isEmpty()) {
                return null;
            }

            int size = gankItemList.size() > 4 ? 4 : gankItemList.size();
            GankItem[] items = new GankItem[size];
            gankItemList.subList(0, size).toArray(items);
            gankItemList.removeAll(Arrays.asList(items));

            NormalPage normalPage = new NormalPage();
            normalPage.items = items;

            return normalPage;
        }

        int getSize() {
            return items == null ? 0 : items.length;
        }

        @Override
        int getType() {
            return TYPE_NORMAL;
        }
    }

    public interface Listener {
        void showInfo(String info);
    }
}
