"""测试用例和API文档模块。"""

from pathlib import Path
from typing import Any

import pytest

from src.symphra_excel import (
    CellStyle,
    Color,
    PredefinedStyles,
    ValidationError,
    Workbook,
)

# 可选导入，如果模块不存在则跳过相关测试
try:
    from src.symphra_excel import AsyncWorkbook, InMemoryWorkbook, TemplateWorkbook

    HAS_TEMPLATE_WORKBOOK = True
    HAS_ASYNC_WORKBOOK = True
    HAS_INMEMORY_WORKBOOK = True
except ImportError:
    HAS_TEMPLATE_WORKBOOK = False
    HAS_ASYNC_WORKBOOK = False
    HAS_INMEMORY_WORKBOOK = False


class TestWorkbook:
    """工作簿测试类。"""

    def test_create_workbook(self) -> None:
        """测试创建工作簿。"""
        workbook = Workbook()
        assert workbook is not None
        assert len(workbook.get_sheet_names()) == 1

    def test_create_worksheet(self) -> None:
        """测试创建工作表。"""
        workbook = Workbook()
        sheet = workbook.create_worksheet("TestSheet")
        assert sheet is not None
        assert "TestSheet" in workbook.get_sheet_names()

    def test_get_worksheet(self) -> None:
        """测试获取工作表。"""
        workbook = Workbook()
        workbook.create_worksheet("TestSheet")
        sheet = workbook.get_worksheet("TestSheet")
        assert sheet is not None
        assert sheet.name == "TestSheet"

    def test_delete_worksheet(self) -> None:
        """测试删除工作表。"""
        workbook = Workbook()
        workbook.create_worksheet("TestSheet")
        result = workbook.delete_worksheet("TestSheet")
        assert result is True
        assert "TestSheet" not in workbook.get_sheet_names()

    def test_save_and_load(self, tmp_path: Path) -> None:
        """测试保存和加载。"""
        # 创建测试工作簿
        workbook = Workbook()
        sheet = workbook.create_worksheet("TestSheet")
        sheet.set_cell_value("A1", "Hello World")

        # 保存到文件
        file_path = tmp_path / "test.xlsx"
        workbook.save(file_path)

        # 从文件加载
        loaded_workbook = Workbook.load(file_path)
        loaded_sheet = loaded_workbook.get_worksheet("TestSheet")
        assert loaded_sheet is not None
        assert loaded_sheet.get_cell_value("A1") == "Hello World"

    def test_save_to_memory(self) -> None:
        """测试保存到内存。"""
        workbook = Workbook()
        sheet = workbook.create_worksheet("TestSheet")
        sheet.set_cell_value("A1", "Memory Test")

        data = workbook.save_to_memory()
        assert isinstance(data, bytes)
        assert len(data) > 0


