package com.fs.app.websocket.service;


import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.fs.ai.service.IBaiduAIService;
import com.fs.ai.vo.BaiduAIMsgResultVO;
import com.fs.app.websocket.bean.MsgBean;
import com.fs.chat.config.WxConfig;
import com.fs.chat.domain.ChatKeyword;
import com.fs.chat.domain.ChatMsg;
import com.fs.chat.domain.ChatRole;
import com.fs.chat.domain.ChatSession;
import com.fs.chat.service.IChatMsgService;
import com.fs.chat.service.IChatRoleService;
import com.fs.chat.service.IChatSessionService;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.spring.SpringUtils;

import com.fs.company.domain.CompanyUser;
import com.fs.company.service.ICompanyUserService;
import com.fs.course.domain.FsCourseSopLogs;
import com.fs.course.service.IFsCourseSopLogsService;
import com.fs.his.domain.FsUser;
import com.fs.his.service.IFsUserService;
import com.fs.wx.kf.dto.WeixinKfImageMsgDTO;
import com.fs.wx.kf.dto.WeixinKfMsgSendDTO;
import com.fs.wx.kf.dto.WeixinKfTextMsgDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static com.fs.common.constant.FsConstants.REDIS_CHAT_SESSION;

@ServerEndpoint("/app/webSocket/{uid}")
@Component
public class WebSocketServer {
    IBaiduAIService baiduAIService=SpringUtils.getBean(IBaiduAIService.class);
    IChatRoleService chatRoleService=SpringUtils.getBean(IChatRoleService.class);
    IChatMsgService chatMsgService=SpringUtils.getBean(IChatMsgService.class);
    IChatSessionService chatSessionService=SpringUtils.getBean(IChatSessionService.class);
    RedisCache redisCache=SpringUtils.getBean(RedisCache.class);
    IFsUserService userService=SpringUtils.getBean(IFsUserService.class);
    ICompanyUserService companyUserService=SpringUtils.getBean(ICompanyUserService.class);
    IFsCourseSopLogsService iFsCourseSopLogsService=SpringUtils.getBean(IFsCourseSopLogsService.class);


    //concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    //发送消息
    public void sendMessage(Session session, String message) throws IOException {
        if(session != null){
            synchronized (session) {
//                System.out.println("发送数据：" + message);
                session.getBasicRemote().sendText(message);
            }
        }
    }
    //给指定用户发送信息
    public void sendInfo(String id, String message){
        Session session = sessionPools.get(id);
        try {
            System.out.println("给指定用户发送信息:"+session);
             sendMessage(session, message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "uid") String uid){
        sessionPools.put(uid, session);
        System.out.println(uid + "加入webSocket！当前人数为" + sessionPools.size());

    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "uid") String uid){
        sessionPools.remove(uid);
        System.out.println(uid + "断开webSocket连接！当前人数为" + sessionPools.size());
    }

