"""
集成测试 - 测试多个模块协同工作
"""

import tempfile
from pathlib import Path

import pytest

from src.symphra_excel import CellStyle, Color, PredefinedStyles, Workbook


class TestCompleteWorkflow:
    """完整工作流程测试"""

    def test_create_report_workflow(self, tmp_path: Path):
        """测试创建报告的完整工作流"""
        # 创建工作簿
        wb = Workbook()

        # 创建数据工作表
        data_sheet = wb.create_worksheet("销售数据")

        # 添加表头
        headers = ["产品名称", "数量", "单价", "总额"]
        for i, header in enumerate(headers):
            cell_ref = f"{chr(65 + i)}1"
            data_sheet.set_cell_value(cell_ref, header)
            data_sheet.apply_style(cell_ref, PredefinedStyles.header_style())

        # 添加数据
        data = [
            ["产品A", 100, 25.5, "=B2*C2"],
            ["产品B", 200, 18.0, "=B3*C3"],
            ["产品C", 150, 32.0, "=B4*C4"],
        ]

        for i, row in enumerate(data, start=2):
            for j, value in enumerate(row):
                data_sheet.set_cell_value(f"{chr(65 + j)}{i}", value)
                data_sheet.apply_style(
                    f"{chr(65 + j)}{i}", PredefinedStyles.data_style()
                )

        # 创建汇总工作表
        summary_sheet = wb.create_worksheet("汇总")
        summary_sheet.set_cell_value("A1", "总销售额")
        summary_sheet.set_cell_value("B1", "=SUM(销售数据!D2:D4)")

        # 保存
        file_path = tmp_path / "sales_report.xlsx"
        wb.save(file_path)

        # 重新加载验证
        wb2 = Workbook.load(file_path)
        loaded_data = wb2.get_worksheet("销售数据")

        assert loaded_data.get_cell_value("A1") == "产品名称"
        assert loaded_data.get_cell_value("A2") == "产品A"
        assert loaded_data.get_cell_value("B2") == 100

    def test_multi_sheet_data_processing(self):
        """测试多工作表数据处理"""
        wb = Workbook()

        # Sheet1: 原始数据
        sheet1 = wb.create_worksheet("RawData")
        raw_data = [[f"Data{i},{j}" for j in range(10)] for i in range(100)]
        sheet1.set_range_values("A1", raw_data)

        # Sheet2: 处理后的数据
        sheet2 = wb.create_worksheet("ProcessedData")
        # 从sheet1读取并处理
        for i in range(1, 11):
            value = sheet1.get_cell_value(f"A{i}")
            sheet2.set_cell_value(f"A{i}", f"Processed: {value}")

        # 验证
        assert sheet2.get_cell_value("A1") == "Processed: Data0,0"
        assert sheet2.get_cell_value("A10") == "Processed: Data9,0"

    def test_complex_styling_workflow(self):
        """测试复杂样式工作流"""
        wb = Workbook()
        sheet = wb.active

        # 设置表头样式
        header_style = CellStyle()
        header_style.set_font(name="Arial", size=12, bold=True, color=Color.WHITE)
        header_style.set_background_color("#4472C4")
        header_style.set_alignment(
            horizontal="center", vertical="center"
        )  # 使用'center'而不是'middle'

        headers = ["ID", "Name", "Score"]
        for i, header in enumerate(headers):
            cell = f"{chr(65 + i)}1"
            sheet.set_cell_value(cell, header)
            sheet.apply_style(cell, header_style)

        # 设置数据样式(奇偶行不同颜色)
        for i in range(2, 12):
            if i % 2 == 0:
                bg_color = "#E7E6E6"
            else:
                bg_color = "#FFFFFF"

            style = CellStyle()
            style.set_background_color(bg_color)
            style.set_alignment(
                horizontal="left", vertical="center"
            )  # 使用'center'而不是'middle'

            for j in range(3):
                cell = f"{chr(65 + j)}{i}"
                sheet.set_cell_value(cell, f"Data{i},{j}")
                sheet.apply_style(cell, style)

        # 验证
        assert sheet.get_cell_value("A1") == "ID"
        assert sheet.get_cell_value("A2") == "Data2,0"


