
# # закоментированы для избежания переполнения бд



# from datetime import datetime, timedelta
# import uuid

# import pytest


# def _find_event(
#     client,
#     admin_tokens: dict,
#     auth_headers,
#     event_type: str,
#     predicate,
#     limit: int = 100,
# ):
#     response = client.get(
#         f"/api/v1/audit-logs?event_type={event_type}&limit={limit}",
#         headers=auth_headers(admin_tokens),
#     )
#     assert response.status_code == 200
#     result = response.json().get("result", [])
#     for item in result:
#         payload = item.get("payload_json") or {}
#         if predicate(payload):
#             return item
#     return None


# def _event_count(client, admin_tokens: dict, auth_headers, event_type: str) -> int:
#     response = client.get(
#         f"/api/v1/audit-logs?event_type={event_type}&limit=1",
#         headers=auth_headers(admin_tokens),
#     )
#     assert response.status_code == 200
#     return int(response.json().get("count") or 0)


# def _pick_target_user_id(client, admin_tokens: dict, auth_headers) -> int:
#     me_resp = client.get(
#         "/api/v1/users/me",
#         headers=auth_headers(admin_tokens),
#     )
#     assert me_resp.status_code == 200
#     me = me_resp.json() or {}
#     assert me.get("id") is not None
#     return int(me["id"])


# def _pick_org_unit_id(client, admin_tokens: dict, auth_headers, user_id: int) -> int:
#     forms_resp = client.get(
#         "/api/v1/form/?limit=100",
#         headers=auth_headers(admin_tokens),
#     )
#     assert forms_resp.status_code == 200
#     forms = forms_resp.json().get("result") or []
#     candidate_ids = [f.get("org_unit_id") for f in forms if f.get("org_unit_id") is not None]
#     assert candidate_ids

#     assigned_resp = client.get(
#         f"/api/v1/users/dfip-many-ssp/?user_id={user_id}",
#         headers=auth_headers(admin_tokens),
#     )
#     assert assigned_resp.status_code == 200
#     assigned = {
#         int(item["id"])
#         for item in (assigned_resp.json().get("result") or {}).get("ssp", [])
#         if item.get("id") is not None
#     }
#     for org_unit_id in candidate_ids:
#         if int(org_unit_id) not in assigned:
#             return int(org_unit_id)
#     raise AssertionError("Не найден org_unit_id, который можно прикрепить пользователю")


# def _create_temp_user(client, admin_tokens: dict, auth_headers, role_id: int = 2) -> int:
#     suffix = uuid.uuid4().hex[:8]
#     username = f"audit_u_{suffix}"
#     response = client.put(
#         "/api/v1/users/",
#         json={
#             "email": f"{username}@example.com",
#             "username": username,
#             "password": "pass123",
#             "full_name": "Audit User",
#             "role_id": role_id,
#         },
#         headers=auth_headers(admin_tokens),
#     )
#     assert response.status_code == 200, response.text
#     result = response.json().get("result") or {}
#     return int(result["id"])


# def _create_project(client, admin_tokens: dict, auth_headers) -> int:
#     response = client.post(
#         "/api/v1/projects",
#         json={"name": f"PT_{uuid.uuid4().hex[:10]}", "year": 2026, "branch_id": 1},
#         headers=auth_headers(admin_tokens),
#     )
#     assert response.status_code == 200, response.text
#     return int(response.json()["project_id"])


# def _add_project_line(client, admin_tokens: dict, auth_headers, project_id: int) -> int:
#     for expense_item_id in range(1, 80):
#         response = client.post(
#             f"/api/v1/projects/{project_id}/report/2026/LIMIT/line",
#             json={"expense_item_id": expense_item_id},
#             headers=auth_headers(admin_tokens),
#         )
#         if response.status_code != 200:
#             continue
#         rows = response.json()
#         input_row = next(
#             (
#                 row
#                 for row in rows
#                 if row.get("row_type") == "INPUT" and row.get("data", {}).get("line_id")
#             ),
#             None,
#         )
#         if input_row:
#             return int(input_row["data"]["line_id"])
#     raise AssertionError("Не удалось добавить строку в проектный отчёт для ROW_* тестов")


# def _create_stage(client, admin_tokens, auth_headers, form_id: int, sheet: str) -> dict:
#     phase_code = f"autotest_{uuid.uuid4().hex[:8]}"
#     opens_at = datetime.utcnow().replace(microsecond=0)
#     closes_at = opens_at + timedelta(days=2)
#     response = client.post(
#         f"/api/v1/stages/form/{form_id}",
#         json={
#             "sheet": sheet,
#             "phase_code": phase_code,
#             "role": "DFIP",
#             "column_keys": ["plan.q1"],
#             "opens_at": opens_at.isoformat() + "Z",
#             "closes_at": closes_at.isoformat() + "Z",
#         },
#         headers=auth_headers(admin_tokens),
#     )
#     assert response.status_code == 200, response.text
#     result = response.json().get("result") or {}
#     assert result.get("phase_code") == phase_code
#     return result


