"""
API 端点测试
"""

from routers.api import file_service


def test_root_endpoint(client):
    """测试根路径"""
    response = client.get("/")
    assert response.status_code == 200
    data = response.json()
    assert data["status"] == "running"
    assert "swagger_docs" in data


def test_health_check(client):
    """测试健康检查端点"""
    response = client.get("/health")
    assert response.status_code == 200
    data = response.json()
    assert data["status"] == "healthy"


def test_get_token_success(client, sample_token_request):
    """测试获取 Token - 成功场景"""
    response = client.post("/account/common/getToken", data=sample_token_request)
    assert response.status_code == 200
    data = response.json()
    assert data["code"] == "200"
    assert "token" in data["data"]
    assert "projectId" in data["data"]


def test_get_token_error_40101(client):
    """测试获取 Token - 错误场景 40101"""
    request_data = {
        "projectNo": "test_error_40101",
        "entityName": "测试企业",
        "userId": "902001",
        "userName": "902001",
        "appId": "remote_app",
        "appSecretCode": "test_secret_code_12345",
        "role": "VIEWER",
        "orgCode": "902000",
        "departmentCode": "902000",
    }
    response = client.post("/account/common/getToken", data=request_data)
    assert response.status_code == 200
    data = response.json()
    assert data["code"] == "40101"
    assert data["successResponse"] == False


def test_fetch_inner_flow_success(client, sample_inner_flow_request):
    """测试拉取行内流水 - 成功场景"""
    response = client.post(
        "/watson/api/project/getJZFileOrZjrcuFile",
        data=sample_inner_flow_request
    )
    assert response.status_code == 200
    data = response.json()
    assert data["code"] == "200"
    assert data["successResponse"] == True
    assert isinstance(data["data"], list)
    assert len(data["data"]) == 1
    assert isinstance(data["data"][0], int)
    assert 10000 <= data["data"][0] <= 99999


def test_fetch_inner_flow_error_501014(client):
    """测试拉取行内流水 - 错误场景 501014"""
    request_data = {
        "groupId": 1001,
        "customerNo": "test_error_501014",
        "dataChannelCode": "test_code",
        "requestDateId": 20240101,
        "dataStartDateId": 20240101,
        "dataEndDateId": 20240131,
        "uploadUserId": 902001,
    }
    response = client.post(
        "/watson/api/project/getJZFileOrZjrcuFile",
        data=request_data
    )
    assert response.status_code == 200
    data = response.json()
    assert data["code"] == "501014"
    assert data["successResponse"] == False


def test_fetch_inner_flow_followed_by_upload_status(client):
    """拉取行内流水后，上传状态查询应命中同一条绑定记录。"""
    response = client.post(
        "/watson/api/project/getJZFileOrZjrcuFile",
        data={
            "groupId": 1001,
            "customerNo": "test_customer_002",
            "dataChannelCode": "test_code",
            "requestDateId": 20240101,
            "dataStartDateId": 20240101,
            "dataEndDateId": 20240131,
            "uploadUserId": 902001,
        },
    )
    assert response.status_code == 200
    log_id = response.json()["data"][0]

    assert log_id in file_service.file_records
    record = file_service.file_records[log_id]

    upload_response = client.get(
        f"/watson/api/project/bs/upload?groupId=1001&logId={log_id}"
    )
    assert upload_response.status_code == 200
    upload_data = upload_response.json()

    assert upload_data["code"] == "200"
    assert upload_data["successResponse"] is True
    assert len(upload_data["data"]["logs"]) == 1

    log = upload_data["data"]["logs"][0]
    assert log["enterpriseNameList"] == [record.primary_enterprise_name]
    assert log["accountNoList"] == [record.primary_account_no]
    assert log["enterpriseNameList"][0] == record.primary_enterprise_name
    assert log["accountNoList"][0] == record.primary_account_no


def test_upload_file_followed_by_upload_status_reads_real_record(client, monkeypatch):
    """上传文件后，上传状态查询应优先返回真实记录而不是 deterministic 回退。"""
    monkeypatch.setattr(
        file_service,
        "_generate_primary_binding",
        lambda: ("上传主体", "6222777788889999"),
    )

    upload_response = client.post(
        "/watson/api/project/remoteUploadSplitFile",
        data={"groupId": 1001},
        files={"files": ("测试文件.csv", b"mock", "text/csv")},
    )
    assert upload_response.status_code == 200
    upload_data = upload_response.json()
    upload_log = upload_data["data"]["uploadLogList"][0]

    log_id = upload_log["logId"]
    status_response = client.get(f"/watson/api/project/bs/upload?groupId=1001&logId={log_id}")
    assert status_response.status_code == 200
    status_data = status_response.json()
    status_log = status_data["data"]["logs"][0]

    assert status_log["enterpriseNameList"] == upload_log["enterpriseNameList"]
    assert status_log["accountNoList"] == upload_log["accountNoList"]
    assert status_log["enterpriseNameList"] == ["上传主体"]
    assert status_log["accountNoList"] == ["6222777788889999"]
    assert len(status_log["enterpriseNameList"]) == 1
    assert len(status_log["accountNoList"]) == 1


