package com.eitc.patient.netty.process;

import com.alibaba.fastjson2.JSON;
import com.eitc.common.core.redis.RedisCache;
import com.eitc.common.utils.spring.SpringUtils;
import com.eitc.patient.netty.protocol.IMDecoder;
import com.eitc.patient.netty.protocol.IMEncoder;
import com.eitc.patient.netty.protocol.IMMessage;
import com.eitc.patient.netty.protocol.IMP;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;










/**消息处理类*/
@Component
public class MsgProcessor {

    //记录在线用户
    private final IMEncoder encoder = new IMEncoder();
    private final IMDecoder decoder = new IMDecoder();
    private static final Map<String, ChannelGroup> channelGroupMap = new HashMap<>();
    private final AttributeKey<String> USERNAME = AttributeKey.valueOf("username");
    //channel自定义属性

    private static final RedisCache redisCache;

    static {
        redisCache = SpringUtils.getBean(RedisCache.class);
    }

    public void individually(Channel client, IMMessage request, List<String> historyList) {
        //将字符串解析为自定义格式


        //获取消息发送者
        String username = request.getSender();
        //消息接收者
        String receiver = request.getReceiver();
        // type 1 username 是医生  2 是用户
        String type = request.getType();

        if (IMP.LOGIN.getName().equals(request.getCmd())) {
            ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
            //患者 如果患者有聊天那么就直接进入聊天室
            if(type.equals("1")){
                // username 是医生
                if (channelGroupMap.get(receiver + username) != null) {
                    channelGroup = channelGroupMap.get(receiver + username);

                } else {
                    // 创建聊天室
                    channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
                    channelGroupMap.put(receiver + username, channelGroup);
                }
                client.attr(USERNAME).set(username);
                // 添加到聊天室
                channelGroup.add(client);
                // 添加到缓存
            }else{
                // username 是患者
                if (channelGroupMap.get(username + receiver) != null) {
                    channelGroup = channelGroupMap.get(username + receiver);

                } else {
                    // 创建聊天室
                    channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
                    channelGroupMap.put(username + receiver, channelGroup);
                }
                // 添加到聊天室
                client.attr(USERNAME).set(username);
                channelGroup.add(client);
                // 添加到缓存
            }


            //像所有用户发送系统消息
            for (Channel channel : channelGroup) {//向其他人发送消息

                if (channel == client){
                    historyDisplay(historyList, channel, username);
                }

            }
        }
        //如果是登出
        else if (IMP.LOGOUT.getName().equals(request.getCmd())) {
            logout(client, request);
        }
        //如果是聊天信息
        else if (IMP.CHAT.getName().equals(request.getCmd())||IMP.CHATIMG.getName().equals(request.getCmd())) {
            ChannelGroup channels =new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
            assert type != null;
            if(type.equals("1")){
                // username 是医生
                channels = channelGroupMap.get(receiver + username);
            }else{
                // username 是患者
                channels =  channelGroupMap.get(username+receiver);
            }
            if (channels != null) {
                for (Channel channel : channels) {//向其他人发送消息
                    if (channel != client) {
                        if (username.equals(client.attr(AttributeKey.valueOf("username")).get())){
                            client.attr(AttributeKey.valueOf("username"));
                        }else{
                            request.setSender(username);
                        }
                    }
                    //向自己发送消息
                    else {
                        request.setSender("MY_SELF");
                    }
                    //自定义IM协议解码
                    String text = encoder.encode(request);

                    channel.writeAndFlush(new TextWebSocketFrame(text));
                    System.out.println(text);
                }

            }
        }
    }

    /**
     * 历史记录渲染
     * @param historyList
     * @param channel
     * @param username
     */
    private void historyDisplay(List<String> historyList, Channel channel, String username) {
        historyList.forEach(x->{
            //发送消息
            IMMessage decode = decoder.decode(x);
            if (username.equals(decode.getSender())){
                decode.setSender("MY_SELF");
            }
            String texthis = encoder.encode(decode);
            channel.writeAndFlush(new TextWebSocketFrame(texthis));
        });
    }


    /**
     * 登出通知
     * @param client
     * @return
     */
    public void logout(Channel client, IMMessage request) {

        //获取消息发送者
        String username = request.getSender();
        //消息接收者
        String receiver = request.getReceiver();
        // type 1 username 是医生  2 是用户
        String type = request.getType();
        ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
        if(type.equals("1")){
            // username 是医生
            channels = channelGroupMap.get(receiver + username);
        }else{
            // username 是患者
            channels =  channelGroupMap.get(username+receiver);
        }

        if (channels != null) {
            request.setCmd(IMP.SYSTEM.getName());
            request.setOnline(channels.size());
            request.setContent(request.getSender() + "已离开！");
            for (Channel channel : channels) {//向其他人发送消息
                if (channel != client) {
                    //自定义IM协议解码
                    String text = encoder.encode(request);
                    //发送消息
                    channel.writeAndFlush(new TextWebSocketFrame(text));
                }
            }
            channels.remove(client);
        }
    }

    /**
     * 退出登录
     * @param client
     */
    public void logout(Channel client) {
//        client.close();
        // 如果断开连接 那我就清除内存中的链接
        List <String> key = new ArrayList<>();
        channelGroupMap.forEach((k,v)->{
            if (v.isEmpty()){
                key.add(k);
            }
        });
        if (!key.isEmpty()){
            key.forEach(channelGroupMap::remove);
        }
    }


}
