import pytest
from httpx import AsyncClient


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_statistics_all_users_success(
    client: AsyncClient, admin_token: str, db_session, admin_user
):
    """测试所有用户获取基础统计成功"""
    from src.models.project import Project
    from datetime import date

    # 创建测试项目
    project1 = Project(
        project_no="PRJ001",
        name="项目1",
        engineering_type="基建",
        contract_amount=100.0,
        actual_receipt_amount=50.0,
        actual_payment_amount=40.0,
        cumulative_progress=50.0,
        signing_date=date(2026, 1, 1),
        created_by=admin_user.id,
    )
    project2 = Project(
        project_no="PRJ002",
        name="项目2",
        engineering_type="业扩",
        contract_amount=200.0,
        actual_receipt_amount=100.0,
        actual_payment_amount=80.0,
        cumulative_progress=50.0,
        signing_date=date(2026, 1, 1),
        created_by=admin_user.id,
    )
    db_session.add(project1)
    db_session.add(project2)
    await db_session.commit()

    response = await client.get(
        "/api/v1/projects/statistics",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert data["data"]["total_count"] == 2
    assert data["data"]["total_contract_amount"] == 300.0
    assert data["data"]["total_receipt_amount"] == 150.0
    assert data["data"]["total_payment_amount"] == 120.0


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_statistics_with_filters(
    client: AsyncClient, admin_token: str, db_session, admin_user
):
    """测试带筛选条件的统计"""
    from src.models.project import Project
    from datetime import date

    # 创建不同类型的项目
    project1 = Project(
        project_no="PRJ001",
        name="基建项目",
        engineering_type="基建",
        contract_amount=100.0,
        signing_date=date(2026, 1, 1),
        created_by=admin_user.id,
    )
    project2 = Project(
        project_no="PRJ002",
        name="业扩项目",
        engineering_type="业扩",
        contract_amount=200.0,
        signing_date=date(2026, 2, 1),
        created_by=admin_user.id,
    )
    db_session.add(project1)
    db_session.add(project2)
    await db_session.commit()

    # 筛选：工程类别=基建
    response = await client.get(
        "/api/v1/projects/statistics?engineering_type=基建",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert data["data"]["total_count"] == 1
    assert data["data"]["total_contract_amount"] == 100.0


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_statistics_empty_data(
    client: AsyncClient, admin_token: str
):
    """测试无数据时的统计"""
    response = await client.get(
        "/api/v1/projects/statistics",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert data["data"]["total_count"] == 0
    assert data["data"]["total_contract_amount"] == 0


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_group_statistics_by_engineering_type(
    client: AsyncClient, admin_token: str, db_session, admin_user
):
    """测试按工程类别分组统计"""
    from src.models.project import Project
    from datetime import date

    # 创建不同类型的项目
    for i in range(3):
        project = Project(
            project_no=f"PRJ{i:03d}",
            name=f"基建项目{i}",
            engineering_type="基建",
            contract_amount=100.0,
            actual_receipt_amount=80.0,
            actual_payment_amount=70.0,
            signing_date=date(2026, 1, 1),
            created_by=admin_user.id,
        )
        db_session.add(project)

    for i in range(2):
        project = Project(
            project_no=f"PRJ{i+3:03d}",
            name=f"业扩项目{i}",
            engineering_type="业扩",
            contract_amount=200.0,
            actual_receipt_amount=150.0,
            actual_payment_amount=130.0,
            signing_date=date(2026, 1, 1),
            created_by=admin_user.id,
        )
        db_session.add(project)

    await db_session.commit()

    response = await client.get(
        "/api/v1/projects/statistics/group?group_by=engineering_type",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert len(data["data"]) == 2

    # 验证基建工程统计
    infra = next(item for item in data["data"] if item["engineering_type"] == "基建")
    assert infra["count"] == 3
    assert infra["total_contract_amount"] == 300.0

    # 验证业扩工程统计
    market = next(item for item in data["data"] if item["engineering_type"] == "业扩")
    assert market["count"] == 2
    assert market["total_contract_amount"] == 400.0


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_group_statistics_by_department(
    client: AsyncClient, admin_token: str, db_session, admin_user
):
    """测试按项目部分组统计"""
    from src.models.project import Project
    from datetime import date

    # 创建不同项目部的项目
    project1 = Project(
        project_no="PRJ001",
        name="项目部一项目",
        engineering_type="基建",
        contract_amount=100.0,
        project_department="项目部一",
        signing_date=date(2026, 1, 1),
        created_by=admin_user.id,
    )
    project2 = Project(
        project_no="PRJ002",
        name="项目部二项目",
        engineering_type="业扩",
        contract_amount=200.0,
        project_department="项目部二",
        signing_date=date(2026, 1, 1),
        created_by=admin_user.id,
    )
    db_session.add(project1)
    db_session.add(project2)
    await db_session.commit()

    response = await client.get(
        "/api/v1/projects/statistics/group?group_by=project_department",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert len(data["data"]) == 2


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_group_statistics_with_date_filter(
    client: AsyncClient, admin_token: str, db_session, admin_user
):
    """测试带日期筛选的分组统计"""
    from src.models.project import Project
    from datetime import date

    # 创建不同日期的项目
    project1 = Project(
        project_no="PRJ001",
        name="一月项目",
        engineering_type="基建",
        contract_amount=100.0,
        signing_date=date(2026, 1, 15),
        created_by=admin_user.id,
    )
    project2 = Project(
        project_no="PRJ002",
        name="二月项目",
        engineering_type="业扩",
        contract_amount=200.0,
        signing_date=date(2026, 2, 15),
        created_by=admin_user.id,
    )
    db_session.add(project1)
    db_session.add(project2)
    await db_session.commit()

    # 只统计1月的项目
    response = await client.get(
        "/api/v1/projects/statistics/group?group_by=engineering_type&signing_date_start=2026-01-01&signing_date_end=2026-01-31",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert len(data["data"]) == 1
    assert data["data"][0]["count"] == 1


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_timeline_statistics_by_month(
    client: AsyncClient, admin_token: str, db_session, admin_user
):
    """测试按月统计"""
    from src.models.project import Project
    from datetime import date

    # 创建不同月份的项目
    for month in [1, 1, 2, 2, 2]:
        project = Project(
            project_no=f"PRJ{month:02d}",
            name=f"{month}月项目",
            engineering_type="基建",
            contract_amount=100.0,
            signing_date=date(2026, month, 15),
            created_by=admin_user.id,
        )
        db_session.add(project)

    await db_session.commit()

    response = await client.get(
        "/api/v1/projects/statistics/timeline?time_field=signing_date&group_by=month",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert len(data["data"]) == 2

    # 验证1月统计
    jan = next(item for item in data["data"] if item["month"] == "2026-01")
    assert jan["count"] == 2

    # 验证2月统计
    feb = next(item for item in data["data"] if item["month"] == "2026-02")
    assert feb["count"] == 3


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_timeline_statistics_by_year(
    client: AsyncClient, admin_token: str, db_session, admin_user
):
    """测试按年统计"""
    from src.models.project import Project
    from datetime import date

    # 创建不同年份的项目
    for year in [2025, 2026, 2026]:
        project = Project(
            project_no=f"PRJ{year}",
            name=f"{year}年项目",
            engineering_type="基建",
            contract_amount=100.0,
            signing_date=date(year, 1, 1),
            created_by=admin_user.id,
        )
        db_session.add(project)

    await db_session.commit()

    response = await client.get(
        "/api/v1/projects/statistics/timeline?time_field=signing_date&group_by=year",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert len(data["data"]) == 2

    # 验证2025年统计
    y2025 = next(item for item in data["data"] if item["year"] == "2025")
    assert y2025["count"] == 1

    # 验证2026年统计
    y2026 = next(item for item in data["data"] if item["year"] == "2026")
    assert y2026["count"] == 2


@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_timeline_statistics_with_filter(
    client: AsyncClient, admin_token: str, db_session, admin_user
):
    """测试带筛选条件的时间统计"""
    from src.models.project import Project
    from datetime import date

    # 创建不同类型和日期的项目
    project1 = Project(
        project_no="PRJ001",
        name="基建一月",
        engineering_type="基建",
        contract_amount=100.0,
        signing_date=date(2026, 1, 1),
        created_by=admin_user.id,
    )
    project2 = Project(
        project_no="PRJ002",
        name="业扩一月",
        engineering_type="业扩",
        contract_amount=200.0,
        signing_date=date(2026, 1, 1),
        created_by=admin_user.id,
    )
    project3 = Project(
        project_no="PRJ003",
        name="业扩二月",
        engineering_type="业扩",
        contract_amount=300.0,
        signing_date=date(2026, 2, 1),
        created_by=admin_user.id,
    )
    db_session.add(project1)
    db_session.add(project2)
    db_session.add(project3)
    await db_session.commit()

    # 只统计业扩项目
    response = await client.get(
        "/api/v1/projects/statistics/timeline?time_field=signing_date&group_by=month&engineering_type=业扩",
        headers={"Authorization": f"Bearer {admin_token}"},
    )

    assert response.status_code == 200
    data = response.json()
    assert data["success"] is True
    assert len(data["data"]) == 2

    # 验证1月业扩项目统计
    jan = next(item for item in data["data"] if item["month"] == "2026-01")
    assert jan["count"] == 1