# def test_audit_user_access_granted_event(client, admin_tokens, auth_headers):
#     user_id = _pick_target_user_id(client, admin_tokens, auth_headers)
#     org_unit_id = _pick_org_unit_id(client, admin_tokens, auth_headers, user_id)

#     response = client.put(
#         f"/api/v1/users/dfip-many-ssp/?user_id={user_id}",
#         json={"ssp_ids": [org_unit_id]},
#         headers=auth_headers(admin_tokens),
#     )
#     assert response.status_code == 200
#     assert response.json().get("success") is True

#     event = _find_event(
#         client,
#         admin_tokens,
#         auth_headers,
#         "USER_ACCESS_GRANTED",
#         lambda payload: int(payload.get("user_id", -1)) == user_id
#         and int(payload.get("org_unit_id", -1)) == org_unit_id,
#     )
#     assert event is not None


# def test_audit_user_access_revoked_event(client, admin_tokens, auth_headers):
#     user_id = _pick_target_user_id(client, admin_tokens, auth_headers)
#     assigned_resp = client.get(
#         f"/api/v1/users/dfip-many-ssp/?user_id={user_id}",
#         headers=auth_headers(admin_tokens),
#     )
#     assert assigned_resp.status_code == 200
#     assigned = (assigned_resp.json().get("result") or {}).get("ssp", [])

#     if assigned:
#         org_unit_id = int(assigned[0]["id"])
#     else:
#         org_unit_id = _pick_org_unit_id(client, admin_tokens, auth_headers, user_id)
#         attach_resp = client.put(
#             f"/api/v1/users/dfip-many-ssp/?user_id={user_id}",
#             json={"ssp_ids": [org_unit_id]},
#             headers=auth_headers(admin_tokens),
#         )
#         assert attach_resp.status_code == 200
#         assert attach_resp.json().get("success") is True

#     response = client.request(
#         "DELETE",
#         f"/api/v1/users/dfip-many-ssp/?user_id={user_id}",
#         json={"ssp_ids": [org_unit_id]},
#         headers=auth_headers(admin_tokens),
#     )
#     assert response.status_code == 200
#     assert response.json().get("success") is True

#     event = _find_event(
#         client,
#         admin_tokens,
#         auth_headers,
#         "USER_ACCESS_REVOKED",
#         lambda payload: int(payload.get("user_id", -1)) == user_id
#         and int(payload.get("org_unit_id", -1)) == org_unit_id,
#     )
#     assert event is not None


# def test_audit_user_create_event(client, admin_tokens, auth_headers):
#     before = _event_count(client, admin_tokens, auth_headers, "USER_CREATE")
#     user_id = _create_temp_user(client, admin_tokens, auth_headers, role_id=2)
#     after = _event_count(client, admin_tokens, auth_headers, "USER_CREATE")
#     assert after > before

#     delete_resp = client.delete(
#         f"/api/v1/users/{user_id}",
#         headers=auth_headers(admin_tokens),
#     )
#     assert delete_resp.status_code == 200


# def test_audit_user_role_change_event(client, admin_tokens, auth_headers):
#     user_id = _create_temp_user(client, admin_tokens, auth_headers, role_id=2)
#     before = _event_count(client, admin_tokens, auth_headers, "USER_ROLE_CHANGE")

#     update_resp = client.patch(
#         f"/api/v1/users/{user_id}",
#         json={"role_id": 3},
#         headers=auth_headers(admin_tokens),
#     )
#     assert update_resp.status_code == 200, update_resp.text
#     after = _event_count(client, admin_tokens, auth_headers, "USER_ROLE_CHANGE")
#     assert after > before

#     delete_resp = client.delete(
#         f"/api/v1/users/{user_id}",
#         headers=auth_headers(admin_tokens),
#     )
#     assert delete_resp.status_code == 200


# def test_audit_project_create_event(client, admin_tokens, auth_headers):
#     before = _event_count(client, admin_tokens, auth_headers, "PROJECT_CREATE")
#     _create_project(client, admin_tokens, auth_headers)
#     after = _event_count(client, admin_tokens, auth_headers, "PROJECT_CREATE")
#     assert after > before


# def test_audit_row_create_event(client, admin_tokens, auth_headers):
#     project_id = _create_project(client, admin_tokens, auth_headers)
#     before = _event_count(client, admin_tokens, auth_headers, "ROW_CREATE")
#     _add_project_line(client, admin_tokens, auth_headers, project_id)
#     after = _event_count(client, admin_tokens, auth_headers, "ROW_CREATE")
#     assert after > before


# def test_audit_row_delete_event(client, admin_tokens, auth_headers):
#     project_id = _create_project(client, admin_tokens, auth_headers)
#     line_id = _add_project_line(client, admin_tokens, auth_headers, project_id)
#     before = _event_count(client, admin_tokens, auth_headers, "ROW_DELETE")

#     delete_resp = client.delete(
#         f"/api/v1/projects/{project_id}/report/2026/LIMIT/line/{line_id}",
#         headers=auth_headers(admin_tokens),
#     )
#     assert delete_resp.status_code == 200, delete_resp.text
#     after = _event_count(client, admin_tokens, auth_headers, "ROW_DELETE")
#     assert after > before
