package com.chatsdk.dispatch;

import com.chatsdk.common.ExtSdkCallback;
import com.chatsdk.common.ExtSdkMethodType;
import io.agora.CallBack;
import io.agora.ChatThreadChangeListener;
import io.agora.ValueCallBack;
import io.agora.chat.ChatThread;
import io.agora.chat.ChatThreadEvent;
import io.agora.chat.ChatClient;
import io.agora.chat.Conversation;
import io.agora.chat.CursorResult;
import io.agora.chat.ChatMessage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class ExtSdkChatThreadManagerWrapper extends ExtSdkWrapper {
    public static class SingleHolder {
        static ExtSdkChatThreadManagerWrapper instance = new ExtSdkChatThreadManagerWrapper();
    }

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

    ExtSdkChatThreadManagerWrapper() { registerEaseListener(); }

    private void registerEaseListener() {
        if (this.threadChangeListener != null) {
            ChatClient.getInstance().chatThreadManager().removeChatThreadChangeListener(this.threadChangeListener);
        }
        this.threadChangeListener = new ChatThreadChangeListener() {
            @Override
            public void onChatThreadCreated(ChatThreadEvent event) {
                ExtSdkWrapper.onReceive(ExtSdkMethodType.onChatThreadCreated,
                                        ExtSdkChatThreadEventHelper.toJson(event));
            }

            @Override
            public void onChatThreadUpdated(ChatThreadEvent event) {
                ExtSdkWrapper.onReceive(ExtSdkMethodType.onChatThreadUpdated,
                                        ExtSdkChatThreadEventHelper.toJson(event));
            }

            @Override
            public void onChatThreadDestroyed(ChatThreadEvent event) {
                ExtSdkWrapper.onReceive(ExtSdkMethodType.onChatThreadDestroyed,
                                        ExtSdkChatThreadEventHelper.toJson(event));
            }

            @Override
            public void onChatThreadUserRemoved(ChatThreadEvent event) {
                ExtSdkWrapper.onReceive(ExtSdkMethodType.onChatThreadUserRemoved,
                                        ExtSdkChatThreadEventHelper.toJson(event));
            }
        };
        ChatClient.getInstance().chatThreadManager().addChatThreadChangeListener(this.threadChangeListener);
    }

    public void fetchChatThreadDetail(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        String threadId = param.getString("threadId");
        ChatClient.getInstance().chatThreadManager().getChatThreadFromServer(
            threadId, new ValueCallBack<ChatThread>() {
                @Override
                public void onSuccess(ChatThread value) {
                    ExtSdkWrapper.onSuccess(result, channelName, ExtSdkChatThreadHelper.toJson(value));
                }

                @Override
                public void onError(int error, String errorMsg) {
                    ExtSdkWrapper.onError(result, error, errorMsg);
                }
            });
    }
    public void fetchJoinedChatThreads(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        String cursor = param.getString("cursor");
        int pageSize = param.getInt("pageSize");
        ChatClient.getInstance().chatThreadManager().getJoinedChatThreadsFromServer(
            pageSize, cursor, new ValueCallBack<CursorResult<ChatThread>>() {
                @Override
                public void onSuccess(CursorResult<ChatThread> value) {
                    ExtSdkWrapper.onSuccess(result, channelName, ExtSdkCursorResultHelper.toJson(value));
                }

                @Override
                public void onError(int error, String errorMsg) {
                    ExtSdkWrapper.onError(result, error, errorMsg);
                }
            });
    }
    public void fetchChatThreadsWithParentId(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        String parentId = param.getString("parentId");
        String cursor = param.getString("cursor");
        int pageSize = param.getInt("pageSize");
        ChatClient.getInstance().chatThreadManager().getChatThreadsFromServer(
            parentId, pageSize, cursor, new ValueCallBack<CursorResult<ChatThread>>() {
                @Override
                public void onSuccess(CursorResult<ChatThread> value) {
                    ExtSdkWrapper.onSuccess(result, channelName, ExtSdkCursorResultHelper.toJson(value));
                }

                @Override
                public void onError(int error, String errorMsg) {
                    ExtSdkWrapper.onError(result, error, errorMsg);
                }
            });
    }
    public void fetchJoinedChatThreadsWithParentId(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        String parentId = param.getString("parentId");
        String cursor = param.getString("cursor");
        int pageSize = param.getInt("pageSize");
        ChatClient.getInstance().chatThreadManager().getJoinedChatThreadsFromServer(
            parentId, pageSize, cursor, new ValueCallBack<CursorResult<ChatThread>>() {
                @Override
                public void onSuccess(CursorResult<ChatThread> value) {
                    ExtSdkWrapper.onSuccess(result, channelName, ExtSdkCursorResultHelper.toJson(value));
                }

                @Override
                public void onError(int error, String errorMsg) {
                    ExtSdkWrapper.onError(result, error, errorMsg);
                }
            });
    }
    public void fetchChatThreadMember(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        String threadId = param.getString("threadId");
        String cursor = param.getString("cursor");
        int pageSize = param.getInt("pageSize");
        ChatClient.getInstance().chatThreadManager().getChatThreadMembers(
            threadId, pageSize, cursor, new ValueCallBack<CursorResult<String>>() {
                @Override
                public void onSuccess(CursorResult<String> value) {
                    ExtSdkWrapper.onSuccess(result, channelName, ExtSdkCursorResultHelper.toJson(value));
                }

                @Override
                public void onError(int error, String errorMsg) {
                    ExtSdkWrapper.onError(result, error, errorMsg);
                }
            });
    }
    public void fetchLastMessageWithChatThreads(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        List<String> list = new ArrayList<String>();
        JSONArray array = param.getJSONArray("threadIds");
        for (int i = 0; i < array.length(); i++) {
            list.add(array.getString(i));
        }
        ChatClient.getInstance().chatThreadManager().getChatThreadLatestMessage(
            list, new ValueCallBack<Map<String, ChatMessage>>() {
                @Override
                public void onSuccess(Map<String, ChatMessage> value) {
                    Map<String, Object> data = new HashMap<>();
                    for (Map.Entry<String, ChatMessage> item : value.entrySet()) {
                        data.put(item.getKey(), ExtSdkMessageHelper.toJson(item.getValue()));
                    }
                    ExtSdkWrapper.onSuccess(result, channelName, data);
                }

                @Override
                public void onError(int error, String errorMsg) {
                    ExtSdkWrapper.onError(result, error, errorMsg);
                }
            });
    }
    public void removeMemberFromChatThread(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        String threadId = param.getString("threadId");
        String memberId = param.getString("memberId");
        ChatClient.getInstance().chatThreadManager().removeMemberFromChatThread(threadId, memberId, new CallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, null);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }
    public void updateChatThreadSubject(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        String threadId = param.getString("threadId");
        String name = param.getString("name");
        ChatClient.getInstance().chatThreadManager().updateChatThreadName(threadId, name, new CallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, null);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }
    public void createChatThread(JSONObject param, String channelName, ExtSdkCallback result) throws JSONException {
        String name = param.getString("name");
        String messageId = param.getString("messageId");
        String parentId = param.getString("parentId");
        ChatClient.getInstance().chatThreadManager().createChatThread(
            parentId, messageId, name, new ValueCallBack<ChatThread>() {
                @Override
                public void onSuccess(ChatThread value) {
                    ExtSdkWrapper.onSuccess(result, channelName, ExtSdkChatThreadHelper.toJson(value));
                }

                @Override
                public void onError(int error, String errorMsg) {
                    ExtSdkWrapper.onError(result, error, errorMsg);
                }
            });
    }
    public void joinChatThread(JSONObject param, String channelName, ExtSdkCallback result) throws JSONException {
        String threadId = param.getString("threadId");
        ChatClient.getInstance().chatThreadManager().joinChatThread(threadId, new ValueCallBack<ChatThread>() {
            @Override
            public void onSuccess(ChatThread value) {
                ExtSdkWrapper.onSuccess(result, channelName, ExtSdkChatThreadHelper.toJson(value));
            }

            @Override
            public void onError(int error, String errorMsg) {
                ExtSdkWrapper.onError(result, error, errorMsg);
            }
        });
    }
    public void leaveChatThread(JSONObject param, String channelName, ExtSdkCallback result) throws JSONException {
        String threadId = param.getString("threadId");
        ChatClient.getInstance().chatThreadManager().leaveChatThread(threadId, new CallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, null);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }
    public void destroyChatThread(JSONObject param, String channelName, ExtSdkCallback result) throws JSONException {
        String threadId = param.getString("threadId");
        ChatClient.getInstance().chatThreadManager().destroyChatThread(threadId, new CallBack() {
            @Override
            public void onSuccess() {
                ExtSdkWrapper.onSuccess(result, channelName, null);
            }

            @Override
            public void onError(int code, String error) {
                ExtSdkWrapper.onError(result, code, error);
            }
        });
    }
    public void getMessageThread(JSONObject param, String channelName, ExtSdkCallback result) throws JSONException {
        String msgId = param.getString("msgId");
        ChatMessage msg = ChatClient.getInstance().chatManager().getMessage(msgId);
        if (ExtSdkWrapper.getMessageParams(msg, channelName, result)) {
            return;
        }
        if (!msg.isChatThreadMessage()) {
            ChatThread info = msg.getChatThread();
            ExtSdkWrapper.onSuccess(result, channelName, info != null ? ExtSdkChatThreadHelper.toJson(info) : null);
        } else {
            ExtSdkWrapper.onSuccess(result, channelName, null);
        }
    }
    public void getThreadConversation(JSONObject param, String channelName, ExtSdkCallback result)
        throws JSONException {
        if (!param.has("isChatThread")) {
            param.put("isChatThread", true);
        }

        Conversation conversation = this.getConversation(param);
        ExtSdkWrapper.onSuccess(result, channelName, ExtSdkConversationHelper.toJson(conversation));
    }

    private ChatThreadChangeListener threadChangeListener = null;
}