class TestBatchOperationsIntegration:
    """批量操作集成测试"""

    def test_large_batch_write(self):
        """测试大批量写入"""
        wb = Workbook()
        sheet = wb.active

        # 批量追加1000行
        rows = [[f"R{i}C{j}" for j in range(20)] for i in range(1000)]
        sheet.append_rows(rows)

        # 验证
        assert sheet.get_cell_value("A1") == "R0C0"
        assert sheet.get_cell_value("T1000") == "R999C19"

    def test_range_operations_integration(self):
        """测试范围操作集成"""
        wb = Workbook()
        sheet = wb.active

        # 写入范围
        data = [[i * j for j in range(10)] for i in range(10)]
        sheet.set_range_values("A1", data)

        # 读取范围
        read_data = sheet.get_range_values("A1:J10")

        # 验证
        assert read_data[0][0] == 0
        assert read_data[5][5] == 25
        assert read_data[9][9] == 81

    def test_mixed_operations(self):
        """测试混合操作"""
        wb = Workbook()
        sheet = wb.active

        # 混合使用不同的写入方法
        sheet.set_cell_value("A1", "Header")
        sheet.append_row(["R1C1", "R1C2", "R1C3"])
        sheet.set_range_values("A3", [[1, 2, 3], [4, 5, 6]])

        # 应用样式
        sheet.apply_style("A1", PredefinedStyles.header_style())
        sheet.apply_range_style("A2:C2", PredefinedStyles.data_style())

        # 验证
        assert sheet.get_cell_value("A1") == "Header"
        assert sheet.get_cell_value("A2") == "R1C1"
        assert sheet.get_cell_value("B4") == 5


class TestErrorHandlingIntegration:
    """错误处理集成测试"""

    def test_graceful_error_recovery(self):
        """测试优雅的错误恢复"""
        wb = Workbook()
        sheet = wb.active

        # 正常操作
        sheet.set_cell_value("A1", "Normal")

        # 触发错误并捕获
        from src.symphra_excel import ValidationError

        try:
            sheet.set_cell_value("INVALID", "Bad")
        except (ValidationError, Exception):
            pass

        # 继续正常操作
        sheet.set_cell_value("A2", "Recovery")
        assert sheet.get_cell_value("A2") == "Recovery"

    def test_mode_restrictions_integration(self):
        """测试模式限制集成"""
        # 只写模式
        wb_write = Workbook(write_only=True)
        sheet_write = wb_write.active

        # 可以追加
        sheet_write.append_row([1, 2, 3])

        # 不能读取
        from src.symphra_excel import ValidationError

        with pytest.raises(ValidationError):
            sheet_write.get_cell_value("A1")


class TestFileIOIntegration:
    """文件IO集成测试"""

    def test_save_load_roundtrip(self, tmp_path: Path):
        """测试保存和加载往返"""
        # 创建包含多种数据的工作簿
        wb1 = Workbook()
        sheet1 = wb1.active

        # 多种数据类型
        sheet1.set_cell_value("A1", "String")
        sheet1.set_cell_value("A2", 123)
        sheet1.set_cell_value("A3", 3.14)
        sheet1.set_cell_value("A4", True)
        sheet1.set_cell_value("A5", None)

        # 样式
        sheet1.apply_style("A1", PredefinedStyles.header_style())

        # 保存
        file_path = tmp_path / "roundtrip.xlsx"
        wb1.save(file_path)

        # 加载
        wb2 = Workbook.load(file_path)
        sheet2 = wb2.active

        # 验证数据
        assert sheet2.get_cell_value("A1") == "String"
        assert sheet2.get_cell_value("A2") == 123
        assert abs(sheet2.get_cell_value("A3") - 3.14) < 1e-10
        assert sheet2.get_cell_value("A4") is True
        assert sheet2.get_cell_value("A5") is None

    def test_save_to_memory_integration(self):
        """测试保存到内存集成"""
        wb = Workbook()
        sheet = wb.active

        for i in range(100):
            sheet.append_row([f"Data{i}", i, i * 2])

        # 保存到内存
        data = wb.save_to_memory()

        # 验证
        assert isinstance(data, bytes)
        assert len(data) > 0

        # 可以从内存数据重新加载
        with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as tmp:
            tmp.write(data)
            tmp_path = tmp.name

        try:
            wb2 = Workbook.load(tmp_path)
            assert wb2.active.get_cell_value("A1") == "Data0"
        finally:
            Path(tmp_path).unlink()


