package com.sino.mci.send.service;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

import static com.sino.mci.test.AuthTestHelper.createTenantAndLogin;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
 * 出站发送端到端测试。
 *
 * <p>覆盖完整业务链路：创建租户 → 创建渠道主体 → 创建渠道账号 → 创建会话 → 绑定发送账号 →
 * 调用模拟发送接口 → 查询发送记录并校验字段。</p>
 */
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
class SendEndToEndTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldCompleteSendFlowFromTenantToRecord() throws Exception {
        String tenantCode = "send-e2e-" + UUID.randomUUID().toString().substring(0, 8);
        String authToken = createTenantAndLogin(mockMvc, tenantCode, "发送端到端测试");

        // 1. 创建渠道主体
        String subjectCode = "sub-" + UUID.randomUUID().toString().substring(0, 8);
        String subjectPayload = String.format(
                "{\"channelType\":\"wecom\",\"subjectCode\":\"%s\",\"subjectName\":\"E2E Subject\"}",
                subjectCode);
        String subjectResponse = mockMvc.perform(post("/msg-platform/api/v1/channel-subject")
                        .contextPath("/msg-platform")
                        .header("Authorization", authToken)
                        .header("X-Tenant-Code", tenantCode)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(subjectPayload))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(0))
                .andExpect(jsonPath("$.data.channelType").value("wecom"))
                .andReturn().getResponse().getContentAsString();
        Long subjectId = ((Number) com.jayway.jsonpath.JsonPath.read(subjectResponse, "$.data.id")).longValue();

        // 2. 创建渠道账号
        String accountPayload = String.format(
                "{\"accountType\":1,\"channelType\":\"wecom\",\"subjectId\":%d,\"accountId\":\"ZhangSan\",\"accountName\":\"张三\"}",
                subjectId);
        String accountResponse = mockMvc.perform(post("/msg-platform/api/v1/channel-account")
                        .contextPath("/msg-platform")
                        .header("Authorization", authToken)
                        .header("X-Tenant-Code", tenantCode)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(accountPayload))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(0))
                .andReturn().getResponse().getContentAsString();
        Long accountId = ((Number) com.jayway.jsonpath.JsonPath.read(accountResponse, "$.data.id")).longValue();

        // 3. 创建会话
        String channelConversationId = "room-" + UUID.randomUUID().toString().substring(0, 8);
        String conversationPayload = String.format(
                "{\"conversationType\":2,\"channelType\":\"wecom\",\"channelConversationId\":\"%s\",\"conversationName\":\"E2E群\",\"subjectId\":%d}",
                channelConversationId, subjectId);
        String conversationResponse = mockMvc.perform(post("/msg-platform/api/v1/conversation")
                        .contextPath("/msg-platform")
                        .header("Authorization", authToken)
                        .header("X-Tenant-Code", tenantCode)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(conversationPayload))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(0))
                .andReturn().getResponse().getContentAsString();
        Long conversationId = ((Number) com.jayway.jsonpath.JsonPath.read(conversationResponse, "$.data.id")).longValue();

        // 4. 绑定发送主号
        String bindPayload = String.format("{\"accountId\":%d,\"bindingType\":1,\"sortOrder\":1}", accountId);
        mockMvc.perform(post("/msg-platform/api/v1/conversation/" + conversationId + "/bind-account")
                        .contextPath("/msg-platform")
                        .header("Authorization", authToken)
                        .header("X-Tenant-Code", tenantCode)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(bindPayload))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(0));

        // 5. 发送消息（模拟发送）
        String sendPayload = String.format(
                "{\"targetType\":\"conversation\",\"targetValue\":{\"conversation_id\":%d},\"contentType\":\"text\",\"content\":{\"text\":\"hello e2e\"},\"channelStrategy\":{\"channel_type\":\"wecom\",\"strategy\":\"primary\"}}",
                conversationId);
        String sendResponse = mockMvc.perform(post("/msg-platform/api/v1/send/test")
                        .contextPath("/msg-platform")
                        .header("Authorization", authToken)
                        .header("X-Tenant-Code", tenantCode)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(sendPayload))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(0))
                .andExpect(jsonPath("$.data.totalCount").value(1))
                .andExpect(jsonPath("$.data.status").value("simulated"))
                .andReturn().getResponse().getContentAsString();
        String taskId = com.jayway.jsonpath.JsonPath.read(sendResponse, "$.data.taskId");

        // 6. 查询发送记录并校验
        mockMvc.perform(get("/msg-platform/api/v1/send/" + taskId + "/records")
                        .contextPath("/msg-platform")
                        .header("Authorization", authToken)
                        .header("X-Tenant-Code", tenantCode))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(0))
                .andExpect(jsonPath("$.data.length()").value(1))
                .andExpect(jsonPath("$.data[0].taskId").value(taskId))
                .andExpect(jsonPath("$.data[0].sendStatus").value(2))
                .andExpect(jsonPath("$.data[0].channelType").value("wecom"))
                .andExpect(jsonPath("$.data[0].conversationId").value(conversationId))
                .andExpect(jsonPath("$.data[0].accountId").value(accountId))
                .andExpect(jsonPath("$.data[0].contentType").value("text"))
                .andExpect(jsonPath("$.data[0].contentBody").value(org.hamcrest.Matchers.containsString("hello e2e")));
    }
}