class TestWorksheet:
    """工作表测试类。"""

    def test_set_get_cell_value(self) -> None:
        """测试设置和获取单元格值。"""
        workbook = Workbook()
        sheet = workbook.create_worksheet("TestSheet")

        # 测试字符串值
        sheet.set_cell_value("A1", "Test String")
        assert sheet.get_cell_value("A1") == "Test String"

        # 测试数字值
        sheet.set_cell_value("B1", 123.45)
        assert sheet.get_cell_value("B1") == 123.45

        # 测试公式
        sheet.set_cell_value("C1", "=A1+B1")
        # 注意：openpyxl不会计算公式值，只存储公式
        assert sheet.get_cell_value("C1") == "=A1+B1"

    def test_set_get_range_values(self) -> None:
        """测试设置和获取范围值。"""
        workbook = Workbook()
        sheet = workbook.create_worksheet("TestSheet")

        values: list[list[Any]] = [
            ["Name", "Age", "City"],
            ["Alice", 25, "New York"],
            ["Bob", 30, "London"],
        ]

        sheet.set_range_values("A1", values)
        retrieved_values = sheet.get_range_values("A1:C3")

        assert len(retrieved_values) == 3
        assert retrieved_values[0][0] == "Name"
        assert retrieved_values[1][1] == 25

    def test_insert_delete_rows(self) -> None:
        """测试插入和删除行。"""
        workbook = Workbook()
        sheet = workbook.create_worksheet("TestSheet")

        # 设置初始数据
        sheet.set_cell_value("A1", "Row 1")
        sheet.set_cell_value("A2", "Row 2")
        sheet.set_cell_value("A3", "Row 3")

        # 插入新行
        sheet.insert_rows(2)
        assert sheet.get_cell_value("A1") == "Row 1"
        assert sheet.get_cell_value("A3") == "Row 2"  # 原A2下移
        assert sheet.get_cell_value("A4") == "Row 3"  # 原A3下移

        # 删除行
        sheet.delete_rows(2)
        assert sheet.get_cell_value("A1") == "Row 1"
        assert sheet.get_cell_value("A2") == "Row 2"  # 恢复原A2
        assert sheet.get_cell_value("A3") == "Row 3"  # 恢复原A3

    def test_insert_delete_columns(self) -> None:
        """测试插入和删除列。"""
        workbook = Workbook()
        sheet = workbook.create_worksheet("TestSheet")

        # 设置初始数据
        sheet.set_cell_value("A1", "Col 1")
        sheet.set_cell_value("B1", "Col 2")
        sheet.set_cell_value("C1", "Col 3")

        # 插入新列
        sheet.insert_columns(2)
        assert sheet.get_cell_value("A1") == "Col 1"
        assert sheet.get_cell_value("C1") == "Col 2"  # 原B1右移
        assert sheet.get_cell_value("D1") == "Col 3"  # 原C1右移

        # 删除列
        sheet.delete_columns(2)
        assert sheet.get_cell_value("A1") == "Col 1"
        assert sheet.get_cell_value("B1") == "Col 2"  # 恢复原B1
        assert sheet.get_cell_value("C1") == "Col 3"  # 恢复原C1


class TestCellStyle:
    """单元格样式测试类。"""

    def test_create_cell_style(self) -> None:
        """测试创建单元格样式。"""
        style = CellStyle()
        assert style is not None
        assert style.font_size == 11
        assert style.font_name == "Calibri"

    def test_font_properties(self) -> None:
        """测试字体属性。"""
        style = CellStyle()

        style.set_font(bold=True, italic=True, size=14, name="Arial")
        assert style.font_bold is True
        assert style.font_italic is True
        assert style.font_size == 14
        assert style.font_name == "Arial"

        style.set_font_color(Color.RED)
        assert style.font_color == Color.RED

    def test_background_color(self) -> None:
        """测试背景颜色。"""
        style = CellStyle()
        style.set_background_color(Color.YELLOW)
        assert style.background_color == Color.YELLOW

    def test_border_properties(self) -> None:
        """测试边框属性。"""
        style = CellStyle()
        style.set_border(
            left="thin",
            right="thin",
            top="thin",
            bottom="thin",
            left_color=Color.BLACK,
            right_color=Color.BLACK,
            top_color=Color.BLACK,
            bottom_color=Color.BLACK,
        )
        assert style.border_left == "thin"
        assert style.border_right == "thin"
        assert style.border_top == "thin"
        assert style.border_bottom == "thin"

    def test_alignment_properties(self) -> None:
        """测试对齐属性。"""
        style = CellStyle()
        style.set_alignment(horizontal="center", vertical="center")
        assert style.horizontal_alignment == "center"
        assert style.vertical_alignment == "center"

    def test_number_format(self) -> None:
        """测试数字格式。"""
        style = CellStyle()
        style.set_number_format("0.00%")
        assert style.number_format == "0.00%"


