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

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

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

import kr.co.hanwha.hifive.data.model.AddTaskRoot;
import kr.co.hanwha.hifive.data.model.BaseData;
import kr.co.hanwha.hifive.data.model.CampaignData;
import kr.co.hanwha.hifive.data.model.CampaignDataRoot;
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.ProjectCampaignData;
import kr.co.hanwha.hifive.data.model.ProjectInfoData;
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.TaskDataSource;
import kr.co.hanwha.hifive.enums.TaskEvaluationType;
import kr.co.hanwha.hifive.network.HFNetworkUtil;
import kr.co.hanwha.hifive.network.hanwha.HanwhaNetworkCallback;
import kr.co.hanwha.hifive.network.hanwha.HanwhaNetworkError;


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

public class TaskDataRepository implements TaskDataSource {
    private static TaskDataRepository sInstance = null;
    private static ArrayList<ProjectInfoData> sListProjectInfo;
    private static ArrayList<MemberInfoData> sListMemberInfo;
    private static HashMap<String, MemberInfoData> sSelectedMemberInfo;
    private static HashMap<String, MemberInfoData> sUnverifiedMemberInfo;
    private static MemberInfoData sMemberInfoData;
    private static boolean sIsMemberChanged = false;
    private static ArrayList<ProjectCampaignData> sListCampaignInfo;
    private static String sUnverifiedCampaignKey;
    private static String sVerifiedCampaignKey;
    private static CampaignData sCampaignData;

    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 (sListMemberInfo != null) sListMemberInfo.clear();
        sListMemberInfo = null;

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

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

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