class TestWorksheetManagement:
    """工作表管理集成测试"""

    def test_create_rename_delete_workflow(self):
        """测试创建、重命名、删除工作流"""
        wb = Workbook()

        # 创建多个工作表
        sheet1 = wb.create_worksheet("Sheet1")
        wb.create_worksheet("Sheet2")
        wb.create_worksheet("Sheet3")

        # 验证创建
        assert "Sheet1" in wb.get_sheet_names()
        assert "Sheet2" in wb.get_sheet_names()
        assert "Sheet3" in wb.get_sheet_names()

        # 重命名
        sheet1.name = "RenamedSheet1"
        assert "RenamedSheet1" in wb.get_sheet_names()

        # 删除
        wb.delete_worksheet("Sheet2")
        assert "Sheet2" not in wb.get_sheet_names()

        # 访问剩余工作表
        remaining = wb.get_worksheet("RenamedSheet1")
        assert remaining is not None

    def test_switch_between_sheets(self):
        """测试在工作表之间切换"""
        wb = Workbook()

        sheet1 = wb.create_worksheet("Data1")
        sheet2 = wb.create_worksheet("Data2")

        # 在不同工作表中写入数据
        sheet1.set_cell_value("A1", "Sheet1 Data")
        sheet2.set_cell_value("A1", "Sheet2 Data")

        # 验证数据独立
        assert wb.get_worksheet("Data1").get_cell_value("A1") == "Sheet1 Data"
        assert wb.get_worksheet("Data2").get_cell_value("A1") == "Sheet2 Data"


@pytest.mark.asyncio
class TestAsyncIntegration:
    """异步操作集成测试"""

    async def test_async_workbook_workflow(self):
        """测试异步工作簿工作流"""
        try:
            from src.symphra_excel import AsyncWorkbook

            # 创建异步工作簿
            wb = AsyncWorkbook()
            await wb.create()

            # 创建工作表
            sheet = await wb.create_worksheet("AsyncData")

            # 写入数据
            await sheet.set_cell_value("A1", "Async Test")

            # 读取数据
            value = await sheet.get_cell_value("A1")
            assert value == "Async Test"

            # AsyncWorksheet可能没有append_row方法,只测试基本读写

        except ImportError:
            pytest.skip("AsyncWorkbook not available")


class TestRealWorldScenarios:
    """真实世界场景测试"""

    def test_invoice_generation(self, tmp_path: Path):
        """测试发票生成场景"""
        wb = Workbook()
        sheet = wb.active

        # 标题
        sheet.set_cell_value("A1", "发票")
        title_style = CellStyle()
        title_style.set_font(size=16, bold=True)
        sheet.apply_style("A1", title_style)

        # 客户信息
        sheet.set_cell_value("A3", "客户名称:")
        sheet.set_cell_value("B3", "ABC公司")

        # 项目明细
        headers = ["项目", "数量", "单价", "金额"]
        for i, header in enumerate(headers):
            sheet.set_cell_value(f"{chr(65 + i)}5", header)
            sheet.apply_style(f"{chr(65 + i)}5", PredefinedStyles.header_style())

        items = [
            ["服务A", 10, 100, "=B6*C6"],
            ["服务B", 5, 200, "=B7*C7"],
        ]

        for i, item in enumerate(items, start=6):
            for j, value in enumerate(item):
                sheet.set_cell_value(f"{chr(65 + j)}{i}", value)

        # 总计
        sheet.set_cell_value("C8", "总计:")
        sheet.set_cell_value("D8", "=SUM(D6:D7)")

        # 保存
        file_path = tmp_path / "invoice.xlsx"
        wb.save(file_path)

        assert file_path.exists()

    def test_data_analysis_report(self):
        """测试数据分析报告场景"""
        wb = Workbook()
        sheet = wb.active

        # 原始数据
        raw_data = [
            ["日期", "销售额", "成本", "利润"],
            ["2025-01", 10000, 7000, 3000],
            ["2025-02", 12000, 8000, 4000],
            ["2025-03", 15000, 9000, 6000],
        ]

        sheet.set_range_values("A1", raw_data)

        # 应用样式
        sheet.apply_range_style("A1:D1", PredefinedStyles.header_style())

        # 添加汇总行
        sheet.set_cell_value("A5", "总计")
        sheet.set_cell_value("B5", "=SUM(B2:B4)")
        sheet.set_cell_value("C5", "=SUM(C2:C4)")
        sheet.set_cell_value("D5", "=SUM(D2:D4)")

        # 验证
        assert sheet.get_cell_value("A1") == "日期"
        assert sheet.get_cell_value("B2") == 10000