class TestPredefinedStyles:
    """预定义样式测试类。"""

    def test_header_style(self) -> None:
        """测试表头样式。"""
        style = PredefinedStyles.header_style()
        assert style.font_bold is True
        assert style.background_color == Color.LIGHT_BLUE
        assert style.horizontal_alignment == "center"

    def test_title_style(self) -> None:
        """测试标题样式。"""
        style = PredefinedStyles.title_style()
        assert style.font_size == 16
        assert style.font_bold is True
        assert style.horizontal_alignment == "center"

    def test_highlight_style(self) -> None:
        """测试高亮样式。"""
        style = PredefinedStyles.highlight_style()
        assert style.background_color == Color.YELLOW
        assert style.font_bold is True


class TestTemplateWorkbook:
    """模板工作簿测试类。"""

    def test_load_template(self, tmp_path: Path) -> None:
        """测试加载模板。"""
        # 创建测试模板文件
        template_workbook = Workbook()
        sheet = template_workbook.create_worksheet("TemplateSheet")
        sheet.set_cell_value("A1", "{{ title }}")
        sheet.set_cell_value("B1", "{{ date }}")

        template_path = tmp_path / "template.xlsx"
        template_workbook.save(template_path)

        # 加载模板
        template = TemplateWorkbook.load_template(template_path)
        assert template is not None

    def test_render_template(self, tmp_path: Path) -> None:
        """测试渲染模板。"""
        # 创建测试模板文件
        template_workbook = Workbook()
        sheet = template_workbook.create_worksheet("TemplateSheet")
        sheet.set_cell_value("A1", "{{ title }}")
        sheet.set_cell_value("B1", "{{ date }}")

        template_path = tmp_path / "template.xlsx"
        template_workbook.save(template_path)

        # 加载并渲染模板
        template = TemplateWorkbook.load_template(template_path)
        context = {"title": "Test Report", "date": "2025-01-01"}

        rendered_workbook = template.render(context)
        rendered_sheet = rendered_workbook.get_worksheet("TemplateSheet")
        assert rendered_sheet is not None

        assert rendered_sheet.get_cell_value("A1") == "Test Report"
        assert rendered_sheet.get_cell_value("B1") == "2025-01-01"

    def test_get_template_variables(self, tmp_path: Path) -> None:
        """测试获取模板变量。"""
        # 创建测试模板文件
        template_workbook = Workbook()
        sheet = template_workbook.create_worksheet("TemplateSheet")
        sheet.set_cell_value("A1", "{{ title }}")
        sheet.set_cell_value("B1", "{{ date }}")
        sheet.set_cell_value("C1", "{{ items[0].name }}")

        template_path = tmp_path / "template.xlsx"
        template_workbook.save(template_path)

        # 加载模板并获取变量
        template = TemplateWorkbook.load_template(template_path)
        variables = template.get_template_variables()

        assert "title" in variables
        assert "date" in variables
        assert "items" in variables


class TestAsyncWorkbook:
    """异步工作簿测试类。"""

    @pytest.mark.asyncio
    async def test_async_create_workbook(self) -> None:
        """测试异步创建工作簿。"""
        workbook = AsyncWorkbook()
        await workbook.create()

        sheet_names = await workbook.get_sheet_names()
        assert len(sheet_names) == 1

    @pytest.mark.asyncio
    async def test_async_save_and_load(self, tmp_path: Path) -> None:
        """测试异步保存和加载。"""
        # 创建测试工作簿
        workbook = AsyncWorkbook()
        await workbook.create()

        # 获取工作表并设置数据
        sheet_names = await workbook.get_sheet_names()
        sheet = await workbook.get_worksheet(sheet_names[0])
        assert sheet is not None
        await sheet.set_cell_value("A1", "Async Test")

        # 异步保存
        file_path = tmp_path / "async_test.xlsx"
        await workbook.save(file_path)

        # 异步加载
        loaded_workbook = AsyncWorkbook()
        await loaded_workbook.load(file_path)

        loaded_sheet = await loaded_workbook.get_worksheet(sheet_names[0])
        assert loaded_sheet is not None
        assert await loaded_sheet.get_cell_value("A1") == "Async Test"

    @pytest.mark.asyncio
    async def test_async_save_to_memory(self) -> None:
        """测试异步保存到内存。"""
        workbook = AsyncWorkbook()
        await workbook.create()

        sheet_names = await workbook.get_sheet_names()
        sheet = await workbook.get_worksheet(sheet_names[0])
        assert sheet is not None
        await sheet.set_cell_value("A1", "Memory Test")

        data = await workbook.save_to_memory()
        assert isinstance(data, bytes)
        assert len(data) > 0