def test_fetch_inner_flow_marks_pending_complete(client):
    """拉取行内流水后，getpendings 应返回未解析状态。"""
    response = client.post(
        "/watson/api/project/getJZFileOrZjrcuFile",
        data={
            "groupId": 1001,
            "customerNo": "test_customer_003",
            "dataChannelCode": "test_code",
            "requestDateId": 20240101,
            "dataStartDateId": 20240101,
            "dataEndDateId": 20240131,
            "uploadUserId": 902001,
        },
    )
    assert response.status_code == 200
    log_id = response.json()["data"][0]

    pending_response = client.post(
        "/watson/api/project/upload/getpendings",
        data={"groupId": 1001, "inprogressList": str(log_id)},
    )
    assert pending_response.status_code == 200
    pending_data = pending_response.json()

    assert pending_data["data"]["parsing"] is False
    assert len(pending_data["data"]["pendingList"]) == 1
    assert pending_data["data"]["pendingList"][0]["logId"] == log_id


def test_get_upload_status_with_log_id(client):
    """测试带 logId 参数查询返回非空 logs"""
    response = client.get("/watson/api/project/bs/upload?groupId=1000&logId=13994")

    assert response.status_code == 200
    data = response.json()

    # 验证基本响应结构
    assert data["code"] == "200"
    assert data["status"] == "200"
    assert data["successResponse"] is True

    # 验证 logs 不为空
    assert len(data["data"]["logs"]) == 1

    # 验证返回的 logId 正确
    log = data["data"]["logs"][0]
    assert log["logId"] == 13994

    # 验证固定成功状态
    assert log["status"] == -5
    assert log["uploadStatusDesc"] == "data.wait.confirm.newaccount"

    # 验证 logMeta 格式正确
    assert log["logMeta"] == "{\"lostHeader\":[],\"balanceAmount\":\"-1\"}"


def test_get_upload_status_without_log_id(client):
    """测试不带 logId 参数查询返回空 logs 数组"""
    response = client.get("/watson/api/project/bs/upload?groupId=1000")

    assert response.status_code == 200
    data = response.json()

    # 验证基本响应结构
    assert data["code"] == "200"
    assert data["status"] == "200"
    assert data["successResponse"] is True

    # 验证 logs 为空
    assert len(data["data"]["logs"]) == 0

    # 验证其他字段存在
    assert data["data"]["status"] == ""
    assert data["data"]["accountId"] == 8954
    assert data["data"]["currency"] == "CNY"


def test_deterministic_data_generation(client):
    """测试相同 logId 多次查询返回相同的核心字段值"""
    # 第一次查询
    response1 = client.get("/watson/api/project/bs/upload?groupId=1000&logId=13994")
    log1 = response1.json()["data"]["logs"][0]

    # 第二次查询
    response2 = client.get("/watson/api/project/bs/upload?groupId=1000&logId=13994")
    log2 = response2.json()["data"]["logs"][0]

    # 验证关键字段相同
    assert log1["logId"] == log2["logId"]
    assert log1["bankName"] == log2["bankName"]
    assert log1["accountNoList"] == log2["accountNoList"]
    assert log1["enterpriseNameList"] == log2["enterpriseNameList"]
    assert len(log1["accountNoList"]) == 1
    assert len(log1["enterpriseNameList"]) == 1
    assert log1["status"] == log2["status"]
    assert log1["logMeta"] == log2["logMeta"]
    assert log1["templateName"] == log2["templateName"]
    assert log1["fileUploadTime"] == log2["fileUploadTime"]
    assert log1["trxDateStartId"] == log2["trxDateStartId"]
    assert log1["trxDateEndId"] == log2["trxDateEndId"]


def test_field_completeness(client):
    """测试返回数据包含完整的 26 个字段"""
    response = client.get("/watson/api/project/bs/upload?groupId=1000&logId=13994")
    log = response.json()["data"]["logs"][0]

    # 验证所有必需字段存在
    required_fields = [
        "accountNoList", "bankName", "dataTypeInfo", "downloadFileName",
        "enterpriseNameList", "fileSize", "fileUploadBy", "fileUploadByUserName",
        "fileUploadTime", "isSplit", "leId", "logId", "logMeta", "logType",
        "loginLeId", "lostHeader", "realBankName", "rows", "source", "status",
        "templateName", "totalRecords", "trxDateEndId", "trxDateStartId",
        "uploadFileName", "uploadStatusDesc"
    ]

    for field in required_fields:
        assert field in log, f"缺少字段: {field}"


def test_delete_files_accepts_array_style_log_ids(client):
    """测试删除文件接口兼容数组风格的 logIds 入参"""
    response = client.post(
        "/watson/api/project/batchDeleteUploadFile",
        data={
            "groupId": 1000,
            "logIds": "[50689]",
            "userId": 902001,
        }
    )

    assert response.status_code == 200
    data = response.json()
    assert data["code"] == "200 OK"
    assert data["message"] == "delete.files.success"
