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

import java.util.*;

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.ChatMsgDTO;
import cn.com.ty.lift.ud.neety.protocol.IMMessage;
import cn.com.ty.lift.ud.neety.protocol.RoomVo;
import cn.com.ty.lift.ud.neety.support.SensitivewordFilter;
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 ChatProcessor extends WebSoketSupport implements ProcessorInterface {

    /**
     * websoket消息处理
     * 
     * @param client
     * @param request
     */
    @Override
    public void process(Channel client, IMMessage request) {
        //获取发送人信息
        String currentUserId = client.attr(USERID).get();

        //获取消息
        String sessionId = request.getSessionid();
        //敏感词过滤
        String message = SensitivewordFilter.replaceSensitiveWord(request.getMsg(), 1, "**");
        request.setMsg(message);

        //redis只存当天的消息，RedisTask中synRedisChatToDB定时任务会在每天凌晨把消息同步到数据库
        //每次发消息，把消息累加到redis中，推送全量数据给客户端
        boolean exists = redis.exists("ALLCHATS:" + sessionId);
        List<IMMessage> chats = null;
        if (exists){
            chats = redis.get("ALLCHATS:" + sessionId, List.class);
        } else {
            chats  = new ArrayList() ;
        }
        chats.add(request);
        redis.setValue("ALLCHATS:" + sessionId, chats);

        //更新聊天室中的最后一条记录及时间，在app中获取聊天室排序有用
        RoomInfo roomInfo = redis.get("ROOM:" + sessionId, RoomInfo.class);
        roomInfo.setLastChat(request.getMsg());
        roomInfo.setLastTime(request.getTime());
        redis.setValue("ROOM:" + sessionId, roomInfo);

        //通过redis获取房间信息
        //用户正常登录的时候链接就会调用login协议，login会加载聊天室与用户关系到数据
        //当用户已经登录了，附近的人聊天的时候，接收人是不知道自己已经有一个新的会话。
        //出诊问诊时，专家没有接单的情况下是不能进入聊天室的。
        //这种情况会造成，附近的人聊天，接收人不进入聊天室接收不到消息，
        //通过标记类型，附近的人聊天，直接用userchannel变量中找到链接发送给接收人，并把聊天记录存入redis中
        if (request.getDataTable() == 3){
            //发给接收人
            //如果接收人不在线，聊天记录存在redis中，等他上线之后进入聊天室同样也可以看到未读记录
            Channel channel = userChannel.get(request.getReceiver());
            if(null != channel){
                sendMessage(channel, request);
            }
            //发给自己
            sendMessage(client, request);
        }else{
            for (int i = 0; roomInfo.getUserLIst() != null
                    && !roomInfo.getUserLIst().isEmpty()
                    &&i < roomInfo.getUserLIst().size(); i++) {
                UserInfo userInfo = roomInfo.getUserLIst().get(i);
                Channel channel = userChannel.get(userInfo.getUserId());

                if(null != channel){
                    sendMessage(channel, request);
                }
            }
        }



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

        if(null != request.getMsg()){
            String message = SensitivewordFilter.replaceSensitiveWord(request.getMsg(), 1, "**");
            request.setMsg(message);
        }
        
        client.attr(IP_ADDR).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<>();
     *//*   boolean flag = true;
        // 确保单个用户服务端channel是唯一的,避免重复发送同一条消息
        for (Channel channel : minRoom) {
            if (channel == client) {
                log.info(":{}==========:{}",channel,client);
                flag = false;
                continue;
            }
        }
        if (flag) {
            log.info("初始化channel .");
            minRoom.add(client);
        } else {
            log.info("重复初始化channel .");
        }*//*
        

        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("出现问题。Chat的时候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);
        }
        

        *//** 如果是聊天信息 *//*

        ChatMsgDTO msgDb = null;
        for (Channel channel : minRoom) {// 向房间内在线用户发送消息
            if (channel != client) {
                request.setName(username);
                if (null == msgDb) {
                    msgDb = saveMsg(request);
                }

            } else { *//** 向自己发送消息 *//*
                request.setName(username);
            }

            sendMessage(channel, request);
        }

        if (null != ob) {*//** 向不在线的用户发送未读消息 *//*

            List<RoomVo> voList = JSONArray.parseArray(ob.toString(), RoomVo.class);
            for (RoomVo item : voList) {
                if (!item.getFlag()) {
                    // 用户不在线记录未读消息同时向缓存中写入聊天记录，供后期同步到数据库中
                    if (null == msgDb) {
                        msgDb = saveMsg(request);
                    }
                    item.getMsgList().add(msgDb);
                    // 写入缓存对象
                    redisRoom.put(room, voList);
                }
            }
        }

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

    }

}
