"""二维码服务测试脚本

使用方法:
    python test_qrcode.py

测试内容:
    1. 生成二维码
    2. 解析生成的二维码
    3. 测试不同的预处理策略
    4. 测试错误处理
"""
import asyncio
import os
import sys
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent.parent.parent
sys.path.insert(0, str(project_root))

from app.services.workcase.qrcode import QrCodeService


class QRCodeTester:
    """二维码服务测试类"""

    def __init__(self):
        self.service = QrCodeService()
        self.test_results = []

    def print_header(self, title: str):
        """打印测试标题"""
        print("\n" + "=" * 60)
        print(f"  {title}")
        print("=" * 60)

    def print_result(self, test_name: str, success: bool, details: str = ""):
        """打印测试结果"""
        status = "✓ 通过" if success else "✗ 失败"
        print(f"\n{status} - {test_name}")
        if details:
            print(f"  详情: {details}")
        self.test_results.append((test_name, success))

    async def test_generate_qrcode(self):
        """测试生成二维码"""
        self.print_header("测试1: 生成二维码")

        # 测试1.1: 基本生成
        result = await self.service.generate_qrcode(
            content="https://github.com",
            size=300,
            error_correction="H"
        )

        if result["success"] and "image" in result:
            self.print_result(
                "1.1 基本生成",
                True,
                f"内容长度: {len(result['image'])} 字符"
            )
            # 保存生成的图片用于后续测试
            self.generated_image = result["image"]
        else:
            self.print_result("1.1 基本生成", False, result.get("error", "未知错误"))
            self.generated_image = None

        # 测试1.2: 不同纠错级别
        for level in ["L", "M", "Q", "H"]:
            result = await self.service.generate_qrcode(
                content="测试内容",
                size=200,
                error_correction=level
            )
            self.print_result(
                f"1.2 纠错级别 {level}",
                result["success"],
                f"图片大小: {result.get('size', 'N/A')}"
            )

        # 测试1.3: 参数验证
        result = await self.service.generate_qrcode(
            content="",
            size=300,
            error_correction="H"
        )
        self.print_result(
            "1.3 空内容验证",
            not result["success"],
            result.get("error", "")
        )

        # 测试1.4: 无效尺寸
        result = await self.service.generate_qrcode(
            content="test",
            size=50,  # 太小
            error_correction="H"
        )
        self.print_result(
            "1.4 无效尺寸验证",
            not result["success"],
            result.get("error", "")
        )

    async def test_parse_qrcode(self):
        """测试解析二维码"""
        self.print_header("测试2: 解析二维码")

        if not self.generated_image:
            print("⚠ 跳过解析测试（没有生成的图片）")
            return

        # 测试2.1: 解析自己生成的二维码
        result = await self.service.parse_qrcode(
            image_source=self.generated_image,
            strategy="auto"
        )

        if result["success"]:
            self.print_result(
                "2.1 解析生成的二维码",
                True,
                f"内容: {result['content']}, 尝试次数: {result.get('total_attempts', 0)}"
            )
        else:
            self.print_result(
                "2.1 解析生成的二维码",
                False,
                result.get("error", "未知错误")
            )

        # 测试2.2: 测试不同策略
        for strategy in ["basic", "auto", "enhanced"]:
            result = await self.service.parse_qrcode(
                image_source=self.generated_image,
                strategy=strategy
            )
            self.print_result(
                f"2.2 策略 {strategy}",
                result["success"],
                f"尝试次数: {result.get('total_attempts', 0)}"
            )

        # 测试2.3: 无效输入
        result = await self.service.parse_qrcode(
            image_source="",
            strategy="auto"
        )
        self.print_result(
            "2.3 空图片源验证",
            not result["success"],
            result.get("error", "")
        )

    async def test_validate_content(self):
        """测试内容验证"""
        self.print_header("测试3: 内容验证")

        # 测试3.1: 正常内容
        result = self.service.validate_qrcode_content("https://example.com")
        self.print_result(
            "3.1 正常内容",
            result["valid"],
            f"长度: {result.get('length', 0)} 字节"
        )

        # 测试3.2: 空内容
        result = self.service.validate_qrcode_content("")
        self.print_result(
            "3.2 空内容",
            not result["valid"],
            result.get("error", "")
        )

        # 测试3.3: 超长内容
        long_content = "a" * 3000
        result = self.service.validate_qrcode_content(long_content)
        self.print_result(
            "3.3 超长内容",
            not result["valid"],
            result.get("error", "")
        )

        # 测试3.4: 中文内容
        result = self.service.validate_qrcode_content("这是一段中文测试内容")
        self.print_result(
            "3.4 中文内容",
            result["valid"],
            f"长度: {result.get('length', 0)} 字节"
        )

    async def test_integration(self):
        """集成测试：生成 -> 解析 -> 验证"""
        self.print_header("测试4: 集成测试")

        test_contents = [
            "https://github.com",
            "简单文本",
            "{'key': 'value', 'number': 123}",  # JSON
            "mailto:test@example.com",
            "tel:+86-123-4567-8900"
        ]

        for idx, content in enumerate(test_contents, 1):
            # 生成
            gen_result = await self.service.generate_qrcode(
                content=content,
                size=300,
                error_correction="H"
            )

            if not gen_result["success"]:
                self.print_result(
                    f"4.{idx} 集成测试: {content[:20]}...",
                    False,
                    "生成失败"
                )
                continue

            # 解析
            parse_result = await self.service.parse_qrcode(
                image_source=gen_result["image"],
                strategy="auto"
            )

            # 验证内容是否一致
            success = (
                parse_result["success"] and
                parse_result.get("content") == content
            )

            self.print_result(
                f"4.{idx} {content[:30]}",
                success,
                f"原始: {content[:20]}... | 解析: {parse_result.get('content', '')[:20]}..."
            )

    async def test_error_handling(self):
        """测试错误处理"""
        self.print_header("测试5: 错误处理")

        # 测试5.1: 无效的图片URL
        result = await self.service.parse_qrcode(
            image_source="https://invalid-url-that-does-not-exist.com/image.png",
            strategy="auto"
        )
        self.print_result(
            "5.1 无效URL处理",
            not result["success"],
            result.get("error", "")[:50]
        )

        # 测试5.2: 无效的base64
        result = await self.service.parse_qrcode(
            image_source="data:image/png;base64,invalid_base64",
            strategy="auto"
        )
        self.print_result(
            "5.2 无效base64处理",
            not result["success"],
            result.get("error", "")[:50]
        )

        # 测试5.3: 无效的纠错级别
        result = await self.service.generate_qrcode(
            content="test",
            size=300,
            error_correction="X"  # 无效
        )
        self.print_result(
            "5.3 无效纠错级别",
            not result["success"],
            result.get("error", "")
        )

    def print_summary(self):
        """打印测试总结"""
        self.print_header("测试总结")

        total = len(self.test_results)
        passed = sum(1 for _, success in self.test_results if success)
        failed = total - passed

        print(f"\n总测试数: {total}")
        print(f"通过: {passed} (✓)")
        print(f"失败: {failed} (✗)")
        print(f"成功率: {passed/total*100:.1f}%\n")

        if failed > 0:
            print("失败的测试:")
            for name, success in self.test_results:
                if not success:
                    print(f"  - {name}")

    async def run_all_tests(self):
        """运行所有测试"""
        print("\n" + "=" * 60)
        print("  二维码服务测试套件")
        print("=" * 60)

        try:
            await self.test_generate_qrcode()
            await self.test_parse_qrcode()
            await self.test_validate_content()
            await self.test_integration()
            await self.test_error_handling()

            self.print_summary()

        except Exception as e:
            print(f"\n❌ 测试过程中出现错误: {str(e)}")
            import traceback
            traceback.print_exc()


async def main():
    """主函数"""
    tester = QRCodeTester()
    await tester.run_all_tests()


if __name__ == "__main__":
    # 运行测试
    asyncio.run(main())
