from __future__ import annotations

from typing import Any

from app.db.platform_store import get_platform_store
from app.modules.compute_gateway.client import ComputeNodeClient


def _node_for_task(task: dict[str, Any]) -> dict[str, Any] | None:
    return next((node for node in get_platform_store().compute_nodes() if node["id"] == task.get("compute_node_id")), None)


async def poll_compute_jobs_once() -> dict[str, Any]:
    store = get_platform_store()
    synced: list[dict[str, Any]] = []
    failed: list[dict[str, str]] = []
    for task in store.running_compute_tasks():
        node = _node_for_task(task)
        if not node:
            failed.append({"task_id": task["id"], "error": "compute node not found"})
            continue
        try:
            client = ComputeNodeClient(node["api_base_url"])
            job = await client.get_job(task["compute_job_id"])
            try:
                logs = await client.job_logs(task["compute_job_id"], tail_lines=5000)
                store.record_training_log_metrics(task["id"], str(logs.get("content") or ""))
            except Exception:
                pass
            synced.append(store.apply_compute_job(task["id"], job))
        except Exception as exc:  # noqa: BLE001 - keep polling other jobs
            failed.append({"task_id": task["id"], "error": str(exc)})
    standalone_synced: list[dict[str, Any]] = []
    for record in store.active_standalone_compute_jobs():
        node = next((item for item in store.compute_nodes() if item["id"] == record.get("node_id")), None)
        if not node:
            failed.append({"job_id": record["id"], "error": "compute node not found"})
            continue
        try:
            job = await ComputeNodeClient(node["api_base_url"]).get_job(record["id"])
            standalone_synced.append(store.sync_model_merge_job(record["id"], job))
        except Exception as exc:  # noqa: BLE001 - keep polling other jobs
            failed.append({"job_id": record["id"], "error": str(exc)})
    return {"synced": len(synced) + len(standalone_synced), "failed": failed, "items": synced, "standalone": standalone_synced}
