package com.cirle.scientific.server;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cirle.scientific.component.SpringUtil;
import com.cirle.scientific.dao.QkjLiveDao;
import com.cirle.scientific.po.QkjLive;
import com.cirle.scientific.po.QkjMember;
import com.cirle.scientific.pojo.Result;
import com.cirle.scientific.service.MemberService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.SpringConfigurator;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 1对多  包括自己在内的所有人发
 * 实时弹幕
 */
@Slf4j
@ServerEndpoint(value = "/live/oneToMany/{liveId}/{memCard}")
//@ServerEndpoint(value = "/live/oneToMany/{liveId}/{memCard}",configurator= SpringConfigurator.class)
@Component
public class WebSocketOneToMany {

    private static Integer LiveJoinMember = 1;

    /**
     * 解决WebSocket不能依赖注入问题,采用手动获取的方式
     */
    private static MemberService memberService;
    @Autowired
    public void setMemberService(MemberService memberService){
        this.memberService = memberService;
    }

    private static QkjLiveDao mevosLivesDao;
    @Autowired
    public void setQkjLiveDao(QkjLiveDao mevosLivesDao){
        this.mevosLivesDao = mevosLivesDao;
    }

    /** 记录当前在线连接数 */
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    /** 存放所有在线的客户端  线程安全的map   基本不会出现并发修改问题 */
    private static Map<String, ConcurrentHashMap<String, Session>> clients = new ConcurrentHashMap<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        JSONObject result = new JSONObject();
        String memCard = session.getPathParameters().get("memCard");
        String liveId = session.getPathParameters().get("liveId");
        if (StringUtils.isNotBlank(liveId)) {
            QkjLive mevosLives = mevosLivesDao.findById(Long.parseLong(liveId)).get();
            mevosLives.setJoinMembers(mevosLives.getJoinMembers()==null?0:mevosLives.getJoinMembers() + LiveJoinMember);
            mevosLivesDao.save(mevosLives);
        }
        ConcurrentHashMap<String, Session> liveMap = clients.get(liveId);
        if (liveMap == null || liveMap.isEmpty()) {
            liveMap = new ConcurrentHashMap<>();
        }
        liveMap.put(session.getId(),session);
        clients.put(liveId,liveMap);
        //远程调用服务获取用户信息   以后可转到公共缓存中存储当前信息  {sessionId,Member}
        QkjMember member = memberService.findByMemCard(memCard);
        if (member != null) {
            for (Map.Entry<String, Session> sessionEntry : clients.get(liveId).entrySet()) {
                Session toSession = sessionEntry.getValue();
                // 排除掉自己   谁进直播间  自己那边不推送
                if (!session.getId().equals(toSession.getId())) {
                    result.put("type",0);
                    result.put("memNickname",member.getMemNickname());
                    result.put("count",onlineCount.get());
                    toSession.getAsyncRemote().sendText(result.toString());
                }

            }
        }
        onlineCount.incrementAndGet(); // 在线数加1
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        String liveId = session.getPathParameters().get("liveId");
        clients.get(liveId).remove(session.getId());
        onlineCount.decrementAndGet();
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     *            客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        //保存弹幕的逻辑 后期交由消息队列异步保存
        //推送弹幕到所有客户端
        if (message != null && !message.equals("心跳检测$$")) {
            this.sendMessage(message,session);
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * 群发消息
     *
     * @param message
     *            消息内容
     */
    private void sendMessage(String message, Session session) {
        JSONObject result = new JSONObject();
        String liveId = session.getPathParameters().get("liveId");
        String memCard = session.getPathParameters().get("memCard");
        QkjMember mevosMember = memberService.findByMemCard(memCard);
        if (mevosMember != null) {
            JSONObject mem = new JSONObject();
            mem.put("memHeadimg",mevosMember.getMemHeadimg());
            mem.put("memNickname",mevosMember.getMemNickname());
            mem.put("msg",message);
            mem.put("time",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            for (Map.Entry<String, Session> sessionEntry : clients.get(liveId).entrySet()) {
                Session toSession = sessionEntry.getValue();
                result.put("type",1);
                result.put("mem",mem);
                toSession.getAsyncRemote().sendText(result.toString());
            }
        }
    }


    /**
     * xxx来了推送
     * @return
     */
    public String sendComing(JSONObject data){
        JSONObject result = new JSONObject();
        if(clients.get(data.get("liveId") + "") != null) {
            for (Map.Entry<String, Session> sessionEntry : clients.get(data.get("liveId") + "").entrySet()) {
                Session toSession = sessionEntry.getValue();
                result.put("type", 7);//推送
                result.put("users", data.get("users"));
                toSession.getAsyncRemote().sendText(result.toString());
            }
        }
        return null;
    }

    /**
     * 开启或者关闭直播推送
     * @param liveId
     * @return
     */
    public String sendStartOrStopLive(Long liveId,Integer liveStatus){
        JSONObject result = new JSONObject();
        log.info("开启或者关闭直播推送liveId:"+liveId);
        if(clients.get(liveId+"") != null){
            for (Map.Entry<String, Session> sessionEntry : clients.get(liveId+"").entrySet()) {
                Session toSession = sessionEntry.getValue();
                result.put("type",2);//推送开启或者关闭直播状态
                result.put("liveId",liveId);
                result.put("liveStatus",liveStatus);
                toSession.getAsyncRemote().sendText(result.toString());
            }
        }
        return null;
    }

    /**
     * 推送评论
     * @return
     */
    public String pushBarrage(JSONObject data){
        JSONObject result = new JSONObject();
        if(clients.get(data.get("liveId") + "") != null) {
            for (Map.Entry<String, Session> sessionEntry : clients.get(data.get("liveId") + "").entrySet()) {
                Session toSession = sessionEntry.getValue();
                result.put("type", 5);//推送
                result.put("barrage", data.get("barrage"));
                toSession.getAsyncRemote().sendText(result.toString());
            }
        }
        return null;
    }

    /**
     * 中奖名单推送
     * @return
     */
    public String sendAwardWinnerList(JSONObject data){
        JSONObject result = new JSONObject();
        if(clients.get(data.get("liveId") + "") != null) {
            for (Map.Entry<String, Session> sessionEntry : clients.get(data.get("liveId") + "").entrySet()) {
                Session toSession = sessionEntry.getValue();
                result.put("type", 4);//推送
                result.put("awardWinnerList", data.get("awardWinnerList"));
                toSession.getAsyncRemote().sendText(result.toString());
            }
        }
        return null;
    }

    /**
     * 开启抽奖推送
     * @param activeId
     * @param liveId
     * @return
     */
    public String sendDrawALotteryActivity(Integer activeId,Long liveId){
        JSONObject result = new JSONObject();
        if(clients.get(liveId + "") != null) {
            for (Map.Entry<String, Session> sessionEntry : clients.get(liveId + "").entrySet()) {
                Session toSession = sessionEntry.getValue();
                result.put("type", 6);//推送
                result.put("activeId", activeId);
                toSession.getAsyncRemote().sendText(result.toString());
            }
        }
        return null;
    }


    /**
     * 获取当前在线用户
     * @param liveId
     * @return
     */
    public Result getOnlineUser(Long liveId){
        JSONArray result = new JSONArray();
        if(clients.get(liveId + "") != null) {
            for (Map.Entry<String, Session> sessionEntry : clients.get(liveId + "").entrySet()) {
                Session toSession = sessionEntry.getValue();
                String memCard = toSession.getPathParameters().get("memCard");
                result.add(memCard);
            }
        }
        return Result.success(result);
    }

    /**
     * 推送直播人气
     * @param liveId
     * @param count
     */
    public void sendLiveUserCount(Long liveId, Integer count) {
        JSONObject result = new JSONObject();
        if(clients.get(liveId + "") != null) {
            for (Map.Entry<String, Session> sessionEntry : clients.get(liveId + "").entrySet()) {
                Session toSession = sessionEntry.getValue();
                result.put("type", 3);//推送
                result.put("liveId", liveId);//推送
                result.put("joinMembers", count);
                toSession.getAsyncRemote().sendText(result.toString());
            }
        }
    }

    public Result<Integer> getOnlineUserCount(Long liveId) {
        int size = 0;
        if(clients.get(liveId + "") != null) {
            ConcurrentHashMap<String, Session> map = clients.get(liveId + "");
            size = map.size();
        }
        return Result.success(size);
    }

    public String sendImgPath(Long liveId, String imgPath) {
        JSONObject result = new JSONObject();
        if(clients.get(liveId + "") != null) {
            for (Map.Entry<String, Session> sessionEntry : clients.get(liveId + "").entrySet()) {
                Session toSession = sessionEntry.getValue();
                result.put("type", 8);//推送图片
                result.put("liveId", liveId);
                result.put("imgPath", imgPath);
                toSession.getAsyncRemote().sendText(result.toString());
            }
        }
        return null;
    }
}
