package com.fs.app.websocket.service;


import com.alibaba.fastjson.JSONObject;
import com.fs.app.websocket.bean.SendMsgVo;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.exception.base.BaseException;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.spring.SpringUtils;
import com.fs.his.domain.FsUser;
import com.fs.his.service.IFsUserService;
import com.fs.live.domain.LiveMsg;
import com.fs.live.domain.LiveWatchUser;
import com.fs.live.service.ILiveMsgService;
import com.fs.live.service.ILiveService;
import com.fs.live.service.ILiveWatchUserService;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@ServerEndpoint("/app/webSocket")
@Component
public class WebSocketServer {


    //concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<Long, Session> sessionPools = new ConcurrentHashMap<>();
    private final RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
    private final ILiveMsgService liveMsgService = SpringUtils.getBean(ILiveMsgService.class);
    private final ILiveService liveService = SpringUtils.getBean(ILiveService.class);
    private final ILiveWatchUserService liveWatchUserService = SpringUtils.getBean(ILiveWatchUserService.class);
    private final IFsUserService fsUserService = SpringUtils.getBean(IFsUserService.class);

    //发送消息
    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 {
            if (session != null) {

                sendMessage(session, message);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session) {
        Map<String, String> params = getParams(session);
        if(!params.containsKey("liveId")) throw new BaseException("未找到直播间");
        if(!params.containsKey("userId")) throw new BaseException("用户信息错误");
        long liveId = Long.parseLong(params.get("liveId"));
        long userId = Long.parseLong(params.get("userId"));
        liveWatchUserService.join(liveId, userId);
        if (liveService.getById(liveId) == null) throw new BaseException("未找到直播间");
        sessionPools.put(liveId, session);
        System.out.println(liveId + "加入webSocket！当前人数为" + sessionPools.size());

    }

    //关闭连接时调用
    @OnClose
    public void onClose(Session session) {
        Map<String, String> params = getParams(session);
        long liveId = Long.parseLong(params.get("liveId"));
        long userId = Long.parseLong(params.get("userId"));
        sessionPools.remove(liveId);
        liveWatchUserService.close(liveId, userId);
        System.out.println(liveId + "断开webSocket连接！当前人数为" + sessionPools.size());
    }

    //收到客户端信息
    @OnMessage
    public void onMessage(String message) throws IOException {
        SendMsgVo msg = JSONObject.parseObject(message, SendMsgVo.class);
        if(msg.isOn()) return;
        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 "sendMsg":
                    session = sessionPools.get(msg.getLiveId());
                    if (session == null) return;
                    LiveWatchUser liveWatchUser = liveWatchUserService.getByLiveIdAndUserId(msg.getLiveId(), msg.getUserId());
                    if(liveWatchUser.getMsgStatus() == 1){
                        sendMessage(session, JSONObject.toJSONString(R.error("你以被禁言")));
                        return;
                    }
                    LiveMsg liveMsg = new LiveMsg();
                    liveMsg.setLiveId(msg.getLiveId());
                    liveMsg.setUserId(msg.getUserId());
                    liveMsg.setNickName(msg.getNickName());
                    liveMsg.setAvatar(msg.getAvatar());
                    liveMsg.setMsg(msg.getMsg());
                    liveMsg.setCreateTime(new Date());
                    liveMsgService.save(liveMsg);
                    msg.setOn(true);
                    sendMessage(session, JSONObject.toJSONString(R.ok().put("data", msg)));
                    break;

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

    }

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

    private Map<String, String> getParams(Session session){
        return session.getRequestParameterMap().entrySet().stream().filter(e -> e.getValue() != null && !e.getValue().isEmpty() && StringUtils.isNotEmpty(e.getValue().get(0))).collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0)));
    }
}
