package com.hzjt.handler;

import cn.hutool.json.JSONUtil;
import com.hzjt.service.TraffFlowService;
import com.hzjt.util.DateUtils;
import com.hzjt.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint("/websocket/{name}")
public class WebSocket {


    public static TraffFlowService traffFlowService;
    /**
     * 与某个客户端的连接对话，需要通过它来给客户端发送消息
     */
    private Session session;


    /**
     * 标识当前连接客户端的用户名
     */
    private String name;

//    private static ApplicationContext applicationContext;
//
//    public static void setApplicationContext(ApplicationContext context){
//        applicationContext=context;
//    }


    /**
     * 用于存所有的连接服务的客户端，这个对象存储是安全的
     */
    private static ConcurrentHashMap<String, WebSocket> webSocketSet = new ConcurrentHashMap<>();


    @OnOpen
    public void OnOpen(Session session, @PathParam(value = "name") String name) {
        this.session = session;
        this.name = name;
        // name是用来表示唯一客户端，如果需要指定发送，需要指定发送通过name来区分
        webSocketSet.put(name, this);
    }


    @OnClose
    public void OnClose() {
        webSocketSet.remove(this.name);
    }


    @OnError
    public void OnError(@PathParam("name") String name, Throwable throwable, Session session) {
        webSocketSet.remove(name);
    }


    @OnMessage
    public void OnMessage(String message) {
        //判断是否需要指定发送，具体规则自定义
        if(message.indexOf("HEARTBEAT")>=0){
            Map map=new HashMap();
            map.put("type","HEARTBEAT");
            map.put("ts",new Date().getTime());
            AppointSending(name, JSONUtil.toJsonStr(map));
        }
    }

    /**
     * 群发
     *
     * @param message
     */
    public boolean GroupSending(String message){
        boolean send=true;
            for (String name : webSocketSet.keySet()) {
                try {

                        if (null != webSocketSet.get(name) && null != webSocketSet.get(name).session && null != webSocketSet.get(name).session.getBasicRemote())
                            synchronized (webSocketSet.get(name).session) {
                            webSocketSet.get(name).session.getBasicRemote().sendText(message);
                           }
                    } catch (Exception e) {
                    send=false;
                }
            }
            return send;
    }

    /**
     * 根据videoid 群发
     */
    public void GroupSendingByVideoid(String name) {
//        log.info("name" + name);
        if (null == traffFlowService) return;
        try {
            List<Map> map = new ArrayList<>();
            if (null != webSocketSet.get(name) && null != webSocketSet.get(name).session && null != webSocketSet.get(name).session.getBasicRemote()) {
//                log.info("name" + name);
                List<Map> dDayFlowmap = traffFlowService.selectFiveAndDayFlow(name);
                if (null != dDayFlowmap)
                    map.addAll(dDayFlowmap);
                List<Map>  TypeDayFlow = traffFlowService.selectFiveAndTypeDayFlow(name);
                if (null != dDayFlowmap)
                    map.addAll(TypeDayFlow);
//                log.info("JSONUtil.toJsonStr(map)" + JSONUtil.toJsonStr(map));
                if (!map.isEmpty() && null!=webSocketSet.get(name) && null!=webSocketSet.get(name).session) {
                    synchronized (webSocketSet.get(name).session) {
                        webSocketSet.get(name).session.getBasicRemote().sendText(JSONUtil.toJsonStr(map));
                    }
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 指定发送
     *
     * @param name
     * @param message
     */
    public void AppointSending(String name, String message) {
        if (null != webSocketSet.get(name) && null != webSocketSet.get(name).session && null != webSocketSet.get(name).session.getBasicRemote()) {
            synchronized (webSocketSet.get(name).session) {
                try {
                    webSocketSet.get(name).session.getBasicRemote().sendText(message);

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

