package yangtz.cs.liu.campus.service.impl.SchoolAuthority;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import yangtz.cs.liu.campus.domain.schoolAuthority.SchoolAuthority;
import yangtz.cs.liu.campus.mapper.schoolAuthority.SchoolAuthorityMapper;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint(value = "/ws/webSocket/{userId}")
@Component
public class WebSocketServer {
    public WebSocketServer() {
        System.out.println("EchoSocket:start");
    }

   // private Session session;
    /**
     * 记录当前在线链接数
     */
    public static final Map<Long, Session> sessionMap = new ConcurrentHashMap<>();

    public static  Map<Long, Session> getList() {
        return sessionMap;
    }

    /**
     * 实例化service层，此处不能使用autowired等注解自动注入，
     * 因spring的bean是默认单例模式
     */
    SchoolAuthorityMapper authorityMapper;

    private static ApplicationContext applicationContext;

    //解决无法注入mapper问题
    public static void setApplicationContext(ApplicationContext context) {
        applicationContext = context;
    }


    /**
     * 打开连接时执行
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId) throws IOException {
        //this.session = session;
        sessionMap.put(userId, session);
        System.out.println("有新用户加入" + userId);
        //实例化bean
        authorityMapper = applicationContext.getBean(SchoolAuthorityMapper.class);
        LambdaQueryWrapper<SchoolAuthority> lqw = new LambdaQueryWrapper<>();
        List<SchoolAuthority> list = authorityMapper.selectList(lqw);
        SchoolAuthority authority = list.get(0);
        JSONObject result = new JSONObject();
        JSONArray array = new JSONArray();
        result.set("users", array);
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.set("grade", authority.getGrade());
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.set("classHeader", authority.getClassHeader());
        JSONObject jsonObject3 = new JSONObject();
        jsonObject3.set("parent", authority.getParent());

        array.add(jsonObject1);
        array.add(jsonObject2);
        array.add(jsonObject3);
        sendMessage(JSONUtil.toJsonStr(result));//后台发送消息给所有客户端
    }

    /**
     * 收到消息时执行
     * 后台收到客户端发送过来的消息
     * 是消息的中转站
     */
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        System.out.println("从客户端收到的消息：" + message);
        sendMessage(JSON.toJSONString("1111"));
    }

    /**
     * 关闭连接时执行
     */
    @OnClose
    public void onClose(Session session,@PathParam("userId")Long userId) {
        sessionMap.remove(userId);
        System.out.println("连接已经关闭");
    }

    /**
     * 连接发生错误时执行
     */
    @OnError
    public void onError(Throwable error, Session session) {
        System.out.println("连接发生错误");
        error.printStackTrace();
    }

    /**
     * websocket session发送文本消息有两个方法：getAsyncRemote()和getBasicRemote()
     * getAsyncRemote()和getBasicRemote()是异步与同步的区别，
     * 大部分情况下，推荐使用getAsyncRemote()。
     */
    public static void sendMessage(String message)  {
        //this.session.getAsyncRemote().sendText(message);
       try{
           for(Session session : sessionMap.values()){
               session.getBasicRemote().sendText(message);
           }
       }catch (Exception e){
           System.out.println("发送失败");
       }

    }
}
