package cn.reghao.tnb.message.app.ws.handler;

import cn.reghao.jutil.jdk.serializer.JsonConverter;
import cn.reghao.tnb.message.api.dto.MediaProgress;
import cn.reghao.tnb.message.api.model.EventType;
import cn.reghao.tnb.message.app.ws.WsConnection;
import cn.reghao.tnb.message.app.ws.msg.EventReq;
import cn.reghao.tnb.message.app.ws.service.ProgressService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;

/**
 * 媒体进度
 *
 * @author reghao
 * @date 2022-03-11 16:45:52
 */
@Slf4j
@Component
public class ProgressHandler implements WebSocketHandler {
    private final WsConnection wsConnection;
    private final ProgressService progressService;

    public ProgressHandler(WsConnection wsConnection, ProgressService progressService) {
        this.wsConnection = wsConnection;
        this.progressService = progressService;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws IOException {
        boolean ret = wsConnection.addSession(webSocketSession);
        if (ret) {
            log.info("WebSocket 建立连接");
        } else {
            log.info("没有认证信息, 关闭 WebSocket 连接");
            webSocketSession.close(CloseStatus.NO_STATUS_CODE);
        }
    }

    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage)
            throws IOException {
        if (webSocketMessage instanceof TextMessage) {
            dispatchTextMessage(webSocketSession, (TextMessage) webSocketMessage);
        } else if (webSocketMessage instanceof BinaryMessage) {
            log.info("接收到 WebSocket 二进制消息");
        } else if (webSocketMessage instanceof PingMessage) {
            log.info("接收到 WebSocket PingMessage");
        } else if (webSocketMessage instanceof PongMessage) {
            log.info("接收到 WebSocket PongMessage");
        } else {
            log.error("接收到未知类型的 WebSocket 消息");
        }
    }

    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) {
        log.error("WebSocket 数据传输错误");
        handleOnClose(webSocketSession);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) {
        log.info("WebSocket 断开连接");
        handleOnClose(webSocketSession);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    private void dispatchTextMessage(WebSocketSession webSocketSession, TextMessage textMessage) {
        String sessionId = webSocketSession.getId();
        String payload = textMessage.getPayload();
        try {
            EventReq eventReq = JsonConverter.jsonToObject(payload, EventReq.class);
            String event = eventReq.getEvent();
            switch (EventType.valueOf(event)) {
                case heartbeat:
                    wsConnection.sendHeartbeatPong(webSocketSession);
                    break;
                case media_progress:
                    String jsonData = eventReq.getData();
                    MediaProgress mediaProgress = JsonConverter.jsonToObject(jsonData, MediaProgress.class);
                    progressService.putMediaProgress(sessionId, mediaProgress);
                    break;
                default:
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void handleOnClose(WebSocketSession webSocketSession) {
        progressService.removeMediaProgress(webSocketSession.getId());
        wsConnection.removeUserSession(webSocketSession);
    }
}
