"""端到端集成测试：验证 110 个 Paper Factors 能被本地引擎计算。

测试目标：
1. 加载 paper factors 库
2. 使用 LocalFactorEvaluator 计算每个因子
3. 验证输出形状为 (M, T) 且不含全 NaN
4. 统计成功率和跳过数

运行命令：uv run pytest tests/test_factorminer_e2e.py -v
"""

import pytest


def test_paper_factors_e2e():
    """端到端测试：验证 110 个 Paper Factors 能被本地引擎计算。

    注意：此测试需要数据库中有 pro_bar 数据。
    如果数据不足，会在计算时失败。
    """
    from src.factorminer.core.library_io import import_from_paper
    from src.factorminer.evaluation.local_engine import LocalFactorEvaluator

    # 1. 加载 paper factors 库
    library = import_from_paper()
    factors = library.list_factors()
    total = len(factors)

    print(f"\n[e2e] 总计加载 {total} 个因子")

    # 2. 过滤 unsupported 因子
    supported_factors = [f for f in factors if not f.metadata.get("unsupported", False)]
    unsupported_count = total - len(supported_factors)

    print(f"[e2e] 可计算因子 {len(supported_factors)} 个")
    print(f"[e2e] 跳过（未实现算子）{unsupported_count} 个")

    if not supported_factors:
        print("[e2e] 没有可计算的因子，测试跳过")
        pytest.skip("No supported factors to test")

    # 3. 实例化 LocalFactorEvaluator
    evaluator = LocalFactorEvaluator(
        start_date="20200101",
        end_date="20201231",
    )

    # 4. 批量计算每个因子
    success_count = 0
    fail_count = 0
    skip_count = 0

    specs = [(f.name, f.formula) for f in supported_factors]

    print(f"[e2e] 开始批量计算 {len(specs)} 个因子...")

    try:
        results = evaluator.evaluate(specs)
    except Exception as e:
        print(f"[e2e] 批量计算失败: {e}")
        pytest.fail(f"Batch evaluation failed: {e}")

    # 5. 验证结果
    for name, result in results.items():
        if result is None:
            fail_count += 1
            continue

        # 检查形状
        if result.ndim != 2:
            print(f"[e2e] 因子 {name} 形状错误: {result.ndim}D（期望 2D）")
            fail_count += 1
            continue

        # 检查是否全 NaN
        if np.isnan(result).all():
            print(f"[e2e] 因子 {name} 输出全为 NaN")
            fail_count += 1
            continue

        success_count += 1

    print(
        f"[e2e] 成功 {success_count}/{total}，"
        f"跳过 {skip_count} 个，失败 {fail_count} 个"
    )

    # 断言：至少 50% 的因子能成功计算（宽松标准）
    success_rate = success_count / total
    assert success_rate >= 0.5, f"成功率 {success_rate:.1%} 低于 50% 阈值"


if __name__ == "__main__":
    import numpy as np
    from src.factorminer.core.library_io import import_from_paper
    from src.factorminer.evaluation.local_engine import LocalFactorEvaluator

    # 手动运行测试
    library = import_from_paper()
    factors = library.list_factors()
    total = len(factors)
    print(f"\n[e2e] 总计加载 {total} 个因子")

    supported_factors = [f for f in factors if not f.metadata.get("unsupported", False)]
    unsupported_count = total - len(supported_factors)
    print(f"[e2e] 可计算因子 {len(supported_factors)} 个")
    print(f"[e2e] 跳过（未实现算子）{unsupported_count} 个")

    if supported_factors:
        evaluator = LocalFactorEvaluator(
            start_date="20200101",
            end_date="20201231",
        )
        specs = [(f.name, f.formula) for f in supported_factors]
        print(f"[e2e] 开始批量计算 {len(specs)} 个因子...")
        results = evaluator.evaluate(specs)
        print(f"[e2e] 批量计算完成，共 {len(results)} 个结果")
