package cn.com.ty.lift.ud.neety.process;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import cn.com.ty.lift.ud.neety.protocol.ChatMsgDTO;
import cn.com.ty.lift.ud.neety.task.RoomInfo;
import cn.com.ty.lift.ud.neety.task.UserInfo;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.com.ty.lift.ud.neety.protocol.IMMessage;
import cn.com.ty.lift.ud.neety.protocol.IMP;
import cn.com.ty.lift.ud.neety.protocol.RoomVo;
import cn.com.ty.lift.ud.neety.support.WebSoketSupport;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

/**
 * 初始化房间操作类
 *
 * @author sKing
 * @Date 2020年6月12日
 */
@Slf4j
public class InitRoomProcessor extends WebSoketSupport implements ProcessorInterface {

    /**
     * websoket消息处理
     *
     * @param client
     * @param request
     */
    @Override
    public void process(Channel client, IMMessage request) {
        String currentUserId = client.attr(USERID).get();
        String currentUserHead = client.attr(HEAD_PIC).get();
        String currentUserName = client.attr(USERNAME).get();

        String SESSION_ID = request.getSessionid();
        String USER_ID = request.getUserId();
        //聊天室不存在返回消息
        boolean exists = redis.exists("ROOM:" + SESSION_ID);
        if (!exists){
            IMMessage im = new IMMessage();
            im.setCmd(IMP.CHAT.getName());
            im.setMsg("房间不存在");
            sendMessage(client, im);
            return;
        }

        //用户每次进来更新自己的信息
        //如果自己的信息不存在就把用户添加到聊天室中
        //如果聊天室存在，并且当前用户没有在聊天室中，把用户添加到聊天室中------start
        RoomInfo roomInfo = redis.get("ROOM:" + SESSION_ID, RoomInfo.class);
        boolean userExists = false;
        for (int i = 0; roomInfo.getUserLIst() != null
                && !roomInfo.getUserLIst().isEmpty()
                && i < roomInfo.getUserLIst().size(); i++) {
            if (currentUserId.equals(roomInfo.getUserLIst().get(i).getUserId())){
                userExists = true;
                roomInfo.getUserLIst().get(i).setAvatarUrl(currentUserHead);
                roomInfo.getUserLIst().get(i).setUserName(currentUserName);
            }
        }
        if (!userExists) {
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(currentUserId);
            userInfo.setUserName(currentUserName);
            userInfo.setAvatarUrl(currentUserHead);
            roomInfo.getUserLIst().add(userInfo);
        }
        redis.setValue("ROOM:" + SESSION_ID, roomInfo);
        //如果聊天室存在，并且当前用户没有在聊天室中，把用户添加到聊天室中------end

        //用户每次进来把当天聊天记录通过后台全部推送过去
        List charts = redis.get("ALLCHATS:" + SESSION_ID, List.class);
        IMMessage im = new IMMessage();
        im.setCmd(IMP.INITROOM.getName());
        im.setMsg(JSONObject.toJSONString(charts));
        im.setSessionid(SESSION_ID);
        sendMessage(client, im);

        /*
        // 获取消息发送者
        String username = request.getName();
        String room = request.getSessionid();
        String sendId = request.getFromUser();
        String avatarUrl = request.getAvatarUrl();

        client.attr(IP_ADDR).getAndSet(getAddress(client));
        client.attr(USERID).getAndSet(getAddress(client));
        client.attr(USERNAME).getAndSet(username);
        client.attr(HEAD_PIC).getAndSet(avatarUrl);
        client.attr(ROOM).getAndSet(room);
        client.attr(SENDID).getAndSet(sendId);

        // room为总得大房间，map中的key为小房间的房间号，值为房间内对应每个用户的对象
        Map<String, List<RoomVo>> redisRoom = redis.get(MAX_ROOM, HashMap.class);
        String txt = redis.getKey(MAX_ROOM);
        Object ob = (txt == null || "null".equals(txt)) ? null : JSONObject.parseObject(txt, HashMap.class).get(room);

        // 获取当前用户的小房间持有用户
        Set<Channel> minRoom = new HashSet<>();
        *//*
        if (null != roomUser.get(room)) {
            minRoom = roomUser.get(room);
        } else {
            minRoom = new HashSet<>();
        }
        boolean flag = true;
        // 确保单个用户服务端channel是唯一的,避免重复发送同一条消息
        for (Channel channel : minRoom) {
            if (channel == client) {
                flag = false;
                continue;
            }
        }
        if (flag) {
            log.info("初始化channel .");
            minRoom.add(client);
        } else {
            log.info("重复初始化channel .");
        }
        
        // TODO 完成诊单之后将从缓存中删除房间
        roomUser.put(room, minRoom);*//*

        Set<HashMap<String, Channel>> userChannel = roomUserChannel.get(room);
        Set<HashMap<String, Channel>> newUserChannel = new HashSet<>();
        if (null != userChannel && userChannel.size() > 0) {
            for (HashMap<String, Channel> map : userChannel) {
                map.keySet().forEach(item -> {
                    log.info("keySet():{}", item);
                    if (item.equals(sendId)) {
                        log.info("sendId:{}重连item存在:{}", sendId, item);
                        map.put(item, client);
                    } else if (!map.containsKey(sendId)) {
                        log.info("重连sendId不存在:{}", sendId);
                        map.put(sendId, client);
                    }
                    newUserChannel.add(map);
                });

            }

            roomUserChannel.put(room, newUserChannel);
        } else {
            userChannel = new HashSet<>();
            HashMap<String, Channel> map = new HashMap<>();
            map.put(sendId, client);
            userChannel.add(map);

            // for (String session : DBsessionList) {
            roomUserChannel.put(room, userChannel);
            
            log.info("====================================");
            log.info("出现问题。InitRoom的时候roomUserChannel为空？");
            log.info("====================================");
            // }
        }

        for (Map<String, Channel> map : roomUserChannel.get(room)) {
            map.values().forEach(item -> {
                minRoom.add(item);
                log.info("房间里面的channel:{}", item.id());
            });
            roomUser.put(room, minRoom);
        }

        List<RoomVo> voList = new ArrayList<>();
        RoomVo vo = new RoomVo(sendId, 0, username, avatarUrl, true, room);

        if (null != redisRoom) {// 缓存中获取全部房间信息

            if (null == ob) {// 拿到当前房间号
                voList.add(vo);
                redisRoom.put(room, voList);
            } else {

                voList = JSONArray.parseArray(ob.toString(), RoomVo.class);
                voList.add(vo);
                voList = voList.stream().filter(distinctByKey(RoomVo::getUserId)).collect(Collectors.toList()); // 去重

                for (RoomVo item : voList) {
                    if (sendId.equals(item.getUserId())) {
                        item.setAvatarUrl(avatarUrl);
                        item.setFlag(true);
                        item.setName(username);
                    }
                }

                redisRoom.put(room, voList);
            }

        } else {
            redisRoom = new HashMap<>();
            voList.add(vo);
            redisRoom.put(room, voList);
        }
        // 获取房间内的用户对象信息
        String loginList = JSONObject.toJSONString(voList);

        *//** 向所有用户发送系统消息 *//*
        for (Channel channel : minRoom) {
            if (channel != client) {
                // 自定义系统消息格式
                IMMessage requestSystem = new IMMessage(IMP.SYSTEM.getName(), sysTime(), 0, loginList);
                sendMessage(channel, requestSystem);
            } else if (channel == client) {*//** 向自己发送消 *//*

         *//**
         * 1、提取该用户所有房间的未读消息列表返回给用户 2、此处为登录初始化调用，不会频繁触发，所以直接查询mysql用的会话列表。来配合缓存读取用户的所有未读消息
         *//*
                if (null != ob) {
                    voList = JSONArray.parseArray(ob.toString(), RoomVo.class);
                    for (RoomVo item : voList) {
                        *//** 提取未读消息列表返回给用户 *//*
                        if (item.getMsgList().size() > 0 && item.getUserId().equals(sendId)) {
                            request = new IMMessage(IMP.UNREAD.getName(), sysTime(), 0,
                                JSONObject.toJSONString(item.getMsgList()));
                            item.setMsgList(null);// 将未读消息置空
                            sendMessage(channel, request);
                            // 写入缓存对象
                            redisRoom.put(room, voList);
                        }
                    }

                }
                log.info("发送消息~~~~~");
                sendOnline(channel, loginList);

            } else {

                request = new IMMessage(IMP.SYSTEM.getName(), sysTime(), 0, loginList);
                sendMessage(channel, request);
                log.info("发送消息~~~~~");
            }
        }

        // 更新缓存
        redis.setValue(MAX_ROOM, redisRoom);*/
    }

}
