package kr.co.hanwha.hifive.data.source;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import kr.co.hanwha.hifive.data.model.AddTaskRoot;
import kr.co.hanwha.hifive.data.model.BaseData;
import kr.co.hanwha.hifive.data.model.LoginData;
import kr.co.hanwha.hifive.data.model.MainHomeAssignedRoot;
import kr.co.hanwha.hifive.data.model.MainHomeRequestRoot;
import kr.co.hanwha.hifive.data.model.MemberInfoData;
import kr.co.hanwha.hifive.data.model.MemberInfoRoot;
import kr.co.hanwha.hifive.data.model.MessageAddData;
import kr.co.hanwha.hifive.data.model.MessageListRoot;
import kr.co.hanwha.hifive.data.model.ProjectInfoData;
import kr.co.hanwha.hifive.data.model.ProjectInfoRoot;
import kr.co.hanwha.hifive.data.model.ProjectTaskRoot;
import kr.co.hanwha.hifive.data.model.ReqMemberInfo;
import kr.co.hanwha.hifive.data.model.SearchTagData;
import kr.co.hanwha.hifive.data.model.TaskData;
import kr.co.hanwha.hifive.data.model.TaskDetailRoot;
import kr.co.hanwha.hifive.data.source.contract.TaskDataDataSource;
import kr.co.hanwha.hifive.enums.EvaluationType;
import kr.co.hanwha.hifive.network.HFNetworkUtil;
import kr.co.hanwha.hifive.network.hanwha.HanwhaNetworkCallback;
import kr.co.hanwha.hifive.network.hanwha.HanwhaNetworkError;

import static kr.co.hanwha.hifive.network.hanwha.HanwhaNetworkUtil.isNetworkConnected;

/**
 * TASK 관련 데이터 저장소
 * Created by sanghoonkwon on 2018. 1. 11..
 */

public class TaskDataRepository implements TaskDataDataSource {
    private static TaskDataRepository sInstance = null;
    private static ArrayList<ProjectInfoData> sListProjectInfo;
    private static ArrayList<MemberInfoData> sListSelectedMemberInfo;
    private static TaskData sTaskData;

    public static TaskDataRepository getInstance() {
        if (sInstance == null) {
            sInstance = new TaskDataRepository();
        }
        return sInstance;
    }

    public static void destroyInstance() {
        sInstance = null;
    }

    @Override
    public void clearData() {
        if (sListProjectInfo != null) sListProjectInfo.clear();
        sListProjectInfo = null;

        if (sListSelectedMemberInfo != null) sListSelectedMemberInfo.clear();
        sListSelectedMemberInfo = null;

        sTaskData = null;
    }

    public static int setMemberListSelect(MemberInfoData data, boolean isSelect) {
        int index = 0;
        if (sListSelectedMemberInfo != null) {
            data.setSelected(isSelect);
            for (int i = 0; i < sListSelectedMemberInfo.size(); i++) {
                if (data.getMember_id() == sListSelectedMemberInfo.get(i).getMember_id() &&
                        data.getProject_id() == sListSelectedMemberInfo.get(i).getProject_id()) {
                    index = i;
                }
            }
            sListSelectedMemberInfo.set(index, data);
        }
        return index;
    }

    public static ArrayList<MemberInfoData> getSelectedDataList() {
        ArrayList<MemberInfoData> list = new ArrayList<>();
        if (sListSelectedMemberInfo != null) {
            for (MemberInfoData data : sListSelectedMemberInfo) {
                if (data.isSelected()) list.add(data);
            }
        }
        Collections.sort(list, sort);

        return list;
    }

    public static boolean setVerifyData() {
        //TODO...
        return true;
    }


    private final static Comparator<MemberInfoData> sort = new Comparator<MemberInfoData>() {
        @Override
        public int compare(MemberInfoData o1, MemberInfoData o2) {
            return Long.compare(o1.getSelectedTime(), o2.getSelectedTime());
        }
    };

