# -*- coding: utf-8 -*-
"""
Excel高级功能和优化测试
合并了优化功能、格式化工具、比较功能等高级特性的测试
这个文件替代了test_optimization_features.py, test_formatter.py等高级功能测试
"""

import pytest
import time
import tempfile
from pathlib import Path
import json
from dataclasses import dataclass
from typing import Any, Dict, List, Optional

from src.excel_mcp_server_fastmcp.core.excel_writer import ExcelWriter
from src.excel_mcp_server_fastmcp.core.excel_manager import ExcelManager
from src.excel_mcp_server_fastmcp.models.types import OperationResult
from src.excel_mcp_server_fastmcp.utils.formatter import (
    format_operation_result,
    _serialize_to_json_dict,
    _convert_to_compact_array_format,
    _deep_clean_nulls,
    _fallback_format_result
)


class TestExcelFeatures:
    """Excel高级功能和优化的综合测试"""

    # ==================== 中文字符处理优化测试 ====================

    def test_chinese_sheet_name_handling(self, sample_excel_file):
        """测试中文工作表名称处理优化"""
        manager = ExcelManager(sample_excel_file)

        # 测试合法名称应成功创建
        valid_cases = [
            ("数据分析", "数据分析"),  # 普通中文
            ("销售报表2024", "销售报表2024"),  # 中英文数字混合
            ("  空格测试  ", "空格测试"),  # 空格处理
        ]

        for input_name, expected_output in valid_cases:
            result = manager.create_sheet(input_name)
            assert result.success is True, f"创建工作表失败：{input_name}"
            assert result.data.name == expected_output, f"名称处理不正确：期望'{expected_output}'，实际'{result.data.name}'"

        # 测试含非法字符的名称应被拒绝（REQ-038: 不再静默替换）
        invalid_cases = [
            "测试/数据",   # 含斜杠
            "Sheet*Test",  # 含星号
            "数据[2024]",  # 含方括号
        ]

        for input_name in invalid_cases:
            result = manager.create_sheet(input_name)
            assert result.success is False, f"含非法字符的名称应被拒绝：{input_name}"
            assert "非法字符" in result.error, f"错误信息应提示非法字符：{result.error}"

    def test_chinese_sheet_long_name_handling(self, sample_excel_file):
        """测试超长中文工作表名称处理"""
        manager = ExcelManager(sample_excel_file)

        # Excel工作表名称限制是31个字符
        long_name = "很长的中文工作表名称测试超过三十一个字符的情况处理"
        result = manager.create_sheet(long_name)

        if result.success:
            # 如果成功，名称应该被适当处理
            assert len(result.data.name) <= 31, "工作表名称长度应该不超过31个字符"
        else:
            # 如果失败，应该有合理的错误信息
            assert isinstance(result.error, str)
            assert len(result.error) > 0

    def test_chinese_data_writing_optimization(self, sample_excel_file):
        """测试中文数据写入优化"""
        writer = ExcelWriter(sample_excel_file)

        chinese_data = [
            ["中文标题", "数值", "备注"],
            ["产品名称", 100, "库存充足"],
            ["服务项目", 200, "需要补充"],
            ["特殊符号测试", 300, "包含：、（）等符号"]
        ]

        result = writer.update_range("Sheet1!A1:C4", chinese_data)
        assert result.success is True
        assert len(result.data) == 12  # 4 rows * 3 columns

    def test_chinese_unicode_normalization(self, sample_excel_file):
        """测试Unicode规范化处理"""
        writer = ExcelWriter(sample_excel_file)

        # 测试不同Unicode编码的相同字符
        unicode_data = [
            ["标准中文"],
            ["繁體中文"],
            ["日本語"],
            ["한국어"]
        ]

        result = writer.update_range("Sheet1!A1:A4", unicode_data)
        assert result.success is True

    # ==================== 缓存机制测试 ====================

    def test_file_reading_cache_performance(self, sample_excel_file):
        """测试文件读取缓存性能优化"""
        from src.excel_mcp_server_fastmcp.core.excel_reader import ExcelReader

        reader = ExcelReader(sample_excel_file)

        # 第一次读取
        start_time = time.time()
        result1 = reader.get_range("Sheet1!A1:C10")
        first_duration = time.time() - start_time

        # 第二次读取（应该更快，如果有缓存）
        start_time = time.time()
        result2 = reader.get_range("Sheet1!A1:C10")
        second_duration = time.time() - start_time

        assert result1.success is True
        assert result2.success is True
        # 注意：缓存效果可能不明显在小文件上

    def test_workbook_caching_optimization(self, sample_excel_file):
        """测试工作簿缓存优化"""
        from src.excel_mcp_server_fastmcp.core.excel_reader import ExcelReader
        manager = ExcelManager(sample_excel_file)
        reader = ExcelReader(sample_excel_file)

        # 连续操作应该重用工作簿对象
        results = []
        for i in range(3):
            result = reader.list_sheets()  # 使用reader的list_sheets方法
            results.append(result)
            assert result.success is True

        # 所有操作都应该成功
        assert all(r.success for r in results)    # ==================== 格式化工具测试 ====================

    def test_format_operation_result_basic(self):
        """测试基础操作结果格式化"""
        @dataclass
        class MockResult:
            success: bool
            message: str
            data: List[str]

        result = MockResult(success=True, message="操作成功", data=["项目1", "项目2"])
        formatted = format_operation_result(result)

        assert isinstance(formatted, dict)
        assert formatted["success"] is True
        assert formatted["message"] == "操作成功"
        assert formatted["data"] == ["项目1", "项目2"]

    def test_json_serialization_chinese(self):
        """测试中文JSON序列化"""
        data = {
            "中文键": "中文值",
            "数字": 123,
            "布尔": True,
            "列表": ["项目1", "项目2", "项目3"]
        }

        serialized = _serialize_to_json_dict(data)
        assert isinstance(serialized, dict)
        assert serialized["中文键"] == "中文值"

    def test_compact_array_format_conversion(self):
        """测试紧凑数组格式转换"""
        # 创建模拟的结构化比较数据
        data = {
            'row_differences': [
                {
                    'row_id': '1',
                    'difference_type': 'row_modified',
                    'detailed_field_differences': [
                        {'field_name': '标题1', 'old_value': '数据1', 'new_value': '数据2', 'change_type': 'text_change'}
                    ]
                }
            ]
        }

        compact = _convert_to_compact_array_format(data)
        assert isinstance(compact, dict)
        assert 'row_differences' in compact

    def test_deep_clean_nulls(self):
        """测试深度null清理"""
        data_with_nulls = {
            "valid_key": "valid_value",
            "null_key": None,
            "empty_string": "",
            "nested": {
                "valid_nested": "value",
                "null_nested": None
            },
            "list_with_nulls": ["value1", None, "value3"]
        }

        cleaned = _deep_clean_nulls(data_with_nulls)
        assert "null_key" not in cleaned
        assert "valid_key" in cleaned
        assert cleaned["nested"]["valid_nested"] == "value"
        assert "null_nested" not in cleaned["nested"]

    def test_fallback_format_handling(self):
        """测试回退格式化处理"""
        # 创建一个无法序列化的对象
        class UnserializableObject:
            def __str__(self):
                raise Exception("Cannot serialize")

        problematic_data = UnserializableObject()
        exception = Exception("Mock exception")
        result = _fallback_format_result(type('MockResult', (), {
            'success': False,
            'message': 'Test error',
            'data': None,
            'metadata': None,
            'error': None
        })(), exception)

        assert isinstance(result, dict)
        assert "message" in result or "success" in result    # ==================== 错误处理优化测试 ====================

    def test_unified_error_handling(self, sample_excel_file):
        """测试统一错误处理机制"""
        from src.excel_mcp_server_fastmcp.core.excel_reader import ExcelReader
        from src.excel_mcp_server_fastmcp.core.excel_writer import ExcelWriter

        reader = ExcelReader(sample_excel_file)
        writer = ExcelWriter(sample_excel_file)

        # 测试各种错误情况的一致性
        errors = [
            reader.get_range("NonExistentSheet!A1:A1"),
            writer.update_range("NonExistentSheet!A1", [["test"]]),
        ]

        for error_result in errors:
            assert error_result.success is False
            assert isinstance(error_result.error, str)
            assert len(error_result.error) > 0

    def test_error_message_localization(self, sample_excel_file):
        """测试错误消息本地化"""
        manager = ExcelManager(sample_excel_file)

        # 尝试创建重复工作表名
        manager.create_sheet("TestSheet")  # First creation
        result = manager.create_sheet("TestSheet")  # Duplicate

        assert result.success is False
        assert isinstance(result.error, str)
        # 错误信息应该是中文或包含有意义的描述
        assert len(result.error) > 0

    # ==================== 性能优化测试 ====================

    def test_large_data_handling_optimization(self, sample_excel_file):
        """测试大数据处理优化"""
        writer = ExcelWriter(sample_excel_file)

        # 创建较大的测试数据
        large_data = []
        for i in range(100):
            large_data.append([f"行{i}", i, f"数据{i}", i * 2])

        start_time = time.time()
        result = writer.update_range("Sheet1!A1:D100", large_data)
        duration = time.time() - start_time

        assert result.success is True
        assert duration < 5.0  # 应该在5秒内完成
        assert len(result.data) == 400  # 100 rows * 4 columns

    def test_memory_efficiency_optimization(self, temp_dir):
        """测试内存效率优化"""
        import gc
        import tracemalloc

        tracemalloc.start()

        # 创建并操作多个文件
        for i in range(5):
            file_path = temp_dir / f"memory_test_{i}.xlsx"
            result = ExcelManager.create_file(str(file_path))
            assert result.success is True

        # 强制垃圾回收
        gc.collect()

        current, peak = tracemalloc.get_traced_memory()
        tracemalloc.stop()

        # 内存使用应该在合理范围内
        assert peak < 100 * 1024 * 1024  # 应该小于100MB

    # ==================== 兼容性测试 ====================

    def test_excel_version_compatibility(self, sample_excel_file):
        """测试Excel版本兼容性"""
        from src.excel_mcp_server_fastmcp.core.excel_reader import ExcelReader

        reader = ExcelReader(sample_excel_file)
        result = reader.list_sheets()

        assert result.success is True
        # 应该能够处理不同版本的Excel文件
        assert len(result.data) >= 1

    def test_file_format_compatibility(self, temp_dir):
        """测试文件格式兼容性"""
        # 测试.xlsx和.xlsm格式
        formats = [".xlsx", ".xlsm"]

        for ext in formats:
            file_path = temp_dir / f"compatibility_test{ext}"
            result = ExcelManager.create_file(str(file_path))

            if result.success:
                assert file_path.exists()
            else:
                # 某些格式可能不支持，但应该有清晰的错误信息
                assert isinstance(result.error, str)

    # ==================== 数据验证优化测试 ====================

    def test_data_type_validation(self, sample_excel_file):
        """测试数据类型验证优化"""
        writer = ExcelWriter(sample_excel_file)

        # 测试各种数据类型的处理
        mixed_data = [
            ["文本", 123, 45.67, True, None],
            ["更多文本", 456, 78.90, False, ""],
            [None, 0, -1.23, None, "空值测试"]
        ]

        result = writer.update_range("Sheet1!A1:E3", mixed_data)
        assert result.success is True
        # 修正期望值 - 空值不会生成修改记录
        assert len(result.data) >= 10  # 至少应该有10个有效的单元格修改    def test_formula_preservation_optimization(self, sample_excel_file):
        """测试公式保护优化"""
        writer = ExcelWriter(sample_excel_file)

        # 测试保护公式的写入
        result = writer.update_range("Sheet1!A1", [["新数据"]], preserve_formulas=True)
        assert result.success is True

        # 测试覆盖公式的写入
        result = writer.update_range("Sheet1!A2", [["覆盖数据"]], preserve_formulas=False)
        assert result.success is True

    # ==================== 集成优化测试 ====================

    def test_end_to_end_optimization_workflow(self, temp_dir):
        """测试端到端优化工作流"""
        file_path = temp_dir / "optimization_workflow.xlsx"

        # 1. 创建文件
        create_result = ExcelManager.create_file(str(file_path), ["数据表", "分析表"])
        assert create_result.success is True

        # 2. 写入中文数据
        writer = ExcelWriter(str(file_path))
        chinese_data = [
            ["产品名称", "销售额", "增长率"],
            ["智能手机", 100000, 0.15],
            ["笔记本电脑", 200000, 0.25]
        ]
        write_result = writer.update_range("数据表!A1:C3", chinese_data)
        assert write_result.success is True

        # 3. 读取数据验证
        from src.excel_mcp_server_fastmcp.core.excel_reader import ExcelReader
        reader = ExcelReader(str(file_path))
        read_result = reader.get_range("数据表!A1:C3")
        assert read_result.success is True
        assert len(read_result.data) == 3

        # 4. 工作表管理
        manager = ExcelManager(str(file_path))
        sheet_result = manager.create_sheet("报告表")
        assert sheet_result.success is True

    def test_optimization_features_compatibility(self, sample_excel_file):
        """测试优化功能兼容性"""
        # 确保所有优化功能可以协同工作
        from src.excel_mcp_server_fastmcp.core.excel_reader import ExcelReader

        reader = ExcelReader(sample_excel_file)
        writer = ExcelWriter(sample_excel_file)
        manager = ExcelManager(sample_excel_file)

        # 执行多个操作
        operations = [
            reader.get_range("Sheet1!A1:B2"),
            writer.update_range("Sheet1!C1", [["优化测试"]]),
            reader.list_sheets()  # 使用reader的list_sheets方法
        ]

        # 所有操作都应该成功
        for result in operations:
            assert result.success is True
            # 确保结果格式一致
            assert hasattr(result, 'success')
            assert hasattr(result, 'data')
            if not result.success:
                assert hasattr(result, 'error')
