package kr.co.hanwha.hifive.adapter;

import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

import java.util.ArrayList;

import kr.co.hanwha.hifive.adapter.contract.SearchTaskListContract;
import kr.co.hanwha.hifive.adapter.model.SearchListViewHolderData;
import kr.co.hanwha.hifive.adapter.viewholder.SearchCategoryTitleViewHolder;
import kr.co.hanwha.hifive.adapter.viewholder.SearchMemberListViewHolder;
import kr.co.hanwha.hifive.adapter.viewholder.SearchMoreViewHolder;
import kr.co.hanwha.hifive.adapter.viewholder.SearchTaskListViewHolder;
import kr.co.hanwha.hifive.adapter.viewholder.SearchUnitListViewHolder;
import kr.co.hanwha.hifive.data.model.ProfileData;
import kr.co.hanwha.hifive.data.model.ProjectInfoData;
import kr.co.hanwha.hifive.data.model.SearchIntegrationData;
import kr.co.hanwha.hifive.data.model.TaskListData;
import kr.co.hanwha.hifive.enums.ViewHolderSearchType;

import static kr.co.hanwha.hifive.enums.ViewHolderSearchType.MEMBER;
import static kr.co.hanwha.hifive.enums.ViewHolderSearchType.MORE;
import static kr.co.hanwha.hifive.enums.ViewHolderSearchType.TITLE;
import static kr.co.hanwha.hifive.enums.ViewHolderSearchType.TODO;
import static kr.co.hanwha.hifive.enums.ViewHolderSearchType.UNIT;

/**
 * Created by sanghoonkwon on 2018. 1. 23..
 */

