package com.sjyt.icom.asst.endpoint;

import com.google.gson.JsonSyntaxException;
import com.sjyt.icom.asst.common.enums.ErrorCodeEnum;
import com.sjyt.icom.asst.common.enums.MsgTypeEnum;
import com.sjyt.icom.asst.common.model.message.News;
import com.sjyt.icom.asst.common.model.room.IcomClient;
import com.sjyt.icom.asst.common.model.sdp.RespError;
import com.sjyt.icom.asst.common.util.JsonUtils;
import com.sjyt.icom.asst.context.handle.cmd.IComMsgHandle;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.MultiValueMap;
import org.yeauty.annotation.*;
import org.yeauty.pojo.Session;

import java.io.IOException;
import java.util.Map;
import java.util.Optional;

/**
 * <p>TODO</p>
 *
 * @author renyanru
 * @version V1.0.0
 * @date 2022/6/30 17:00
 */
@Slf4j
@AllArgsConstructor
@ServerEndpoint(path = "/icom/{arg}", host = "${ws.icom.host}", port = "${ws.icom.port}", readerIdleTimeSeconds = "55")
public class WsEndpoint {
    private final BeanResolvable beanResolvable;
    private final IComMsgHandle iComMsgHandle;

    @BeforeHandshake
    public void handshake(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap<String, Object> reqMap, @PathVariable String arg, @PathVariable Map<String, Object> pathMap) {
        //todo 校验用户合法性
        log.debug("客户端认证参数：{}", arg);
        if (!"1".equals(arg)) {
            log.error("Authentication failed!");
            session.sendText("Authentication failed!");
            session.close();
        }
    }

    @OnOpen
    public void onOpen(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap<String, Object> reqMap, @PathVariable String arg, @PathVariable Map<String,Object> pathMap) {
        log.info("新的连接加入，用户id为：{}", arg);
        //todo 用户id解码
        final IcomClient client = IcomClient.builder().uid(arg).session(session).build();
        beanResolvable.addSession(arg, client);
    }

    @OnClose
    public void onClose(Session session) throws IOException {
        log.info("连接断开，连接id为：{}", session.id());
        beanResolvable.removeSession(session);
    }

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

    @OnMessage
    public void onMessage(Session session, String message) {
        session.sendText("Hello Netty!");
        log.info("收到来自客户端的消息");
        Optional.ofNullable(message).map(msg -> {
            News news = null;
            try {
                news = JsonUtils.jsonToPojo(msg, News.class);
            } catch (JsonSyntaxException e) {
                log.error(ErrorCodeEnum.REQ_PARAM_ERROR.getVALUE() + "{}", e.getMessage());
                RespError respError = RespError.builder().msgType(MsgTypeEnum.RespError.getCODE()).msg(ErrorCodeEnum.REQ_PARAM_ERROR.getVALUE())
                        .code(ErrorCodeEnum.REQ_PARAM_ERROR.getCode()).build();
                session.sendText(JsonUtils.pojoToJson(respError));
            }
            return news;
        }).ifPresent(iComMsgHandle::todo);
    }

    @OnBinary
    public void onBinary(Session session, byte[] bytes) {
        for (byte b : bytes) {
            System.out.println(b);
        }
        session.sendBinary(bytes);
    }

    @OnEvent
    public void onEvent(Session session, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    log.info("read idle");
                    break;
                case WRITER_IDLE:
                    log.info("write idle");
                    break;
                case ALL_IDLE:
                    log.info("all idle");
                    break;
                default:
                    break;
            }
        }
    }
}