    //收到客户端信息
    @OnMessage
    public void onMessage(String message) throws IOException{
        MsgBean msg=(MsgBean) JSONObject.parseObject(message, MsgBean.class);
        Session session;
        System.out.println( "收到数据" + msg.getCmd());
        try {
            switch (msg.getCmd()){
                case "heartbeat":
                    session=sessionPools.get(msg.getUserId());
                    sendMessage(session, JSONObject.toJSONString(msg));
                    break;
                case "qw"://问答
                    if(msg.getData()!=null&&msg.getData()!=""){
                        session=sessionPools.get(msg.getUserId());
                        ChatRole chatRole=chatRoleService.selectChatRoleByRoleId(Long.parseLong(msg.getRoleId()));
                        WxConfig wxConfig=JSONUtil.toBean(chatRole.getModeConfigJson(), WxConfig.class);
                        Long sessionId=redisCache.getCacheObject(REDIS_CHAT_SESSION+msg.getUserId()+":"+chatRole.getKfId());
                        if(sessionId==null){
                            ChatSession chatSession=new ChatSession();
                            String sessionCode = IdUtil.getSnowflake(0, 0).nextIdStr();
                            chatSession.setSessionCode(sessionCode);
                            chatSession.setKfId(chatRole.getKfId());
                            chatSession.setUserId(msg.getUserId());
                            chatSession.setStatus(1);
                            if(msg.getUserType()!=null){
                                chatSession.setUserType(msg.getUserType());
                            }
                            if(msg.getUserType().equals(2)){
                                FsUser user=userService.selectFsUserByUserId(Long.parseLong(msg.getUserId()));
                                chatSession.setNickName(user.getNickName());
                                chatSession.setAvatar(user.getAvatar());

                            }
                            else if(msg.getUserType().equals(3)){
                                CompanyUser user=companyUserService.selectCompanyUserById(Long.parseLong(msg.getUserId()));
                                chatSession.setNickName(user.getNickName());
                                chatSession.setAvatar(user.getAvatar());
                                chatSession.setCompanyId(user.getCompanyId());
                            }else {
                                chatSession.setCompanyId(chatRole.getCompanyId());
                            }
                            chatSessionService.insertChatSession(chatSession);
                            sessionId=chatSession.getSessionId();
                            //重新创建REDIS
                        }
                        redisCache.setCacheObject(REDIS_CHAT_SESSION+msg.getUserId()+":"+chatRole.getKfId(),sessionId,10, TimeUnit.MINUTES);
                        //接收
                        ChatMsg chatMsg=new ChatMsg();
                        chatMsg.setUserId(msg.getUserId());
                        if(msg.getUserType().equals(2)){
                            FsUser user=userService.selectFsUserByUserId(Long.parseLong(msg.getUserId()));
                            chatMsg.setNickName(user.getNickName());
                            chatMsg.setAvatar(user.getAvatar());
                        }
                        else if(msg.getUserType().equals(3)){
                            CompanyUser user=companyUserService.selectCompanyUserById(Long.parseLong(msg.getUserId()));
                            chatMsg.setNickName(user.getNickName());
                            chatMsg.setAvatar(user.getAvatar());
                            chatMsg.setCompanyId(user.getCompanyId());
                        }else {
                            chatMsg.setCompanyId(chatRole.getCompanyId());
                        }
                        if(msg.getUserType()!=null){
                            chatMsg.setUserType(msg.getUserType());
                        }
                        chatMsg.setSessionId(sessionId);
                        chatMsg.setExtId("");
                        chatMsg.setMsgType(1);
                        chatMsg.setContent(msg.getData());
                        chatMsg.setRoleId(chatRole.getRoleId());
                        chatMsg.setSendType(1);
                        chatMsgService.insertChatMsg(chatMsg);

                        ChatSession chatSession=chatSessionService.selectChatSessionBySessionId(sessionId);
                        BaiduAIMsgResultVO vo=baiduAIService.run(wxConfig.getAppId(),chatSession.getBaiduSessionId(),msg.getData());
                        if(StringUtils.isNotEmpty(vo.getConversationId())){
                            ChatSession sessionMap=new ChatSession();
                            sessionMap.setSessionId(sessionId);
                            sessionMap.setBaiduSessionId(vo.getConversationId());
                            chatSessionService.updateChatSession(sessionMap);

                        }

                        //过滤** 特殊字符
                        String str=vo.getResult().getAnswer();
                        str=str.replaceAll("\\*\\*.*\\*\\*\\^\\[.*\\]\\^\n\n", "");
                        str=str.replaceAll("\\^\\[.*\\]\\^", "");
                        str=str.replaceAll("\\*\\*", "");
                        str=str.replaceAll("\\*", "");
                        msg.setData(str);
                        msg.setMsg(chatMsg);
                        //写入记录
                        chatMsg.setSendType(2);
                        chatMsg.setExtId("");
                        chatMsg.setContent(str);
                        chatMsg.setStatus(0);
                        chatMsgService.insertChatMsg(chatMsg);
                        sendMessage(session, JSONObject.toJSONString(msg));
                    }
                    break;

            }
        }
        catch (Exception e){
            System.out.println( "收到数据" + e.getMessage());
        }

    }
    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable){
        System.out.println("发生错误");
        throwable.printStackTrace();
    }


}