public class SearchTaskListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
        implements SearchTaskListContract.Model, SearchTaskListContract.View {
    private final int ZERO = 0;

    private final int TYPE_TASK = 1;
    private final int COUNT_TITLE = 1;
    private final int COUNT_DISPLAY_ITEM = 5;

    private int mMoreIndexMember;
    private int mMoreIndexTodo;
    private int mMoreIndexUnit;
    private String mServerTime = "";

    private ArrayList<ProfileData> mListMemberData;
    private ArrayList<TaskListData> mListTaskData;
    private ArrayList<ProjectInfoData> mListProjectData;
    private ArrayList<SearchListViewHolderData> mListData;

    private SearchTaskListContract.OnSearchListListener onSearchListListener;

    public void setOnSearchListListener(SearchTaskListContract.OnSearchListListener onSearchListListener) {
        this.onSearchListListener = onSearchListListener;
    }

    /**************************************************
     * ViewActivity
     **************************************************/
    @Override
    public void notifyDataAll() {
        this.notifyDataSetChanged();

    }

    @Override
    public void notifyDataRangeChanged(int positionStart, int itemCount) {
        this.notifyItemRangeChanged(positionStart, itemCount);
    }

    /**************************************************
     * Model
     **************************************************/
    @Override
    public void clearItems() {
        if (mListData != null) mListData.clear();
    }

    @Override
    public void addItem(TaskListData data) {
        if (mListData == null) mListData = new ArrayList<>();
//        mListData.add(data);
    }

    @Override
    public void addItem(TaskListData data, int index) {
        if (mListData != null && mListData.size() > index) {
//            mListData.set(index, data);
        }
    }

    @Override
    public void addItems(ArrayList<TaskListData> list) {
        if (mListData == null) mListData = new ArrayList<>();
        else mListData.clear();
//        mListData.addAll(0, list);
    }

    @Override
    public void addItems(SearchIntegrationData response) {
        mListMemberData = initList(mListMemberData);
        mListMemberData.addAll(response.getResultMembers());
        mListTaskData = initList(mListTaskData);
        mListTaskData.addAll(response.getResultTasks());
        mListProjectData = initList(mListProjectData);
        mListProjectData.addAll(response.getResultProjects());
        mListData = initList(mListData);
        mServerTime = response.getServer_time();

        setMemberData();
        setTaskData();
        setProjectData();

        if (mListData.size() > 0) {
            // 마지막 더보기 체크
            if (mListData.get(mListData.size() - 1).getType() == MORE) {
                mListData.get(mListData.size() - 1).setLast(true);
            }
        }
    }

    @Override
    public void addItems(ArrayList<ProfileData> resultMembers, ArrayList<TaskListData> resultTasks, ArrayList<ProjectInfoData> resultProjects) {

    }

    private void setMemberData() {
        if (mListMemberData.size() > 0) {
            mListData.add(new SearchListViewHolderData.Builder(TITLE).setIntValue(mListMemberData.size()).build());
            for (int i = 0; i < mListMemberData.size(); i++) {
                if (i == COUNT_DISPLAY_ITEM) {
                    mListData.add(new SearchListViewHolderData.Builder(MORE).setIntValue(MEMBER.getCode()).build());
                    mMoreIndexMember = mListData.size() - 1;
                    break;
                }
                mListData.add(makeMemberViewHolderData(i));
            }
        }
    }

    private SearchListViewHolderData makeMemberViewHolderData(int index) {
        ProfileData memberData = mListMemberData.get(index);

        SearchListViewHolderData.Builder builder = new SearchListViewHolderData.Builder(MEMBER)
                .setMemberId(memberData.getMember_id())
                .setLoginId(memberData.getLogin_id())
                .setMemberName(memberData.getMember_name())
                .setCompany(memberData.getCompany())
                .setDepartment(memberData.getDepartment())
                .setRankTitle(memberData.getRank_title())
                .setPhoneMobile(memberData.getPhone_mobile());

        // 처음 멤버 아이템 체크
        if (index == 0) {
            builder.setFirst(true);
        }

        // 마지막 멤버 아이템 체크
        if (index == mListMemberData.size() - 1) {
            builder.setLast(true);
        }

        return builder.build();
    }

    private void setTaskData() {
        if (mListTaskData.size() > 0) {
            mListData.add(new SearchListViewHolderData.Builder(TITLE).setIntValue(mListTaskData.size()).build());
            for (int i = 0; i < mListTaskData.size(); i++) {
                if (i == COUNT_DISPLAY_ITEM) {
                    mListData.add(new SearchListViewHolderData.Builder(MORE).setIntValue(TODO.getCode()).build());
                    mMoreIndexTodo = mListData.size() - 1;
                    break;
                }
                mListData.add(makeTaskViewHolderData(i));
            }
        }
    }

    private SearchListViewHolderData makeTaskViewHolderData(int index) {
        TaskListData taskData = mListTaskData.get(index);

        return new SearchListViewHolderData.Builder(TODO)
                .setMemberId(taskData.getMember_id())
                .setMemberName(taskData.getMember_name())
                .setTaskId(taskData.getTask_id())
                .setDescription(taskData.getDescription())
                .setDueTo(taskData.getDue_to())
                .setStatus(taskData.getStatus())
                .setEvaluation(taskData.getEvaluation())
                .setFinishedAt(taskData.getFinished_at())
                .setClosedAt(taskData.getClosed_at())
                .setAuthorMemberId(taskData.getAuthor_member_id())
                .setAuthorName(taskData.getAuthor_name())
                .build();
    }

    private void setProjectData() {
        if (mListProjectData.size() > 0) {
            mListData.add(new SearchListViewHolderData.Builder(TITLE).setIntValue(mListProjectData.size()).build());
            for (int i = 0; i < mListProjectData.size(); i++) {
                if (i == COUNT_DISPLAY_ITEM) {
                    mListData.add(new SearchListViewHolderData.Builder(MORE).setIntValue(UNIT.getCode()).build());
                    mMoreIndexUnit = mListData.size() - 1;
                    break;
                }
                mListData.add(makeProjectViewHolderData(i));
            }
        }
    }

    private SearchListViewHolderData makeProjectViewHolderData(int index) {
        ProjectInfoData projectData = mListProjectData.get(index);

        return new SearchListViewHolderData.Builder(UNIT)
                .setMemberId(projectData.getMember_id())
                .setMemberName(projectData.getMember_name())
                .setTrackId(projectData.getTrack_id())
                .setTrackName(projectData.getTrack_name())
                .setProjectId(projectData.getProject_id())
                .setProjectName(projectData.getProject_name())
                .setEvaluation(projectData.getEvaluation())
                .setAchievement(projectData.getProject_avg_achieve_rate())
                .setRoleCode(projectData.getRole_code())
                .setRoleName(projectData.getRole_name())
                .setServerTime(mServerTime)
                .build();
    }

    private ArrayList initList(ArrayList list) {
        if (list == null) return new ArrayList();
        else {
            list.clear();
            return list;
        }
    }

    /**************************************************
     * Adapter
     **************************************************/

    @Override
    public int getItemViewType(int position) {
        return mListData.get(position).getType().getCode();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ViewHolderSearchType searchType = ViewHolderSearchType.valueOf(viewType);
        if (searchType == TITLE)
            return new SearchCategoryTitleViewHolder(parent);
        else if (searchType == MEMBER)
            return new SearchMemberListViewHolder(parent, onSearchListListener);
        else if (searchType == TODO)
            return new SearchTaskListViewHolder(parent, onSearchListListener);
        else if (searchType == UNIT)
            return new SearchUnitListViewHolder(parent, onSearchListListener);
        else if (searchType == MORE)
            return new SearchMoreViewHolder(parent, onSearchListListener);

        throw new RuntimeException("############################################################\n" +
                "There is no type that matches the type " + viewType + " + make sure your using types correctly\n" +
                "############################################################");
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        int index = position;
        SearchListViewHolderData data = mListData.get(index);
        ViewHolderSearchType viewType = ViewHolderSearchType.valueOf(getItemViewType(position));

        if (viewType == TITLE) {
            SearchCategoryTitleViewHolder view = (SearchCategoryTitleViewHolder) holder;
            // 다음 index의 아이템으로 멤버/To-Do/유닛 중 어떤 아이템의 타이틀인지 판단
            view.onBind(mListData.get(index + 1).getType(), data.getIntValue());
        } else if (viewType == MEMBER) {
            SearchMemberListViewHolder view = (SearchMemberListViewHolder) holder;
            view.onBind(mListData.get(index), index);
        } else if (viewType == TODO) {
            SearchTaskListViewHolder view = (SearchTaskListViewHolder) holder;
            view.onBind(mListData.get(index), index);
        } else if (viewType == UNIT) {
            SearchUnitListViewHolder view = (SearchUnitListViewHolder) holder;
            view.onBind(mListData.get(index), index);
        } else if (viewType == MORE) {
            SearchMoreViewHolder view = (SearchMoreViewHolder) holder;
            view.onBind(mListData.get(index), data.getIntValue());
        }
    }

    @Override
    public int getItemCount() {
        return (mListData != null ? mListData.size() : ZERO);
    }

    public void loadMoreData(ViewHolderSearchType type) {
        switch (type) {
            case MEMBER:
                loadMoreMember();
                break;
            case TODO:
                loadMoreTodo();
                break;
            case UNIT:
                loadMoreUnit();
                break;
        }
    }

    private void loadMoreMember() {
        int itemCount = 0;
        mListData.remove(mMoreIndexMember);
        for (int i = mListMemberData.size() - 1; i >= COUNT_DISPLAY_ITEM; i--) {
            mListData.add(mMoreIndexMember, makeMemberViewHolderData(i));
            itemCount++;
        }
        notifyDataRangeChanged(mMoreIndexMember, itemCount);
        mMoreIndexTodo += (itemCount - 1);
    }

    private void loadMoreTodo() {
        int itemCount = 0;
        mListData.remove(mMoreIndexTodo);
        for (int i = mListTaskData.size() - 1; i >= COUNT_DISPLAY_ITEM; i--) {
            mListData.add(mMoreIndexTodo, makeTaskViewHolderData(i));
            itemCount++;
        }
        notifyDataRangeChanged(mMoreIndexTodo, itemCount);
    }

    private void loadMoreUnit() {
        int itemCount = 0;
        mMoreIndexUnit = mListData.size() - 1;
        mListData.remove(mListData.size() - 1);
        for (int i = COUNT_DISPLAY_ITEM; i < mListProjectData.size(); i++) {
            mListData.add(makeProjectViewHolderData(i));
            itemCount++;
        }
        notifyDataRangeChanged(mMoreIndexUnit, itemCount);
    }
}