    public static TaskData getTaskData() {
        return sTaskData;
    }

    public static void setTaskData(TaskData taskData) {
        TaskDataRepository.sTaskData = taskData;
    }

    public static void setMemeberListSelectMine(boolean isSelected) {
        if (isSelected) {
            boolean isMine = false;
            if (sListSelectedMemberInfo != null && sListSelectedMemberInfo.size() > 0) {
                for (int i = 0; i < sListSelectedMemberInfo.size(); i++) {
                    MemberInfoData data = sListSelectedMemberInfo.get(i);
                    if (data.getMember_id() == MemberDataRepository.getInstance().getMemberId() && isMine == false) {
                        setMemberListSelect(data, isSelected);
                        isMine = true;
                    }
                }
            }
        } else {
            if (sListSelectedMemberInfo != null && sListSelectedMemberInfo.size() > 0) {
                for (int i = 0; i < sListSelectedMemberInfo.size(); i++) {
                    MemberInfoData data = sListSelectedMemberInfo.get(i);
                    if (data.getMember_id() == MemberDataRepository.getInstance().getMemberId()) {
                        setMemberListSelect(data, isSelected);
                    }
                }
            }
        }
    }

    @Override
    public void requestSetTaskToday(@NonNull Context context, @NonNull TaskData taskData,
                                    @NonNull boolean isToday, @Nullable HanwhaNetworkCallback callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        taskData.setIs_today(isToday);
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTasksUpdateToday(context, taskData, encryption_member_id, callback);
    }

    @Override
    public void requestTasksGetMainAssigned(@NonNull Context context, @NonNull final HanwhaNetworkCallback<MainHomeAssignedRoot> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();

        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTasksGetMainAssigned(context, encryption_member_id, new HanwhaNetworkCallback<MainHomeAssignedRoot>() {
            @Override
            public void onSuccess(MainHomeAssignedRoot response) {
                callback.onSuccess(response);
            }

            @Override
            public void onFailure(HanwhaNetworkError error) {
                if (error != null && error.getStatusCode() == -2) {
                    callback.onSuccess(null);
                } else
                    callback.onFailure(error);
            }

            @Override
            public void onPreExecute() {
                callback.onPreExecute();
            }

            @Override
            public void onPostExecute() {
                callback.onPostExecute();
            }
        });
    }

    @Override
    public void requestTasksGetMainRequest(@NonNull Context context, @NonNull final HanwhaNetworkCallback<MainHomeRequestRoot> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();

        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTasksGetMainRequest(context, encryption_member_id, new HanwhaNetworkCallback<MainHomeRequestRoot>() {
            @Override
            public void onSuccess(MainHomeRequestRoot response) {
                callback.onSuccess(response);
            }

            @Override
            public void onFailure(HanwhaNetworkError error) {
                if (error != null && error.getStatusCode() == -2) {
                    callback.onSuccess(null);
                } else
                    callback.onFailure(error);
            }

            @Override
            public void onPreExecute() {
                callback.onPreExecute();
            }

            @Override
            public void onPostExecute() {
                callback.onPostExecute();
            }
        });
    }

    @Override
    public void requestTeamModuleList(@NonNull Context context, @Nullable final HanwhaNetworkCallback<ArrayList<ProjectInfoData>> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_no = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestGetProjectsInfo(context, encryption_member_no, new HanwhaNetworkCallback<ProjectInfoRoot>() {
            @Override
            public void onSuccess(ProjectInfoRoot response) {
                if (sListProjectInfo != null) sListProjectInfo.clear();
                else sListProjectInfo = new ArrayList<>();

                if (response != null && response.getListMyProjectsInfo() != null) {
                    for (int i = 0; i < response.getListMyProjectsInfo().size(); i++) {
                        sListProjectInfo.add(response.getListMyProjectsInfo().get(i));
                    }
                }

                callback.onSuccess(sListProjectInfo);
            }

            @Override
            public void onFailure(HanwhaNetworkError error) {
                callback.onFailure(error);
            }

            @Override
            public void onPreExecute() {
                callback.onPreExecute();
            }

            @Override
            public void onPostExecute() {
                callback.onPostExecute();
            }
        });
    }