        sUnverifiedCampaignKey = null;
        sVerifiedCampaignKey = null;
        sMemberInfoData = null;
        sCampaignData = null;
    }

    public static void setSelectMember(MemberInfoData data, boolean isSelect) {
        if (sUnverifiedMemberInfo == null) sUnverifiedMemberInfo = new HashMap<>();

        /*
        http://www.junstarok.com/redmine/issues/1118
        */
        if (isSelect) {
            if (sUnverifiedMemberInfo.size() > 0)
                sUnverifiedMemberInfo.clear();

            sUnverifiedMemberInfo.put(data.getKey(), data);
            data.setSelectedTime();
        } else {
            if (sUnverifiedMemberInfo.containsKey(data.getKey())) {
                sUnverifiedMemberInfo.remove(data.getKey());
                data.clearSelectedTime();
            }
        }
        /*
        2018.5.29 기획 변경으로 한명만 선택되도록 변경
        if (isSelect) {
            if (sUnverifiedMemberInfo.containsKey(data.getKey()) == false) {
                sUnverifiedMemberInfo.put(data.getKey(), data);
                data.setSelectedTime();
            }
        } else {
            if (sUnverifiedMemberInfo.containsKey(data.getKey())) {
                sUnverifiedMemberInfo.remove(data.getKey());
                data.clearSelectedTime();
            }
        }
         */
    }

    // 다시 만들자...너무 구려..머리 맑을떄 다시..
    public static void setUnverifiedMemberInfo() {
        if (sUnverifiedMemberInfo == null) sUnverifiedMemberInfo = new HashMap<>();
        else sUnverifiedMemberInfo.clear();

        if (sSelectedMemberInfo != null) {
            for (MemberInfoData data : sListMemberInfo) {
                if (sSelectedMemberInfo.containsKey(data.getKey()))
                    sUnverifiedMemberInfo.put(data.getKey(), data);
            }
        }
    }

    public static void setVerifyMemberInfo() {
        if (sSelectedMemberInfo != null && sUnverifiedMemberInfo != null) {
            if (sSelectedMemberInfo.size() != sUnverifiedMemberInfo.size()) {
                sVerifiedCampaignKey = "";
//                sIsMemberChanged= true;
            } else {
                for (String key : sSelectedMemberInfo.keySet()) {
                    if (sUnverifiedMemberInfo.containsKey(key) == false)
                        sVerifiedCampaignKey = "";//sIsMemberChanged = true;
                }

                for (String key : sUnverifiedMemberInfo.keySet()) {
                    if (sSelectedMemberInfo.containsKey(key) == false)
                        sVerifiedCampaignKey = "";//sIsMemberChanged = true;
                }
            }
        } else {
            sVerifiedCampaignKey = "";
        }

        if (sSelectedMemberInfo == null) sSelectedMemberInfo = new HashMap<>();
        else sSelectedMemberInfo.clear();

        if (sUnverifiedMemberInfo != null) {
            for (MemberInfoData data : sListMemberInfo) {
                if (sUnverifiedMemberInfo.containsKey(data.getKey()))
                    sSelectedMemberInfo.put(data.getKey(), data);
            }
        }
    }

    public static HashMap<String, MemberInfoData> getUnverifyMemberInfo() {
        return sUnverifiedMemberInfo;
    }

    public static MemberInfoData getMemberInfoData() {
        return sMemberInfoData;
    }

    public static void setMemberInfoData(MemberInfoData memberInfoData) {
        sMemberInfoData = memberInfoData;
    }

    public static ArrayList<MemberInfoData> getSelectedMemberList() {
        ArrayList<MemberInfoData> list = new ArrayList<>();
        if (sListMemberInfo != null && sSelectedMemberInfo != null) {
            for (MemberInfoData data : sListMemberInfo) {
                if (sSelectedMemberInfo.containsKey(data.getKey())) list.add(data);
            }
        }
        Collections.sort(list, sort);

        return list;
    }

    public static ArrayList<MemberInfoData> getUnverifySelectedMemberList() {
        ArrayList<MemberInfoData> list = new ArrayList<>();
        if (sListMemberInfo != null && sUnverifiedMemberInfo != null) {
            for (MemberInfoData data : sListMemberInfo) {
                if (sUnverifiedMemberInfo.containsKey(data.getKey())) list.add(data);
            }
        }
        Collections.sort(list, sort);

        return list;
    }

    public static String getVerifiedCampaignKey() {
        return sVerifiedCampaignKey;
    }

    public static void setUnverifiedCampaignInfo() {
        if (TextUtils.isEmpty(sVerifiedCampaignKey) == false)
            sUnverifiedCampaignKey = new String(sVerifiedCampaignKey);
    }

    public static void setVerifyCampaignInfo() {
        if (sUnverifiedCampaignKey == null) return;
        sVerifiedCampaignKey = new String(sUnverifiedCampaignKey);
    }

    public static void setVerifyCampaignInfo(String verifyCampaignKey) {
        sVerifiedCampaignKey = verifyCampaignKey;
    }

    public static void setCampaignListSelect(CampaignData data) {
        if (sListCampaignInfo != null) {
            sUnverifiedCampaignKey = data.getKey();
        } else {
            sCampaignData = data;
        }
    }

    public static ProjectCampaignData getSelectedCampaignData() {
        if (sListCampaignInfo != null && TextUtils.isEmpty(sVerifiedCampaignKey) == false) {
            for (ProjectCampaignData data : sListCampaignInfo) {
                if (data.getKey().equals(sVerifiedCampaignKey)) return data;
            }
        }
        if (sCampaignData != null) return new ProjectCampaignData(sCampaignData);
        return null;
    }

    public static void clearSelectedCampaignData() {
        sVerifiedCampaignKey = "";
        sUnverifiedCampaignKey = "";
        sCampaignData = null;
    }

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

    @Override
    public void requestSetTaskToday(@NonNull Context context, @NonNull TaskData taskData,
                                    @NonNull boolean isToday, @Nullable HanwhaNetworkCallback callback) {
        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) {
        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) {
        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 requestAllMember(@NonNull Context context, @NonNull final HanwhaNetworkCallback callback) {
        if (sListMemberInfo == null || sListMemberInfo.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 (sListMemberInfo == null)
                            sListMemberInfo = new ArrayList<>();
                        // TODO  내가 제일 위에 나오도록 정렬...Collection 으로 변경하자
                        for (int i = 0; i < response.getListMemberInfo().size(); i++) {
                            MemberInfoData data = response.getListMemberInfo().get(i);
                            if (data.getMember_id() == MemberDataRepository.getInstance().getMemberId())
                                sListMemberInfo.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);
                                }
                                sListMemberInfo.add(data);
                            }
                        }
                        callback.onSuccess(sListMemberInfo);
                    }
                }

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

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

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

    @Override
    public void requestCampaignListByProjectId(@NonNull Context context, @NonNull ArrayList<Integer> listReqProjectId, @NonNull final HanwhaNetworkCallback callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestCampaignListByProjectId(context, encryption_member_id,
                listReqProjectId,
                new HanwhaNetworkCallback<CampaignDataRoot>() {
                    @Override
                    public void onSuccess(CampaignDataRoot response) {
                        if (response != null) {
                            sListCampaignInfo = response.getListProjectsCampaignsInfo();
                        }

                        callback.onSuccess(sListCampaignInfo);
                    }

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

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

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

    @Override
    public void requestCampaignListByMemberId(@NonNull Context context, @NonNull ArrayList<Integer> listMemberInfo, @NonNull final HanwhaNetworkCallback callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestCampaignListByMemberId(context, encryption_member_id,
                listMemberInfo,
                new HanwhaNetworkCallback<CampaignDataRoot>() {
                    @Override
                    public void onSuccess(CampaignDataRoot response) {
                        if (response != null) {
                            sListCampaignInfo = response.getListProjectsCampaignsInfo();
                        }

                        callback.onSuccess(sListCampaignInfo);
                    }

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

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

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

    @Override
    public void requestSendTask(@NonNull Context context,
                                @NonNull String task_name,
                                @NonNull String due_to,
                                @NonNull ArrayList<MemberInfoData> listMemberInfo,
                                @Nullable CampaignData campaignData,
                                @Nullable final HanwhaNetworkCallback callback) {
        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, campaignData, 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 CampaignData campaignData,
                                  @Nullable final HanwhaNetworkCallback callback) {
        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()));

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

    @Override
    public void requestGetTaskDetail(@NonNull Context context,
                                     @NonNull int task_id,
                                     @NonNull int project_id,
                                     @Nullable final HanwhaNetworkCallback<TaskDetailRoot> callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTasksGetDetails(context,
                encryption_member_id,
                task_id,
                project_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) {
        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) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskStatusAccept(context, encryption_member_id, taskData.getAuthor_member_id(), taskData.getTask_id(), callback);
    }

    @Override
    public void requestTaskReject(@NonNull Context context, @NonNull TaskData taskData, @NonNull String message, @Nullable HanwhaNetworkCallback<BaseData> callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();

        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskStatusRejectedRequest(context, encryption_member_id, taskData.getAuthor_member_id(), taskData.getTask_id(), message, callback);
    }

    @Override
    public void requestGetMessageList(@NonNull Context context, @NonNull int task_id, @NonNull int current_page,
                                      @Nullable final HanwhaNetworkCallback<MessageListRoot> callback) {
        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) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestAddMessage(context, encryption_member_id, task_id, contents, callback);
    }

    @Override
    public void requestDeleteMessage(@NonNull Context context, @NonNull int id, @Nullable HanwhaNetworkCallback callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestDeleteMessage(context, encryption_member_id, id, callback);
    }

    @Override
    public void requestSearchTaskByTag(@NonNull Context context, @NonNull String searchTag, @Nullable final HanwhaNetworkCallback<SearchTagData> callback) {
        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();
            }
        });
    }

    @Override
    public void requestSetTaskDeleteRequest(@NonNull Context context, @NonNull TaskData taskData, @Nullable HanwhaNetworkCallback callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();

        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskStatusClosed(context, encryption_member_id, taskData.getAuthor_member_id(), taskData.getTask_id(), callback);
    }

    @Override
    public void requestSetTaskReRequest(@NonNull Context context, @NonNull TaskData taskData, @Nullable HanwhaNetworkCallback callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();

        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskStatusRequest(context, encryption_member_id, taskData.getAuthor_member_id(), taskData.getTask_id(), callback);
    }

    @Override
    public void requestSetTaskEvaluation(@NonNull Context context,
                                         @NonNull TaskData taskData,
                                         @NonNull TaskEvaluationType taskEvaluationType,
                                         @Nullable HanwhaNetworkCallback<BaseData> callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();
        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskStatusEvaluated(context, encryption_member_id, taskData.getAuthor_member_id(), taskData.getTask_id(), taskEvaluationType, callback);
    }

    @Override
    public void requestSetTaskEvaluationAccept(@NonNull Context context, @NonNull TaskData taskData, @Nullable HanwhaNetworkCallback callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();

        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskStatusClosed(context, encryption_member_id, taskData.getAuthor_member_id(), taskData.getTask_id(), callback);
    }

    @Override
    public void requestSetTaskEvaluationReject(@NonNull Context context, @NonNull TaskData taskData,
                                               @NonNull String message, @Nullable HanwhaNetworkCallback callback) {
        String encryption_member_id = MemberDataRepository.getInstance().getEncryptionMemberId();

        HFNetworkUtil networkUtil = new HFNetworkUtil();
        networkUtil.requestTaskStatusRejectedEvaluation(context, encryption_member_id, taskData.getAuthor_member_id(), taskData.getTask_id(), message, callback);
    }
}
