package com.ccwangluo.ccim.manage;

import com.ccwangluo.ccim.CCIMClient;
import com.ccwangluo.ccim.listener.ResultEventCallback;

import java.util.HashSet;
import java.util.List;
import java.util.logging.Logger;

import ccim.protocol.Channel;
import ccim.protocol.Chat;

public class ChannelManager {
    private final Logger logger = Logger.getLogger(CCIMClient.class.getName());
    private SocketManager socketManager;
    private CallBackManager<Chat.ChatResponseMessage> callBackManager;
    private HashSet<Long> channelIds = new HashSet<>();

    public ChannelManager(SocketManager socketManager, CallBackManager<Chat.ChatResponseMessage> callBackManager) {
        this.socketManager = socketManager;
        this.callBackManager = callBackManager;
    }


    /**
     * 创建频道
     */
    public void createChannel(String channelName, String tag, boolean isOpen, List<Long> userIds, ResultEventCallback<Long> callback) {
        Channel.CreateChannelRequest.Builder createChannelReq = Channel.CreateChannelRequest.newBuilder()
                .setName(channelName)
                .setTag(tag)
                .setOpen(isOpen);
        for (Long id : userIds) {
            createChannelReq.addUserIds(id);
        }
        Chat.ChatRequestMessage.Builder builder = Chat.ChatRequestMessage.newBuilder();
        builder.setCreateChannelReq(createChannelReq);
        int id = socketManager.sendRequest(builder);
        callBackManager.addCallBack(id, new ResultEventCallback<Chat.ChatResponseMessage>() {
            @Override
            public void onSuccess(Chat.ChatResponseMessage chatResponseMessage) {
                if (chatResponseMessage.hasCreateChannelRes()) {
                    logger.info(String.valueOf(chatResponseMessage));
                    Channel.CreateChannelResponse createChannelRes = chatResponseMessage.getCreateChannelRes();
                    callback.onSuccess(createChannelRes.getChannelId());
                    channelIds.add(createChannelRes.getChannelId());
                }
            }

            @Override
            public void onFailed(int errorCode) {
                callback.onFailed(errorCode);
            }
        });
    }

    /**
     * 加入频道
     */
    public void joinChannel(Long channelId, ResultEventCallback<Void> callback) {
        Chat.ChatRequestMessage.Builder builder = Chat.ChatRequestMessage.newBuilder();
        Channel.JoinChannelRequest.Builder joinchannel = Channel.JoinChannelRequest.newBuilder()
                .setChannelId(channelId);
        builder.setJoinChannelReq(joinchannel);
        int id = socketManager.sendRequest(builder);
        callBackManager.addCallBack(id, new ResultEventCallback<Chat.ChatResponseMessage>() {
            @Override
            public void onSuccess(Chat.ChatResponseMessage chatResponseMessage) {
                callback.onSuccess(null);
                channelIds.add(channelId);
            }

            @Override
            public void onFailed(int errorCode) {
                callback.onFailed(errorCode);
            }
        });
    }

    /**
     * 移除频道成员
     */
    public void removeChannelMember(Long channelId, Long userId, ResultEventCallback<Void> callback) {
        Chat.ChatRequestMessage.Builder builder = Chat.ChatRequestMessage.newBuilder();
        Channel.RemoveMemberRequest.Builder removeMemberReq = Channel.RemoveMemberRequest.newBuilder()
                .setChannelId(channelId)
                .setUserId(userId);
        builder.setRemoveMemberReq(removeMemberReq);
        int id = socketManager.sendRequest(builder);
        callBackManager.addCallBack(id, new ResultEventCallback<Chat.ChatResponseMessage>() {
            @Override
            public void onSuccess(Chat.ChatResponseMessage chatResponseMessage) {
                if (chatResponseMessage.hasRemoveMemberRes()) {
                    logger.info(String.valueOf(chatResponseMessage));
                    callback.onSuccess(null);
                }
            }

            @Override
            public void onFailed(int errorCode) {
                callback.onFailed(errorCode);
            }
        });
    }

    /**
     * 频道拉黑
     */
    public void blockChannelUser(Long channelId, Long userId, ResultEventCallback<Void> callback) {
        Chat.ChatRequestMessage.Builder builder = Chat.ChatRequestMessage.newBuilder();
        Channel.ChannelBlockUserRequest request = Channel.ChannelBlockUserRequest.newBuilder()
                .setChannelId(channelId)
                .setBlockedUserId(userId)
                .build();
        builder.setChannelBlockUserReq(request);
        int id = socketManager.sendRequest(builder);
        callBackManager.addCallBack(id, new ResultEventCallback<Chat.ChatResponseMessage>() {
            @Override
            public void onSuccess(Chat.ChatResponseMessage chatResponseMessage) {
                logger.info(String.valueOf(chatResponseMessage));
                callback.onSuccess(null);
            }

            @Override
            public void onFailed(int errorCode) {
                callback.onFailed(errorCode);
            }
        });
    }

    /**
     * 退出频道
     */
    public void exitChannel(Long channelId, ResultEventCallback<Void> callback) {
        Chat.ChatRequestMessage.Builder builder = Chat.ChatRequestMessage.newBuilder();
        Channel.ExitChannelRequest.Builder exitChannel = Channel.ExitChannelRequest.newBuilder()
                .setChannelId(channelId);
        builder.setExitChannelReq(exitChannel);
        int id = socketManager.sendRequest(builder);
        callBackManager.addCallBack(id, new ResultEventCallback<Chat.ChatResponseMessage>() {
            @Override
            public void onSuccess(Chat.ChatResponseMessage chatResponseMessage) {
                logger.info(String.valueOf(chatResponseMessage));
                callback.onSuccess(null);
                channelIds.remove(channelId);
            }

            @Override
            public void onFailed(int errorCode) {
                callback.onFailed(errorCode);
            }
        });
    }

    public void reConnection() {
        for (Long channelId : channelIds) {
            joinChannel(channelId, new ResultEventCallback<Void>() {
                @Override
                public void onSuccess(Void unused) {

                }

                @Override
                public void onFailed(int errorCode) {

                }
            });
        }
        channelIds.clear();
    }
}
