package com.gxwebsoft.common.core.utils;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import javax.annotation.Resource;
import java.util.Map;

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

/**
 * 加密二维码工具类测试
 *
 * @author WebSoft
 * @since 2025-08-18
 */
@SpringBootTest
@ActiveProfiles("dev")
public class EncryptedQrCodeUtilTest {

    @Resource
    private EncryptedQrCodeUtil encryptedQrCodeUtil;

    @Test
    public void testGenerateAndDecryptData() {
        // 测试数据
        String originalData = "https://www.example.com/user/123";
        Long expireMinutes = 30L;

        // 生成加密数据
        Map<String, String> encryptedInfo = encryptedQrCodeUtil.generateEncryptedData(originalData, expireMinutes);

        assertNotNull(encryptedInfo);
        assertNotNull(encryptedInfo.get("token"));
        assertNotNull(encryptedInfo.get("encryptedData"));
        assertEquals(expireMinutes.toString(), encryptedInfo.get("expireMinutes"));

        // 解密数据
        String decryptedData = encryptedQrCodeUtil.decryptData(
            encryptedInfo.get("token"),
            encryptedInfo.get("encryptedData")
        );

        assertEquals(originalData, decryptedData);
    }

    @Test
    public void testGenerateEncryptedQrCode() {
        // 测试数据
        String originalData = "测试二维码数据";
        int width = 300;
        int height = 300;
        Long expireMinutes = 60L;

        // 生成加密二维码
        Map<String, Object> result = encryptedQrCodeUtil.generateEncryptedQrCode(
            originalData, width, height, expireMinutes
        );

        assertNotNull(result);
        assertNotNull(result.get("qrCodeBase64"));
        assertNotNull(result.get("token"));
        assertEquals(originalData, result.get("originalData"));
        assertEquals(expireMinutes.toString(), result.get("expireMinutes"));
    }

    @Test
    public void testTokenValidation() {
        // 生成测试数据
        String originalData = "token验证测试";
        Map<String, String> encryptedInfo = encryptedQrCodeUtil.generateEncryptedData(originalData, 30L);
        String token = encryptedInfo.get("token");

        // 验证token有效性
        assertTrue(encryptedQrCodeUtil.isTokenValid(token));

        // 使token失效
        encryptedQrCodeUtil.invalidateToken(token);

        // 再次验证token应该无效
        assertFalse(encryptedQrCodeUtil.isTokenValid(token));
    }

    @Test
    public void testInvalidToken() {
        // 测试无效token
        assertFalse(encryptedQrCodeUtil.isTokenValid("invalid_token"));
        assertFalse(encryptedQrCodeUtil.isTokenValid(""));
        assertFalse(encryptedQrCodeUtil.isTokenValid(null));
    }

    @Test
    public void testDecryptWithInvalidToken() {
        // 测试用无效token解密
        assertThrows(RuntimeException.class, () -> {
            encryptedQrCodeUtil.decryptData("invalid_token", "encrypted_data");
        });
    }

    @Test
    public void testGenerateEncryptedQrCodeWithBusinessType() {
        // 测试数据
        String originalData = "用户登录数据";
        int width = 200;
        int height = 200;
        Long expireMinutes = 30L;
        String businessType = "LOGIN";

        // 生成带业务类型的加密二维码
        Map<String, Object> result = encryptedQrCodeUtil.generateEncryptedQrCode(
            originalData, width, height, expireMinutes, businessType
        );

        assertNotNull(result);
        assertNotNull(result.get("qrCodeBase64"));
        assertNotNull(result.get("token"));
        assertEquals(originalData, result.get("originalData"));
        assertEquals(expireMinutes.toString(), result.get("expireMinutes"));
        assertEquals(businessType, result.get("businessType"));

        System.out.println("=== 带BusinessType的二维码生成测试 ===");
        System.out.println("原始数据: " + originalData);
        System.out.println("业务类型: " + businessType);
        System.out.println("Token: " + result.get("token"));
        System.out.println("二维码Base64长度: " + ((String)result.get("qrCodeBase64")).length());

        // 验证不传businessType的情况
        Map<String, Object> resultWithoutType = encryptedQrCodeUtil.generateEncryptedQrCode(
            originalData, width, height, expireMinutes
        );

        assertNull(resultWithoutType.get("businessType"));
        System.out.println("不传BusinessType时的结果: " + resultWithoutType.get("businessType"));
    }
}
