package com.lemon.testng;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class WebSocketFlowTest {

    private WebSocketClient webSocketClient;
    private CountDownLatch latch4Event3;
    private CountDownLatch latch4Event5;
    private String msgRemoteId;
     private String receivedRequestId;
    private String expectedRequestId;
    // 创建定时任务发送心跳消息
    private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private List<String> event5Messages = new ArrayList<>();
    Integer messageCount;


    @BeforeClass
    public void setup() throws URISyntaxException, InterruptedException {
        // 初始化 WebSocket 客户端并连接
        webSocketClient = new WebSocketClient(new URI("wss://wss.5rs.me/chat/ws")) {
            @Override
            public void onOpen(ServerHandshake handshake) {
                System.out.println("WebSocket连接已打开");
                System.out.println("连接状态: " + webSocketClient.isOpen());

            }

            @Override
            public void onMessage(String message) {
                System.out.println("收到消息: " + message);
                JSONObject receiveJson = JSONUtil.parseObj(message);
                Integer event = receiveJson.getInt("event");
                if (null == event) {
                    System.out.println("event为null，消息异常不处理");
                    return;
                }
                JSONObject messageBody = receiveJson.getJSONObject("messageBody");

                if (event == 3) {
                    // 提取并验证 requestId
                    receivedRequestId = receiveJson.getStr("requestId");
                    System.out.println("receivedRequestId是" + receivedRequestId + "、expectedRequestId是" + expectedRequestId);
                    if (receivedRequestId.equals(expectedRequestId)) {
                        if (null == messageBody) {
                            System.out.println("messageBody为null，消息异常不处理");
                            return;
                        }
                        msgRemoteId = messageBody.getStr("msgRemoteId");
                        latch4Event3.countDown();
                    }
                } else if (event == 5) {
                    // 处理 event-5 消息
                   if (null == messageBody) {
                       System.out.println("messageBody为null，消息异常不处理");
                       return;
                   }
                    String  msgRemoteId4Event5 = messageBody.getStr("msgRemoteId");
                    Boolean  stream = messageBody.getBool("stream");
                   if (msgRemoteId.equals(msgRemoteId4Event5)) {
                       latch4Event5.countDown();  // 结束接受消息
                   }
                   if(!stream) {
                        event5Messages.add(messageBody.getStr("message"));
                       latch4Event5.countDown();  // 每条非流式消息执行一次
                   }
                }
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                System.out.println("WebSocket连接已关闭，原因: " + reason);
            }

            @Override
            public void onError(Exception ex) {
                System.out.println("WebSocket出错: " + ex.getMessage());
            }
        };

        webSocketClient.connect();

        // 等待连接成功
        while (!webSocketClient.isOpen()) {
            Thread.sleep(100);
        }
    }


    @Test(priority = 1)
    public void testSendEvent2AndReceiveEvent3() throws Exception {
        try {
            messageCount = 2;
            // 设置 latch，等待服务端 event-3 响应
            latch4Event3 = new CountDownLatch(1);

            // 定义 requestId，发送 event-2 消息时使用，并在接收 event-3 时验证
             String event2Message = "{\"event\":2,\"sendType\":0,\"userId\":\"143773987\",\"officialAccountsId\":997,\"messageBody\":\"{\\\"contentType\\\":\\\"Text\\\",\\\"content\\\":{\\\"textMsgDTO\\\":{\\\"content\\\":\\\"一起学中文\\\"}},\\\"digitalPersonId\\\":\\\"2938\\\",\\\"language\\\":\\\"zh-CN\\\",\\\"chatTypeEnum\\\":\\\"\\\"}\",\"origin\":\"WEB_H5\",\"bookId\":\"12597711\",\"requestId\":\"W5dI5aII\"}";
            System.out.println("发送event2的消息是" + event2Message);
            JSONObject sendJson = JSONUtil.parseObj(event2Message);

            webSocketClient.send(event2Message);
            expectedRequestId = sendJson.getStr("requestId");
            System.out.println("expectedRequestId是" + expectedRequestId);




            // 等待最多 10 秒
            boolean event3Received = latch4Event3.await(10, TimeUnit.SECONDS);
            Assert.assertTrue(event3Received, "未在规定时间内收到 event-3 响应");
            System.out.println("收到的msgRemoteId是: " + msgRemoteId);

            // 验证 msgRemoteId 非空
            Assert.assertNotNull(msgRemoteId, "msgRemoteId 不应为空");
            // 验证 event-3 的 requestId 是否匹配
            System.out.println("receivedRequestId 是: " + receivedRequestId + "expectedRequestId 是: " + expectedRequestId);
            Assert.assertEquals(receivedRequestId, expectedRequestId, "收到的 requestId 不匹配");
        } catch (Exception e) {
            webSocketClient.close();
            System.out.println("testSendEvent2AndReceiveEvent3,WebSocket出错: " + e.getMessage());
            throw new Exception(e);
        }
    }

    @Test(priority = 2, dependsOnMethods = "testSendEvent2AndReceiveEvent3")
    public void testReceiveEvent5Responses() throws Exception {
        try {
            // 设置 latch，等待服务端 event-5 响应
            latch4Event5 = new CountDownLatch(messageCount);

            // 等待并验证 event-5 消息
            boolean event5Received = latch4Event5.await(20, TimeUnit.SECONDS);
            Assert.assertTrue(event5Received, "未在规定时间内收到 event-5 响应");

            // 验证 event-5 消息的内容
            System.out.println("event5 收到的消息是: " + JSONUtil.toJsonStr(event5Messages));
            Assert.assertNotNull(event5Messages, "event-5 消息不应为空");
         } catch (Exception e) {
            webSocketClient.close();
            System.out.println("testReceiveEvent5Responses,WebSocket出错: " + e.getMessage());
            throw new Exception(e);
        }
    }

    @AfterClass
    public void tearDown() {
        System.out.println("执行tearDown");
        // 关闭 WebSocket 连接
        if (webSocketClient != null) {
            System.out.println("执行 webSocketClient.close");
            webSocketClient.close();
        }
    }
}
