"""Ejecución de propuestas vía Cursor Bridge API (actuador)."""

from __future__ import annotations

import time
from typing import Any

import httpx

from app.core.config import get_settings


def bridge_status() -> dict[str, Any]:
    s = get_settings()
    base = (s.cursor_bridge_url or "").rstrip("/")
    out: dict[str, Any] = {
        "enabled": bool(s.cursor_api_enabled),
        "configured": bool(base and s.cursor_bridge_token),
        "url": base,
        "project": s.cursor_bridge_project,
        "online": False,
    }
    if not base:
        return out
    try:
        with httpx.Client(timeout=5.0) as client:
            r = client.get(f"{base}/health")
            out["online"] = r.status_code < 500
            try:
                out["health"] = r.json()
            except Exception:  # noqa: BLE001
                out["health"] = {"status_code": r.status_code}
    except Exception as exc:  # noqa: BLE001
        out["error"] = str(exc)
    return out


def execute_prompt(
    prompt: str,
    *,
    project: str | None = None,
    new_chat: bool = True,
    wait: bool = True,
) -> dict[str, Any]:
    """POST /api/chat al bridge. Si wait=True, hace poll del job."""
    s = get_settings()
    if not s.cursor_api_enabled:
        return {"ok": False, "error": "CURSOR_API_ENABLED=false"}
    if not s.cursor_bridge_url or not s.cursor_bridge_token:
        return {"ok": False, "error": "Bridge URL/token no configurados"}

    base = s.cursor_bridge_url.rstrip("/")
    headers = {
        "Authorization": f"Bearer {s.cursor_bridge_token}",
        "Content-Type": "application/json",
    }
    payload = {
        "project": project or s.cursor_bridge_project,
        "message": prompt,
        "newChat": new_chat,
        "mobileLight": True,
    }
    try:
        with httpx.Client(timeout=45.0) as client:
            start = client.post(f"{base}/api/chat", headers=headers, json=payload)
            if start.status_code == 401:
                return {"ok": False, "error": "Bridge 401 — token inválido"}
            start.raise_for_status()
            data = start.json()
            stream_id = data.get("streamId") or data.get("stream_id")
            if not wait:
                return {"ok": True, "stream_id": stream_id, "raw": data}
            if not stream_id:
                return {"ok": True, "raw": data, "note": "sin streamId"}

            deadline = time.time() + max(90, s.cursor_bridge_timeout_sec)
            last: dict[str, Any] = {}
            while time.time() < deadline:
                job = client.get(f"{base}/api/chat/jobs/{stream_id}", headers=headers)
                if job.status_code >= 400:
                    time.sleep(2)
                    continue
                last = job.json()
                status = (last.get("status") or last.get("state") or "").lower()
                if status in {"done", "completed", "success", "finished", "ok"}:
                    return {"ok": True, "stream_id": stream_id, "status": status, "job": last}
                if status in {"error", "failed"}:
                    return {"ok": False, "stream_id": stream_id, "status": status, "job": last}
                time.sleep(2)
            return {
                "ok": True,
                "stream_id": stream_id,
                "status": "timeout_running",
                "job": last,
                "note": "Bridge sigue trabajando; revisa Cursor",
            }
    except Exception as exc:  # noqa: BLE001
        return {"ok": False, "error": str(exc)}