class TestInMemoryWorkbook:
    """内存工作簿测试类。"""

    def test_create_in_memory_workbook(self) -> None:
        """测试创建内存工作簿。"""
        workbook = InMemoryWorkbook()
        assert workbook is not None
        assert len(workbook.get_sheet_names()) == 1

    def test_in_memory_operations(self) -> None:
        """测试内存操作。"""
        workbook = InMemoryWorkbook()
        sheet = workbook.create_worksheet("TestSheet")

        # 设置数据
        sheet.set_cell_value("A1", "Memory Test")
        sheet.set_cell_value("B1", 123)

        # 验证数据
        assert sheet.get_cell_value("A1") == "Memory Test"
        assert sheet.get_cell_value("B1") == 123

    def test_to_bytes(self) -> None:
        """测试转换为字节。"""
        workbook = InMemoryWorkbook()
        sheet = workbook.create_worksheet("TestSheet")
        sheet.set_cell_value("A1", "Byte Test")

        data = workbook.to_bytes()
        assert isinstance(data, bytes)
        assert len(data) > 0

    def test_from_bytes(self) -> None:
        """测试从字节加载。"""
        # 创建工作簿并转换为字节
        original_workbook = InMemoryWorkbook()
        sheet = original_workbook.create_worksheet("TestSheet")
        sheet.set_cell_value("A1", "From Bytes")

        data = original_workbook.to_bytes()

        # 从字节加载
        loaded_workbook = InMemoryWorkbook.from_bytes(data)
        loaded_sheet = loaded_workbook.get_worksheet("TestSheet")
        assert loaded_sheet is not None

        assert loaded_sheet.get_cell_value("A1") == "From Bytes"

    def test_clone(self, tmp_path: Path) -> None:
        """测试克隆。"""
        original_workbook = InMemoryWorkbook()
        sheet = original_workbook.create_worksheet("TestSheet")
        sheet.set_cell_value("A1", "Clone Test")

        cloned_workbook = original_workbook.clone()
        cloned_sheet = cloned_workbook.get_worksheet("TestSheet")
        assert cloned_sheet is not None

        assert cloned_sheet.get_cell_value("A1") == "Clone Test"

        # 修改克隆的工作簿不应影响原始工作簿
        cloned_sheet.set_cell_value("A1", "Modified Clone")
        original_sheet = original_workbook.get_worksheet("TestSheet")
        cloned_sheet_check = cloned_workbook.get_worksheet("TestSheet")
        assert original_sheet is not None
        assert cloned_sheet_check is not None
        assert original_sheet.get_cell_value("A1") == "Clone Test"
        assert cloned_sheet_check.get_cell_value("A1") == "Modified Clone"

    def test_context_manager(self) -> None:
        """测试上下文管理器。"""
        with InMemoryWorkbook() as workbook:
            sheet = workbook.create_worksheet("TestSheet")
            sheet.set_cell_value("A1", "Context Test")
            assert sheet.get_cell_value("A1") == "Context Test"


class TestValidationError:
    """验证错误测试类。"""

    def test_validation_error_creation(self) -> None:
        """测试创建验证错误。"""
        error = ValidationError("Test validation error")
        assert str(error) == "Test validation error"

    def test_validation_error_with_details(self) -> None:
        """测试带详细信息的验证错误。"""
        error = ValidationError("Invalid cell reference", details={"cell": "A1"})
        assert str(error) == "Invalid cell reference (详细信息: {'cell': 'A1'})"
        assert error.details == {"cell": "A1"}


