package com.kexue.skills;

import com.kexue.skills.entity.PaymentOrder;
import com.kexue.skills.service.PayService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;
import java.util.UUID;

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

/**
 * 微信支付接口自测类
 */
@SpringBootTest
@ActiveProfiles("dev")  // 使用开发环境配置
class WechatPayTest {

    @Resource
    private PayService payService;

    private PaymentOrder testOrder;

    @BeforeEach
    void setUp() {
        // 准备测试订单数据
        testOrder = new PaymentOrder();
        testOrder.setUserId(1L);
        testOrder.setUserName("测试用户");
        testOrder.setProductName("测试商品-" + System.currentTimeMillis());
        testOrder.setProductDesc("这是一个测试商品");
        testOrder.setAmount(new BigDecimal("0.01"));  // 测试金额 0.01 元
        testOrder.setBusinessId(1L);
        testOrder.setBusinessType("purchase_content");
    }

    /**
     * 测试 1：创建微信支付订单 - 正常场景
     */
    @Test
    void testCreateWechatPay_Success() {
        System.out.println("========== 测试 1：创建微信支付订单（正常场景） ==========");
        
        try {
            // 生成唯一订单号
            String orderNo = "TEST_" + System.currentTimeMillis();
            testOrder.setOrderNo(orderNo);
            
            // 调用支付接口（传入测试 IP）
            Map<String, String> result = payService.createWechatPay(testOrder, "192.168.1.100");
            
            // 验证返回结果
            assertNotNull(result, "返回结果不应为空");
            assertTrue(result.containsKey("code_url"), "应包含 code_url");
            assertTrue(result.containsKey("order_no"), "应包含 order_no");
            
            System.out.println("✅ 测试通过！");
            System.out.println("订单号：" + result.get("order_no"));
            System.out.println("二维码链接：" + result.get("code_url"));
            
        } catch (Exception e) {
            System.err.println("❌ 测试失败：" + e.getMessage());
            e.printStackTrace();
            fail("创建微信支付订单失败：" + e.getMessage());
        }
    }

    /**
     * 测试 2：创建微信支付订单 - 金额为空
     */
    @Test
    void testCreateWechatPay_NullAmount() {
        System.out.println("\n========== 测试 2：金额为空（应抛出异常） ==========");
        
        testOrder.setOrderNo("TEST_NULL_AMOUNT_" + System.currentTimeMillis());
        testOrder.setAmount(null);  // 设置金额为空
        
        assertThrows(IllegalArgumentException.class, () -> {
            payService.createWechatPay(testOrder, "192.168.1.100");
        }, "金额为空时应抛出 IllegalArgumentException");
        
        System.out.println("✅ 测试通过：正确捕获了金额为空的异常");
    }

