package cn.hztech.sdk.server;

import cn.hztech.sdk.api.ApiManagementApiClient;
import cn.hztech.sdk.integration.BaseIntegrationTest;
import cn.hztech.sdk.model.PageResult;
import cn.hztech.sdk.model.entity.ApiMetadata;
import cn.hztech.sdk.model.request.ApiCreateRequest;
import cn.hztech.sdk.model.request.ApiListRequest;
import cn.hztech.sdk.model.request.ApiUpdateRequest;
import org.junit.jupiter.api.*;

import static org.junit.jupiter.api.Assertions.*;

/**
 * ApiManagement API服务端集成测试
 * <p>
 * 测试接口管理相关的所有API接口
 * <p>
 * 前置条件：
 * <ul>
 *   <li>platform-server已启动（端口8080）</li>
 *   <li>使用test profile启动</li>
 * </ul>
 * <p>
 * 测试说明：
 * <ul>
 *   <li>测试按CRUD顺序执行（创建→查询→更新→列表→删除）</li>
 *   <li>使用唯一的时间戳确保每次测试数据不冲突</li>
 *   <li>即使测试失败也会尝试清理测试数据</li>
 * </ul>
 * <p>
 * 运行方式：
 * <pre>
 * # 启动服务器
 * cd sdk/platform-server
 * mvn spring-boot:run -Dspring.profiles.active=test
 *
 * # 运行测试
 * mvn test -Dtest=ApiManagementApiClientServerIntegrationTest
 * </pre>
 *
 * @author SDK Team
 * @since 1.0.0
 */
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ApiManagementApiClientServerIntegrationTest extends BaseIntegrationTest {

    private ApiManagementApiClient apiManagementApiClient;

    /**
     * 存储创建的API ID,用于后续测试
     */
    private static String createdApiId;

    /**
     * 存储创建的API编码,用于后续测试
     */
    private static String createdApiCode;

    @BeforeEach
    void setUp() {
        apiManagementApiClient = new ApiManagementApiClient(httpClient);
    }

    @Test
    @Order(1)
    @DisplayName("测试创建接口元数据 - 成功场景")
    void testCreate_Success() {
        System.out.println("\n=== 测试创建接口元数据 ===");

        try {
            // Arrange - 准备测试数据
            String timestamp = String.valueOf(System.currentTimeMillis());

            ApiCreateRequest request = new ApiCreateRequest();
            request.setApiName("测试API " + timestamp);
            request.setApiCode("TEST_API_" + timestamp);
            request.setApiPath("/test/api/" + timestamp);
            request.setApiMethod("POST");
            request.setDescription("这是一个测试API");

            // Act - 执行API调用
            ApiMetadata result = apiManagementApiClient.create(request);

            // Assert - 验证结果
            assertNotNull(result, "创建结果不应为空");
            assertNotNull(result.getId(), "API ID不应为空");

            // 存储创建的API信息用于后续测试
            createdApiId = result.getId();
            createdApiCode = request.getApiCode();

            System.out.println("✓ 接口元数据创建成功");
            System.out.println("  API ID: " + createdApiId);
            System.out.println("  API名称: " + request.getApiName());
            System.out.println("  API编码: " + createdApiCode);
            System.out.println("  API路径: " + request.getApiPath());
        } catch (Exception e) {
            System.err.println("✗ 接口元数据创建失败: " + e.getMessage());
            e.printStackTrace();
            fail("接口元数据创建失败: " + e.getMessage());
        }
    }

    @Test
    @Order(2)
    @DisplayName("测试查询接口详情 - 成功场景")
    void testGetDetail_Success() {
        System.out.println("\n=== 测试查询接口详情 ===");

        // 确保前置测试已执行
//        assertNotNull(createdApiId, "API ID应已从create测试中设置,请确保测试按顺序执行");

        try {
            // Act - 执行API调用
            ApiMetadata result = apiManagementApiClient.getDetail(createdApiId);
//            ApiMetadata result = apiManagementApiClient.getDetail("xxx");

            // Assert - 验证结果
            assertNotNull(result, "查询结果不应为空");
            assertEquals(createdApiId, result.getId(), "API ID应匹配");
            assertEquals(createdApiCode, result.getApiCode(), "API编码应匹配");
            assertNotNull(result.getApiName(), "API名称不应为空");

            System.out.println("✓ 接口详情查询成功");
            System.out.println("  API ID: " + result.getId());
            System.out.println("  API名称: " + result.getApiName());
            System.out.println("  API编码: " + result.getApiCode());
            System.out.println("  API路径: " + result.getApiPath());
            System.out.println("  API方法: " + result.getApiMethod());
        } catch (Exception e) {
            System.err.println("✗ 接口详情查询失败: " + e.getMessage());
            e.printStackTrace();
            fail("接口详情查询失败: " + e.getMessage());
        }
    }

    @Test
    @Order(3)
    @DisplayName("测试更新接口元数据 - 成功场景")
    void testUpdate_Success() {
        System.out.println("\n=== 测试更新接口元数据 ===");

        // 确保前置测试已执行
        assertNotNull(createdApiId, "API ID应已从create测试中设置,请确保测试按顺序执行");

        try {
            // Arrange - 准备测试数据
            ApiUpdateRequest request = new ApiUpdateRequest();
            request.setId(createdApiId);
            request.setApiName("更新后的测试API");
            request.setApiCode(createdApiCode);
            request.setApiPath("/test/api/updated");
            request.setApiMethod("PUT");
            request.setDescription("这是更新后的测试API描述");

            // Act - 执行API调用
            ApiMetadata result = apiManagementApiClient.update(request);

            // Assert - 验证结果
            assertNotNull(result, "更新结果不应为空");
            assertEquals(createdApiId, result.getId(), "API ID应匹配");
            assertEquals("更新后的测试API", result.getApiName(), "API名称应已更新");

            System.out.println("✓ 接口元数据更新成功");
            System.out.println("  API ID: " + result.getId());
            System.out.println("  更新后名称: " + result.getApiName());
            System.out.println("  更新后描述: " + result.getDescription());
        } catch (Exception e) {
            System.err.println("✗ 接口元数据更新失败: " + e.getMessage());
            e.printStackTrace();
            fail("接口元数据更新失败: " + e.getMessage());
        }
    }

    @Test
    @Order(4)
    @DisplayName("测试查询接口列表 - 成功场景")
    void testGetList_Success() {
        System.out.println("\n=== 测试查询接口列表 ===");

        try {
            // Arrange - 准备测试数据
            ApiListRequest request = new ApiListRequest();
            request.setPageNum(1);
            request.setPageSize(10);

            // Act - 执行API调用
            PageResult<ApiMetadata> pageResult = apiManagementApiClient.getList(request);

            // Assert - 验证结果
            assertNotNull(pageResult, "分页结果不应为空");
            assertNotNull(pageResult.getList(), "接口列表不应为空");
            assertTrue(pageResult.getList().size() > 0, "接口列表应该有数据");

            System.out.println("✓ 接口列表查询成功");
            System.out.println("  总数: " + pageResult.getTotal());
            System.out.println("  当前页: " + pageResult.getPageNum());
            System.out.println("  页大小: " + pageResult.getPageSize());
            System.out.println("  接口数: " + pageResult.getList().size());

            // 验证我们创建的API在列表中
            boolean found = pageResult.getList().stream()
                .anyMatch(api -> createdApiId != null && createdApiId.equals(api.getId()));

            if (found) {
                System.out.println("  ✓ 找到刚创建的测试API");
            }
        } catch (Exception e) {
            System.err.println("✗ 接口列表查询失败: " + e.getMessage());
            e.printStackTrace();
            fail("接口列表查询失败: " + e.getMessage());
        }
    }

    @Test
    @Order(5)
    @DisplayName("测试删除接口元数据 - 成功场景")
    void testDelete_Success() {
        System.out.println("\n=== 测试删除接口元数据 ===");

        // 确保前置测试已执行
        assertNotNull(createdApiId, "API ID应已从create测试中设置,请确保测试按顺序执行");

        try {
            // Act - 执行API调用
            apiManagementApiClient.delete(createdApiId);

            System.out.println("✓ 接口元数据删除成功");
            System.out.println("  已删除API ID: " + createdApiId);

            // 验证删除后查询会失败或返回空
            // 注意:这里可能会抛出异常,取决于服务器实现
            try {
                ApiMetadata result = apiManagementApiClient.getDetail(createdApiId);
                // 如果没有抛出异常,检查结果是否为空
                if (result != null) {
                    System.out.println("  警告: 删除后仍能查询到API,可能是服务器未实现物理删除");
                }
            } catch (Exception e) {
                // 预期行为:删除后查询应该失败
                System.out.println("  ✓ 验证成功: 删除后查询API失败,符合预期");
            }

        } catch (Exception e) {
            System.err.println("✗ 接口元数据删除失败: " + e.getMessage());
            e.printStackTrace();
            fail("接口元数据删除失败: " + e.getMessage());
        }
    }
}