    @Override
    public void requestAllMember(@NonNull Context context, @NonNull final HanwhaNetworkCallback callback) {
        if (HFNetworkUtil.isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        if (sListSelectedMemberInfo == null || sListSelectedMemberInfo.size() == 0) {
            String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
            HFNetworkUtil networkUtil = new HFNetworkUtil();
            networkUtil.requestMemberAll(context, encryption_member_id, new HanwhaNetworkCallback<MemberInfoRoot>() {
                @Override
                public void onSuccess(MemberInfoRoot response) {
                    if (response != null) {
                        if (sListSelectedMemberInfo == null)
                            sListSelectedMemberInfo = new ArrayList<>();
                        for (int i = 0; i < response.getListMemberInfo().size(); i++) {
                            MemberInfoData data = response.getListMemberInfo().get(i);
                            if (data.getMember_id() == MemberDataRepository.getInstance().getMemberId())
                                sListSelectedMemberInfo.add(data);
                        }
                        boolean topLineAdd = false;
                        for (int i = 0; i < response.getListMemberInfo().size(); i++) {
                            MemberInfoData data = response.getListMemberInfo().get(i);
                            if (data.getMember_id() != MemberDataRepository.getInstance().getMemberId()) {
                                if (topLineAdd == false) {
                                    topLineAdd = true;
                                    data.setTopLine(true);
                                }
                                sListSelectedMemberInfo.add(data);
                            }
                        }
//                    sListMemberInfo = response.getListMemberInfo();
                        callback.onSuccess(sListSelectedMemberInfo);
                    }
                }

                @Override
                public void onFailure(HanwhaNetworkError error) {
                    callback.onFailure(error);
                }

                @Override
                public void onPreExecute() {
                    callback.onPreExecute();
                }

                @Override
                public void onPostExecute() {
                    callback.onPostExecute();
                }
            });
        } else {
            callback.onSuccess(sListSelectedMemberInfo);
        }
    }

    @Override
    public void requestSendTask(@NonNull Context context,
                                @NonNull String task_name,
                                @NonNull String due_to,
                                @NonNull ArrayList<MemberInfoData> listMemberInfo,
                                @Nullable final HanwhaNetworkCallback callback) {
        if (HFNetworkUtil.isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }


        ArrayList<ReqMemberInfo> listMemberId = new ArrayList<>();
        if (listMemberInfo != null) {
            for (MemberInfoData data : listMemberInfo) {
                listMemberId.add(new ReqMemberInfo(data.getMember_id(), data.getProject_id(), data.getTrack_id()));
            }
        }

        int author_member_id = MemberDataRepository.getInstance().getMemberId();
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestSendTask(context, author_member_id, encryption_member_id, task_name, due_to, listMemberId, new HanwhaNetworkCallback<AddTaskRoot>() {
            @Override
            public void onSuccess(AddTaskRoot response) {
                callback.onSuccess(response);
            }

            @Override
            public void onFailure(HanwhaNetworkError error) {
                callback.onFailure(error);
            }

            @Override
            public void onPreExecute() {
                callback.onPreExecute();
            }

            @Override
            public void onPostExecute() {
                callback.onPostExecute();
            }
        });
    }

    @Override
    public void requestUpdateTask(@NonNull Context context,
                                  @NonNull TaskData taskData,
                                  @Nullable final HanwhaNetworkCallback callback) {
        if (HFNetworkUtil.isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }


        ArrayList<MemberInfoData> list = new ArrayList<>();
        list.add(new MemberInfoData(taskData.getMember_id(),
                taskData.getMember_name(),
                taskData.getMember_profile_url(),
                taskData.getProject_id(),
                taskData.getProject_name()));

        int author_member_id = MemberDataRepository.getInstance().getMemberId();
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestUpdateTask(context, encryption_member_id, taskData, new HanwhaNetworkCallback<BaseData>() {
            @Override
            public void onSuccess(BaseData response) {
                callback.onSuccess(response);
            }

            @Override
            public void onFailure(HanwhaNetworkError error) {
                callback.onFailure(error);
            }

            @Override
            public void onPreExecute() {
                callback.onPreExecute();
            }

            @Override
            public void onPostExecute() {
                callback.onPostExecute();
            }
        });
    }

    @Override
    public void requestGetTaskDetail(@NonNull Context context,
                                     @NonNull int task_id,
                                     @NonNull int project_id,
                                     @NonNull int track_id,
                                     @Nullable final HanwhaNetworkCallback<TaskDetailRoot> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTasksGetDetails(context,
                encryption_member_id,
                task_id,
                project_id,
                track_id,
                new HanwhaNetworkCallback<TaskDetailRoot>() {
                    @Override
                    public void onSuccess(TaskDetailRoot response) {
                        if (response != null)
                            callback.onSuccess(response);
                        else callback.onSuccess(null);
                    }

                    @Override
                    public void onFailure(HanwhaNetworkError error) {
                        callback.onFailure(error);
                    }

                    @Override
                    public void onPreExecute() {
                        callback.onPreExecute();
                    }

                    @Override
                    public void onPostExecute() {
                        callback.onPostExecute();
                    }
                });
    }

    @Override
    public void requestDeleteTask(@NonNull Context context, @NonNull TaskData taskData, @Nullable HanwhaNetworkCallback callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskDelete(context, taskData, encryption_member_id, callback);
    }

    @Override
    public void requestTaskAccept(@NonNull Context context,
                                  @NonNull TaskData taskData,
                                  @Nullable HanwhaNetworkCallback<BaseData> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskAccept(context, encryption_member_id, taskData, callback);
    }

    @Override
    public void requestTaskReject(@NonNull Context context, @NonNull TaskData taskData, @NonNull String message, @Nullable HanwhaNetworkCallback<BaseData> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTasksUpdateRejection(context, encryption_member_id, taskData, message, callback);
    }

    @Override
    public void requestSetTaskEvaluation(@NonNull Context context,
                                         @NonNull TaskData taskData,
                                         @NonNull EvaluationType evaluationType,
                                         @Nullable HanwhaNetworkCallback<BaseData> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestSetTaskEvaluation(context, encryption_member_id, taskData, evaluationType, callback);
    }

    @Override
    public void requestGetMessageList(@NonNull Context context, @NonNull int task_id, @NonNull int current_page,
                                      @Nullable final HanwhaNetworkCallback<MessageListRoot> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestGetMessageList(context, encryption_member_id, task_id, current_page, callback);
    }

    @Override
    public void requestAddMessage(@NonNull Context context, @NonNull int task_id, @NonNull String contents, @Nullable HanwhaNetworkCallback<MessageAddData> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestAddMessage(context, encryption_member_id, task_id, contents, callback);
    }

    @Override
    public void requestSearchTaskByTag(@NonNull Context context, @NonNull String searchTag, @Nullable final HanwhaNetworkCallback<SearchTagData> callback) {
        if (isNetworkConnected(context) == false) {
            callback.onFailure(new HanwhaNetworkError(HanwhaNetworkError.CODE_NETWORK_CONNECTION_ERROR));
            return;
        }

        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestSearchTaskByTag(context, encryption_member_id, searchTag, new HanwhaNetworkCallback<SearchTagData>() {
            @Override
            public void onSuccess(SearchTagData response) {
                callback.onSuccess(response);
            }

            @Override
            public void onFailure(HanwhaNetworkError error) {
                if (error != null && error.getStatusCode() == -2) {
                    callback.onSuccess(null);
                } else
                    callback.onFailure(error);
            }

            @Override
            public void onPreExecute() {
                callback.onPreExecute();
            }

            @Override
            public void onPostExecute() {
                callback.onPostExecute();
            }
        });
    }
}