    /**
     * 测试 3：创建微信支付订单 - 金额过小
     */
    @Test
    void testCreateWechatPay_AmountTooSmall() {
        System.out.println("\n========== 测试 3：金额过小（应抛出异常） ==========");
        
        testOrder.setOrderNo("TEST_SMALL_AMOUNT_" + System.currentTimeMillis());
        testOrder.setAmount(new BigDecimal("0.001"));  // 小于 0.01 元
        
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
            payService.createWechatPay(testOrder, "192.168.1.100");
        });
        
        System.out.println("✅ 测试通过：捕获异常 - " + exception.getMessage());
    }

    /**
     * 测试 4：创建微信支付订单 - 金额过大
     */
    @Test
    void testCreateWechatPay_AmountTooLarge() {
        System.out.println("\n========== 测试 4：金额过大（应抛出异常） ==========");
        
        testOrder.setOrderNo("TEST_LARGE_AMOUNT_" + System.currentTimeMillis());
        testOrder.setAmount(new BigDecimal("200000"));  // 超过 10 万元
        
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
            payService.createWechatPay(testOrder, "192.168.1.100");
        });
        
        System.out.println("✅ 测试通过：捕获异常 - " + exception.getMessage());
    }

    /**
     * 测试 5：创建微信支付订单 - 订单号为空
     */
    @Test
    void testCreateWechatPay_NullOrderNo() {
        System.out.println("\n========== 测试 5：订单号为空（应抛出异常） ==========");
        
        testOrder.setOrderNo(null);  // 订单号为空
        
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
            payService.createWechatPay(testOrder, "192.168.1.100");
        });
        
        System.out.println("✅ 测试通过：捕获异常 - " + exception.getMessage());
    }

    /**
     * 测试 6：创建微信支付订单 - 订单号格式不正确
     */
    @Test
    void testCreateWechatPay_InvalidOrderNo() {
        System.out.println("\n========== 测试 6：订单号格式不正确（应抛出异常） ==========");
        
        testOrder.setOrderNo("TEST@INVALID#ORDER");  // 包含特殊字符
        
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
            payService.createWechatPay(testOrder, "192.168.1.100");
        });
        
        System.out.println("✅ 测试通过：捕获异常 - " + exception.getMessage());
    }

    /**
     * 测试 7：创建微信支付订单 - 订单号超长
     */
    @Test
    void testCreateWechatPay_OrderNoTooLong() {
        System.out.println("\n========== 测试 7：订单号超长（应抛出异常） ==========");
        
        testOrder.setOrderNo("TEST_" + UUID.randomUUID().toString().replace("-", ""));  // 超过 32 位
        
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
            payService.createWechatPay(testOrder, "192.168.1.100");
        });
        
        System.out.println("✅ 测试通过：捕获异常 - " + exception.getMessage());
    }

    /**
     * 测试 8：创建微信支付订单 - 商品名称为空
     */
    @Test
    void testCreateWechatPay_NullProductName() {
        System.out.println("\n========== 测试 8：商品名称为空（应抛出异常） ==========");
        
        testOrder.setOrderNo("TEST_NULL_PRODUCT_" + System.currentTimeMillis());
        testOrder.setProductName(null);  // 商品名称为空
        
        IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
            payService.createWechatPay(testOrder, "192.168.1.100");
        });
        
        System.out.println("✅ 测试通过：捕获异常 - " + exception.getMessage());
    }

    /**
     * 测试 9：创建微信支付订单 - IP 地址为 null（应使用默认值）
     */
    @Test
    void testCreateWechatPay_NullIpAddress() {
        System.out.println("\n========== 测试 9：IP 地址为 null（应使用默认 127.0.0.1） ==========");
        
        testOrder.setOrderNo("TEST_NULL_IP_" + System.currentTimeMillis());
        
        try {
            Map<String, String> result = payService.createWechatPay(testOrder, null);
            assertNotNull(result, "即使 IP 为 null，也应返回结果");
            System.out.println("✅ 测试通过：IP 为 null 时使用了默认值");
        } catch (Exception e) {
            fail("IP 为 null 时不应抛出异常：" + e.getMessage());
        }
    }

    /**
     * 测试 10：创建微信支付订单 - 长商品描述（应自动截断）
     */
    @Test
    void testCreateWechatPay_LongProductDescription() {
        System.out.println("\n========== 测试 10：长商品描述（应自动截断） ==========");
        
        testOrder.setOrderNo("TEST_LONG_DESC_" + System.currentTimeMillis());
        
        // 创建一个很长的商品描述（超过 128 字节）
        StringBuilder longDesc = new StringBuilder();
        for (int i = 0; i < 100; i++) {
            longDesc.append("这是非常长的商品描述测试");
        }
        testOrder.setProductName(longDesc.toString());
        
        try {
            Map<String, String> result = payService.createWechatPay(testOrder, "192.168.1.100");
            assertNotNull(result, "长描述应该也能成功创建订单");
            System.out.println("✅ 测试通过：长商品描述已自动处理");
        } catch (Exception e) {
            fail("长商品描述不应导致失败：" + e.getMessage());
        }
    }

    /**
     * 测试 11：边界值测试 - 最小金额
     */
    @Test
    void testCreateWechatPay_MinimumAmount() {
        System.out.println("\n========== 测试 11：最小金额边界测试（0.01 元） ==========");
        
        testOrder.setOrderNo("TEST_MIN_AMOUNT_" + System.currentTimeMillis());
        testOrder.setAmount(new BigDecimal("0.01"));  // 最小金额
        
        try {
            Map<String, String> result = payService.createWechatPay(testOrder, "192.168.1.100");
            assertNotNull(result, "最小金额应该可以成功下单");
            System.out.println("✅ 测试通过：0.01 元可以正常下单");
        } catch (Exception e) {
            fail("最小金额不应抛出异常：" + e.getMessage());
        }
    }

    /**
     * 测试 12：边界值测试 - 最大金额
     */
    @Test
    void testCreateWechatPay_MaximumAmount() {
        System.out.println("\n========== 测试 12：最大金额边界测试（100000 元） ==========");
        
        testOrder.setOrderNo("TEST_MAX_AMOUNT_" + System.currentTimeMillis());
        testOrder.setAmount(new BigDecimal("100000"));  // 最大金额限制
        
        try {
            Map<String, String> result = payService.createWechatPay(testOrder, "192.168.1.100");
            assertNotNull(result, "最大金额应该可以成功下单");
            System.out.println("✅ 测试通过：100000 元可以正常下单");
        } catch (Exception e) {
            fail("最大金额不应抛出异常：" + e.getMessage());
        }
    }

    /**
     * 测试 13：真实场景模拟 - 购买内容
     */
    @Test
    void testCreateWechatPay_PurchaseContent() {
        System.out.println("\n========== 测试 13：真实场景 - 购买内容 ==========");
        
        PaymentOrder order = new PaymentOrder();
        order.setOrderNo("BUY_" + System.currentTimeMillis());
        order.setUserId(1L);
        order.setUserName("张三");
        order.setAmount(new BigDecimal("9.99"));  // 9.99 元
        order.setProductName("AI 技能高级教程");
        order.setProductDesc("这是一套完整的 AI 技能培训课程，包含从入门到精通的所有内容。");
        order.setBusinessId(100L);
        order.setBusinessType("purchase_content");
        
        try {
            Map<String, String> result = payService.createWechatPay(order, "10.0.0.1");
            assertNotNull(result, "购买内容场景应成功");
            System.out.println("✅ 测试通过：购买内容场景模拟成功");
            System.out.println("订单号：" + result.get("order_no"));
        } catch (Exception e) {
            fail("购买内容场景不应失败：" + e.getMessage());
        }
    }

    /**
     * 测试 14：真实场景模拟 - 账户充值
     */
    @Test
    void testCreateWechatPay_Recharge() {
        System.out.println("\n========== 测试 14：真实场景 - 账户充值 ==========");
        
        PaymentOrder order = new PaymentOrder();
        order.setOrderNo("RECHARGE_" + System.currentTimeMillis());
        order.setUserId(1L);
        order.setUserName("李四");
        order.setAmount(new BigDecimal("100.00"));  // 充值 100 元
        order.setProductName("账户充值");
        order.setProductDesc("用户账户余额充值");
        order.setBusinessId(1L);
        order.setBusinessType("recharge");
        
        try {
            Map<String, String> result = payService.createWechatPay(order, "172.16.0.100");
            assertNotNull(result, "充值场景应成功");
            System.out.println("✅ 测试通过：账户充值场景模拟成功");
            System.out.println("充值金额：￥" + order.getAmount());
        } catch (Exception e) {
            fail("充值场景不应失败：" + e.getMessage());
        }
    }

    /**
     * 辅助方法：打印测试结果
     */
    private void printTestResult(String testName, boolean success, String message) {
        System.out.println("===========================================");
        System.out.println("测试：" + testName);
        System.out.println("状态：" + (success ? "✅ 通过" : "❌ 失败"));
        if (!success) {
            System.out.println("原因：" + message);
        }
        System.out.println("===========================================\n");
    }
}