# API文档示例
def api_documentation_examples() -> None:
    """
    API文档示例函数。

    此函数包含各种使用示例，用于生成API文档。
    """

    # 示例1: 创建和保存工作簿
    def example_create_save_workbook() -> None:
        """创建工作簿并保存的示例。"""
        # 创建工作簿
        workbook = Workbook()

        # 创建工作表
        sheet = workbook.create_worksheet("Sales Data")

        # 设置数据
        sheet.set_cell_value("A1", "Product")
        sheet.set_cell_value("B1", "Quantity")
        sheet.set_cell_value("C1", "Price")

        sheet.set_cell_value("A2", "Widget A")
        sheet.set_cell_value("B2", 100)
        sheet.set_cell_value("C2", 9.99)

        # 保存到文件
        workbook.save("sales_data.xlsx")

    # 示例2: 使用样式
    def example_use_styles() -> None:
        """使用样式的示例。"""
        workbook = Workbook()
        sheet = workbook.create_worksheet("Styled Sheet")

        # 创建表头样式
        header_style = CellStyle()
        header_style.set_font(bold=True, size=12)
        header_style.set_background_color(Color.LIGHT_BLUE)
        header_style.set_alignment(horizontal="center")

        # 应用样式到表头
        sheet.set_cell_value("A1", "Name")
        sheet.apply_style("A1", header_style)

        # 使用预定义样式
        sheet.set_cell_value("A2", "High Priority")
        sheet.apply_style("A2", PredefinedStyles.highlight_style())

    # 示例3: 使用模板
    def example_use_template() -> None:
        """使用模板的示例。"""
        # 加载模板
        template = TemplateWorkbook.load_template("report_template.xlsx")

        # 准备数据
        context = {
            "title": "Monthly Report",
            "date": "2025-01-01",
            "items": [
                {"name": "Item 1", "value": 100},
                {"name": "Item 2", "value": 200},
            ],
        }

        # 渲染模板
        workbook = template.render(context)

        # 保存结果
        workbook.save("generated_report.xlsx")

    # 示例4: 异步处理
    async def example_async_processing() -> None:
        """异步处理的示例。"""
        # 异步创建工作簿
        workbook = AsyncWorkbook()
        await workbook.create()

        # 异步操作
        sheet = await workbook.create_worksheet("Async Sheet")
        await sheet.set_cell_value("A1", "Async Data")  # type: ignore

        # 异步保存
        await workbook.save("async_output.xlsx")

    # 示例5: 内存操作
    def example_in_memory_operations() -> None:
        """内存操作的示例。"""
        # 创建内存工作簿
        with InMemoryWorkbook() as workbook:
            sheet = workbook.create_worksheet("Memory Sheet")

            # 设置数据
            sheet.set_cell_value("A1", "In Memory")

            # 转换为字节
            data = workbook.to_bytes()

            # 从字节加载
            loaded_workbook = InMemoryWorkbook.from_bytes(data)
            loaded_sheet = loaded_workbook.get_worksheet("Memory Sheet")
            assert loaded_sheet is not None

            assert loaded_sheet.get_cell_value("A1") == "In Memory"

    # 示例6: 批量处理
    def example_batch_processing() -> None:
        """批量处理的示例。"""

        def process_workbook(workbook: Workbook) -> Workbook:
            """处理单个工作簿的函数。"""
            # 在每个工作簿中添加汇总信息
            summary_sheet = workbook.create_worksheet("Summary")
            summary_sheet.set_cell_value("A1", "Processed")
            summary_sheet.set_cell_value("A2", "Date: 2025-01-01")
            return workbook

        # 批量处理（这里需要实现具体的批量处理逻辑）
        # file_paths = ['file1.xlsx', 'file2.xlsx', 'file3.xlsx']
        # results = batch_process_files(file_paths, process_workbook)

    print("API文档示例函数已定义，包含各种使用场景。")


if __name__ == "__main__":
    # 运行API文档示例
    api_documentation_examples()

    print("所有API文档示例已生成。")
    print("要运行测试，请使用: pytest test_api.py")
