package com.chatsdk.dispatch;

import com.chatsdk.common.ExtSdkCallback;
import com.chatsdk.common.ExtSdkMethodType;
import com.hyphenate.EMCallBack;
import com.hyphenate.EMContactListener;
import com.hyphenate.EMValueCallBack;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMContact;
import com.hyphenate.exceptions.HyphenateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;

public class ExtSdkContactManagerWrapper extends ExtSdkWrapper {

    public static class SingleHolder {
        static ExtSdkContactManagerWrapper instance = new ExtSdkContactManagerWrapper();
    }

    public static ExtSdkContactManagerWrapper getInstance() {
        return ExtSdkContactManagerWrapper.SingleHolder.instance;
    }

    ExtSdkContactManagerWrapper() { registerEaseListener(); }

    public void addContact(JSONObject param, String channelName, ExtSdkCallback result) throws JSONException {
        String username = param.getString("username");
        String reason = param.getString("reason");

        EMClient.getInstance().contactManager().asyncAddContact(username, reason, new EMCallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, username);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }

    public void deleteContact(JSONObject param, String channelName, ExtSdkCallback result) throws JSONException {
        String username = param.getString("username");
        param.getBoolean("keepConversation");

        EMClient.getInstance().contactManager().asyncDeleteContact(username, new EMCallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, username);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }

    public void getAllContactsFromDB(JSONObject params, String channelName, ExtSdkCallback result)
        throws JSONException {
        try {
            List contacts = EMClient.getInstance().contactManager().getContactsFromLocal();
            onSuccess(result, channelName, contacts);
        } catch (HyphenateException e) {
            onError(result, e, null);
        }
    }

    public void addUserToBlockList(JSONObject params, String channelName, ExtSdkCallback result) throws JSONException {
        String username = params.getString("username");
        EMClient.getInstance().contactManager().asyncAddUserToBlackList(username, false, new EMCallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, username);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }

    public void removeUserFromBlockList(JSONObject params, String channelName, ExtSdkCallback result)
        throws JSONException {
        String username = params.getString("username");
        EMClient.getInstance().contactManager().asyncRemoveUserFromBlackList(username, new EMCallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, username);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }

    public void getBlockListFromServer(JSONObject params, String channelName, ExtSdkCallback result)
        throws JSONException {
        EMClient.getInstance().contactManager().asyncGetBlackListFromServer(new EMValueCallBack<List<String>>() {
            @Override
            public void onSuccess(List<String> value) {
                ExtSdkWrapper.onSuccess(result, channelName, value);
            }

            @Override
            public void onError(int error, String errorMsg) {
                ExtSdkWrapper.onError(result, error, errorMsg);
            }
        });
    }

    public void getBlockListFromDB(JSONObject params, String channelName, ExtSdkCallback result) throws JSONException {
        List contacts = EMClient.getInstance().contactManager().getBlackListUsernames();
        onSuccess(result, channelName, contacts);
    }

    public void acceptInvitation(JSONObject params, String channelName, ExtSdkCallback result) throws JSONException {
        String username = params.getString("username");
        EMClient.getInstance().contactManager().asyncAcceptInvitation(username, new EMCallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, username);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }

    public void declineInvitation(JSONObject params, String channelName, ExtSdkCallback result) throws JSONException {
        String username = params.getString("username");
        EMClient.getInstance().contactManager().asyncDeclineInvitation(username, new EMCallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, username);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }

    public void getSelfIdsOnOtherPlatform(JSONObject params, String channelName, ExtSdkCallback result)
        throws JSONException {
        EMClient.getInstance().contactManager().asyncGetSelfIdsOnOtherPlatform(new EMValueCallBack<List<String>>() {
            @Override
            public void onSuccess(List<String> value) {
                ExtSdkWrapper.onSuccess(result, channelName, value);
            }

            @Override
            public void onError(int error, String errorMsg) {
                ExtSdkWrapper.onError(result, error, errorMsg);
            }
        });
    }

    public void getAllContacts(JSONObject params, String channelName, ExtSdkCallback result) throws JSONException {
        EMClient.getInstance().contactManager().asyncFetchAllContactsFromLocal(new EMValueCallBack<List<EMContact>>() {
            @Override
            public void onSuccess(List<EMContact> value) {
                List<Map> contactList = new ArrayList<>();
                for (EMContact contact : value) {
                    contactList.add(ExtSdkContactHelper.toJson(contact));
                }
                ExtSdkWrapper.onSuccess(result, channelName, contactList);
            }

            @Override
            public void onError(int error, String errorMsg) {
                ExtSdkWrapper.onError(result, error, errorMsg);
            }
        });
    }

    public void setContactRemark(JSONObject params, String channelName, ExtSdkCallback result) throws JSONException {
        String userId = params.getString("userId");
        String remark = params.getString("remark");
        EMClient.getInstance().contactManager().asyncSetContactRemark(userId, remark, new EMCallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, null);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }

    public void getContact(JSONObject params, String channelName, ExtSdkCallback result) throws JSONException {
        String userId = params.getString("userId");
        try {
            EMContact contact = EMClient.getInstance().contactManager().fetchContactFromLocal(userId);
            if (contact != null) {
                ExtSdkWrapper.onSuccess(result, channelName, ExtSdkContactHelper.toJson(contact));
            } else {
                ExtSdkWrapper.onSuccess(result, channelName, null);
            }
        } catch (HyphenateException e) {
            ExtSdkWrapper.onError(result, e, null);
        }
    }

    private void registerEaseListener() {
        if (this.contactListener != null) {
            EMClient.getInstance().contactManager().removeContactListener(this.contactListener);
        }
        this.contactListener = new EMContactListener() {
            @Override
            public void onContactAdded(String userName) {
                Map<String, Object> data = new HashMap<>();
                data.put("type", "onContactAdded");
                data.put("username", userName);
                onReceive(ExtSdkMethodType.onContactChanged, data);
            }

            @Override
            public void onContactDeleted(String userName) {
                Map<String, Object> data = new HashMap<>();
                data.put("type", "onContactDeleted");
                data.put("username", userName);
                onReceive(ExtSdkMethodType.onContactChanged, data);
            }

            @Override
            public void onContactInvited(String userName, String reason) {
                Map<String, Object> data = new HashMap<>();
                data.put("type", "onContactInvited");
                data.put("username", userName);
                data.put("reason", reason);
                onReceive(ExtSdkMethodType.onContactChanged, data);
            }

            @Override
            public void onFriendRequestAccepted(String userName) {
                Map<String, Object> data = new HashMap<>();
                data.put("type", "onFriendRequestAccepted");
                data.put("username", userName);
                onReceive(ExtSdkMethodType.onContactChanged, data);
            }

            @Override
            public void onFriendRequestDeclined(String userName) {
                Map<String, Object> data = new HashMap<>();
                data.put("type", "onFriendRequestDeclined");
                data.put("username", userName);
                onReceive(ExtSdkMethodType.onContactChanged, data);
            }

            @Override
            public void onContactInfoUpdate(EMContact contact) {
                Map<String, Object> data = new HashMap<>();
                data.put("type", "onContactInfoUpdate");
                data.put("contact", ExtSdkContactHelper.toJson(contact));
                onReceive(ExtSdkMethodType.onContactChanged, data);
            }
        };
        EMClient.getInstance().contactManager().setContactListener(this.contactListener);
    }
    private EMContactListener contactListener = null;
}
