package com.jxy.marketall.websocket;

import com.jxy.common.core.utils.StringUtils;
import com.jxy.marketall.Therad.AppSocketThread;
import com.jxy.marketall.Therad.SocketThread;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description AppWebSocketService服务类
 * @Date 2022/6/30 11:11
 * @Author 杜懿
 */
@ServerEndpoint(value = "/app/websocket/{userName}")
@Component
@Data
public class AppWebSocketService {

    private static final Logger log = LoggerFactory.getLogger(AppWebSocketService.class);

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

    /**与某个客户端的连接会话，需要通过它来给客户端发送数据*/
    private Session session;
    /**接收userName*/
    private String userName;

    private String message;

    private Date date;

    /**某个连接实例的持续推送线程*/
    private Thread thread;

    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session, @PathParam("userName") String userName) {
        //if(!webSocketMap.containsKey(userName))
        //{
        //    addOnlineCount(); // 在线数 +1
        //}
        this.session = session;
        this.userName = userName;
        JXYWebSocketClient jxyClient = new JXYWebSocketClient();

        this.date = new Date();
        jxyClient.setDate(this.date);
        jxyClient.setSession(session);
        jxyClient.setUri(session.getRequestURI().toString());
        //System.out.println("用户"+userName+"连接成功,时间"+jxyClient.getDate());
        webSocketMap.put(userName, jxyClient);

        //log.info("----------------------------------------------------------------------------");
        //log.info("用户连接:"+userName+",当前在线人数为:" + getOnlineCount());
        try {
            sendMessage("来自后台的反馈：连接成功");
            //开启推送信息的线程
            if(StringUtils.isNotBlank(message)){
                if(thread != null){
                    if(userName.equals(thread.getName())){
                        stopPush();
                        System.out.println("收到消息后原有线程已停止");
                    }
                }
            }else{
                System.out.println("当前用户没有线程");
            }

            startPush(message);
        } catch (IOException e) {
            //log.error("用户:"+userName+",网络异常!!!!!!");
            //System.out.println("用户："+userName+"连接异常");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userName)){
            stopPush();
            webSocketMap.remove(userName);
        }

        //log.info("----------------------------------------------------------------------------");
        //log.info(userName+"用户退出,当前在线人数为:" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到用户消息:"+userName+",报文:"+message);
        //开启推送信息的线程
        //if(StringUtils.isNotBlank(message)){
        //    if(thread != null){
        //        if(userName.equals(thread.getName())){
        //            stopPush();
        //            System.out.println("收到消息后原有线程已停止");
        //        }
        //    }
        //}else{
        //    System.out.println("当前用户没有线程");
        //}
        //
        //startPush(message);
        //消息保存到数据库、redis
        //if(StringUtils.isNotBlank(message)){
        //
        //}
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:"+this.userName+",原因:"+error.getMessage());
        error.printStackTrace();
    }

    /**
     * 连接服务器成功后主动推送
     */
    public void sendMessage(String message) throws IOException {
        synchronized (session){ this.session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 向指定客户端发送消息
     * @param userName
     * @param message
     */
    public static void sendMessage(String userName,String message){
        try {
            JXYWebSocketClient JXYWebSocketClient = webSocketMap.get(userName);
            if(JXYWebSocketClient !=null){
                JXYWebSocketClient.getSession().getBasicRemote().sendText(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    public void startPush(String message) {
        if (this.thread != null){//todo  解决this.thread始终为空的问题
            if(userName.equals(thread.getName())){
                //如果存在同名线程则将其关闭
                if(!thread.isInterrupted()){
                    stopPush();
                }
            }
        }
        thread = new Thread(new AppSocketThread(this), userName);
        System.out.println("为用户"+userName+"创建线程，线程名为："+ this.thread.getName());
        thread.start();
    }

    private void stopPush() {
        try {
            if (thread != null) {

                Thread.sleep(5);
                thread.interrupt();
                //this.thread.stop();
                //thread = null;
                //System.out.println("用户连接已断开！");
            }
        } catch(Exception e) {
            System.out.println("停止推送异常:"+e);
            log.error("停止推送异常：", e);
        }
    }

    public static ConcurrentHashMap<String, JXYWebSocketClient> getWebSocketMap() {
        return webSocketMap;
    }

    public static void setWebSocketMap(ConcurrentHashMap<String, JXYWebSocketClient> webSocketMap) {
        AppWebSocketService.webSocketMap = webSocketMap;
    }

}
