package com.sy.coinage.websocket;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.sy.coinage.core.redis.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * websocket业务处理类
 *
 * @author lug 2021年6月2日
 */
@Slf4j
@Component
@ServerEndpoint("/WebSocketServer/{token}")
public class WebSocketServer {

    // 当前端创建连接【 new WebSocket("ws://localhost:8080/websocket") 】时，调用的方法
    @OnOpen
    public void clientConnected(@PathParam("token") String token, Session session) {
        Map<String, Session> map = null;
        if (WebSocketSession.ONLINE_USER_SESSIONS_NEW.containsKey(token)) {
            map = WebSocketSession.ONLINE_USER_SESSIONS_NEW.get(token);
        } else {
            map = new ConcurrentHashMap<>();
        }
        map.put(session.getId(), session);
        WebSocketSession.ONLINE_USER_SESSIONS_NEW.put(token, map);
        WebSocketSession.increaseConnectedClientNum();
        log.debug("websocket消息：TOEKN 为 " + token + " 的客户端连接成功");
        // this.session = session;
        JSONObject json = new JSONObject();
        // 校验命令执行结果
        json.put("success", true);
        json.put("code", 1);
        json.put("msg", "系统消息：TOEKN 为 " + token + " 的客户端连接成功");
        sendMessage2allClients(JSON.toJSONString(json));
//        if (!WebSocketSession.ONLINE_USER_SESSIONS.containsKey(token)) {
//            WebSocketSession.increaseConnectedClientNum();
//            WebSocketSession.ONLINE_USER_SESSIONS.put(token, session);
//            log.debug("websocket消息：TOEKN 为 " + token + " 的客户端连接成功");
//            // this.session = session;
//            JSONObject json = new JSONObject();
//            // 校验命令执行结果
//            json.put("success", true);
//            json.put("code", 1);
//            json.put("msg", "系统消息：TOEKN 为 " + token + " 的客户端连接成功");
//            sendMessage2allClients(JSON.toJSONString(json));
//        }
    }

    // 收到客户端【浏览器】消息后调用的方法
    @OnMessage
    public void receiveMessageFromClient(@PathParam("token") String token, String message) {
        JSONObject json = new JSONObject();
        // 校验命令执行结果
        json.put("success", true);
        json.put("code", 1);
        json.put("msg", "TOEKN " + token + " : " + message);
        sendMessage2allClients(JSON.toJSONString(json));
    }

    //
    @OnError
    public void onError(Throwable error) {
        error.printStackTrace();
    }


    // 连接关闭调用的方法
    @OnClose
    public void onClose(@PathParam("token") String token, Session session) {
        if (WebSocketSession.ONLINE_USER_SESSIONS_NEW.containsKey(token)) {
            Map<String, Session> map = WebSocketSession.ONLINE_USER_SESSIONS_NEW.get(token);
            map.remove(session.getId());
            WebSocketSession.ONLINE_USER_SESSIONS_NEW.put(token, map);
            WebSocketSession.decreaseConnectedClientNum();
            log.debug("websocket消息：TOKEN_ID 为 " + token + " 的客户端断开了连接");
        }
//        WebSocketSession.decreaseConnectedClientNum();
//        WebSocketSession.ONLINE_USER_SESSIONS.remove(token);
//        log.debug("websocket消息：TOKEN_ID 为 " + token + " 的客户端断开了连接");
    }

    /**
     * -单一客户端【浏览器】发消息
     *
     * @param token
     * @param message
     */
    public static String sendMessageClient(String token, Object message) {
        String resp = null;
        Map<String, Session> map = WebSocketSession.ONLINE_USER_SESSIONS_NEW.get(token);
        if (map != null && !map.isEmpty()) {
            Iterator<Map.Entry<String, Session>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Session> next = iterator.next();
                Session session = next.getValue();
                synchronized (session) {
                    try {
                        // 发消息
                        session.getBasicRemote().sendText(JSON.toJSONString(message));
                        resp = "发送成功";
                    } catch (IOException e) {
                        e.printStackTrace();
                        // 给某一个客户端【浏览器】发消息抛异常，没关系，继续给下一个客户端【浏览器】发消息
                        resp = "发送失败";
                    }
                }
            }
        } else {
            resp = "通道不存在，或者已关闭";
        }
        return resp;
//        String resp = null;
//        Session session = WebSocketSession.ONLINE_USER_SESSIONS.get(token);
//        if (session != null) {
//            synchronized (session) {
//                try {
//                    // 发消息
//                    session.getBasicRemote().sendText(JSON.toJSONString(message));
//                    resp = "发送成功";
//                } catch (IOException e) {
//                    e.printStackTrace();
//                    // 给某一个客户端【浏览器】发消息抛异常，没关系，继续给下一个客户端【浏览器】发消息
//                    resp = "发送失败";
//                }
//            }
//        } else {
//            resp = "通道不存在，或者已关闭";
//        }
//        return resp;
    }

    /**
     * -向所有客户端【浏览器】发消息
     *
     * @param message
     */
    public static void sendMessage2allClients(Object message) {
//        WebSocketSession.ONLINE_USER_SESSIONS.forEach((sessionId, session) -> {
//            try {
//                // 发消息
//                session.getBasicRemote().sendText(JSON.toJSONString(message));
//            } catch (IOException e) {
//                e.printStackTrace();
//                // 给某一个客户端【浏览器】发消息抛异常，没关系，继续给下一个客户端【浏览器】发消息
//            }
//        });
    }

}
