"""Active smoke checks for the deployed job-processing path."""

from __future__ import annotations

import time
from dataclasses import dataclass, field

import httpx

DEFAULT_TEST_AUDIO_URL = "https://upload.wikimedia.org/wikipedia/commons/4/40/En-us-hello.ogg"


@dataclass
class JobSmokeResult:
    ok: bool
    detail: str
    job_id: str | None = None
    final_status: str | None = None
    transcript: str | None = None
    elapsed_seconds: int = 0
    status_history: list[str] = field(default_factory=list)


def run_job_smoke_check(
    base_url: str,
    api_key: str,
    *,
    audio_url: str = DEFAULT_TEST_AUDIO_URL,
    language: str = "en",
    model: str = "large-v3",
    audio_duration: float | None = None,
    timeout_seconds: int = 600,
    poll_interval_seconds: int = 5,
    expected_substring: str | None = None,
) -> JobSmokeResult:
    """Submit a job and wait for the result or terminal failure."""
    base = base_url.rstrip("/")
    headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
    payload: dict[str, object] = {"audio_url": audio_url, "language": language, "model": model}
    if audio_duration is not None:
        payload["audio_duration"] = audio_duration

    with httpx.Client(timeout=15) as client:
        try:
            submit = client.post(f"{base}/api/v1/jobs", headers=headers, json=payload)
        except Exception as exc:
            return JobSmokeResult(ok=False, detail=f"Submit failed: {exc}")

        if submit.status_code >= 400:
            return JobSmokeResult(ok=False, detail=f"Submit failed: HTTP {submit.status_code} {submit.text.strip()}")

        try:
            job_id = submit.json()["job_id"]
        except Exception as exc:
            return JobSmokeResult(ok=False, detail=f"Submit response was invalid: {exc}")

        history: list[str] = []
        started = time.monotonic()
        deadline = started + timeout_seconds

        while time.monotonic() <= deadline:
            result_resp = client.get(f"{base}/api/v1/jobs/{job_id}/result", headers=headers)
            if result_resp.status_code == 200:
                data = result_resp.json()
                transcript = (data.get("result") or {}).get("transcript", "")
                elapsed = int(time.monotonic() - started)
                if expected_substring and expected_substring.lower() not in transcript.lower():
                    return JobSmokeResult(
                        ok=False,
                        detail=f"Transcript completed but missing expected text: {expected_substring!r}",
                        job_id=job_id,
                        final_status="completed",
                        transcript=transcript,
                        elapsed_seconds=elapsed,
                        status_history=history or ["completed"],
                    )
                return JobSmokeResult(
                    ok=True,
                    detail="Job completed successfully",
                    job_id=job_id,
                    final_status="completed",
                    transcript=transcript,
                    elapsed_seconds=elapsed,
                    status_history=history or ["completed"],
                )

            if result_resp.status_code not in {202, 404}:
                return JobSmokeResult(
                    ok=False,
                    detail=f"Result polling failed: HTTP {result_resp.status_code} {result_resp.text.strip()}",
                    job_id=job_id,
                    status_history=history,
                )

            status_resp = client.get(f"{base}/api/v1/jobs/{job_id}", headers=headers)
            if status_resp.status_code != 200:
                return JobSmokeResult(
                    ok=False,
                    detail=f"Status polling failed: HTTP {status_resp.status_code} {status_resp.text.strip()}",
                    job_id=job_id,
                    status_history=history,
                )

            status = status_resp.json().get("status", "unknown")
            if not history or history[-1] != status:
                history.append(status)

            if status == "failed":
                elapsed = int(time.monotonic() - started)
                return JobSmokeResult(
                    ok=False,
                    detail="Job reached terminal failed state",
                    job_id=job_id,
                    final_status=status,
                    elapsed_seconds=elapsed,
                    status_history=history,
                )

            time.sleep(poll_interval_seconds)

        elapsed = int(time.monotonic() - started)
        return JobSmokeResult(
            ok=False,
            detail="Timed out waiting for completion",
            job_id=job_id,
            final_status=history[-1] if history else None,
            elapsed_seconds=elapsed,
            status_history=history,
        )


def format_job_smoke_result(result: JobSmokeResult) -> str:
    lines = [
        f"Job smoke: {'PASS' if result.ok else 'FAIL'}",
        f"  detail: {result.detail}",
    ]
    if result.job_id:
        lines.append(f"  job_id: {result.job_id}")
    if result.final_status:
        lines.append(f"  status: {result.final_status}")
    if result.elapsed_seconds:
        lines.append(f"  elapsed_seconds: {result.elapsed_seconds}")
    if result.status_history:
        lines.append(f"  history: {' -> '.join(result.status_history)}")
    if result.transcript:
        lines.append(f"  transcript: {result.transcript[:200]}")
    return "\n".join(lines)


def troubleshooting_hints(result: JobSmokeResult) -> list[str]:
    hints: list[str] = []
    if result.ok:
        return hints

    if result.detail.startswith("Submit failed"):
        hints.append("Verify HIVE_CLIENT_API_KEY and confirm the coordinator accepts POST /api/v1/jobs.")
    if result.detail == "Timed out waiting for completion":
        hints.append("If the job stayed pending, verify at least one worker is enrolled and polling.")
        hints.append("If the job was claimed but never finished, inspect worker logs with 'hive logs --lines 200'.")
    if result.final_status == "failed":
        hints.append("Check the job events and worker logs to see why the worker reported failure.")
    if "expected text" in result.detail:
        hints.append("Confirm the chosen smoke audio matches the expected transcript substring.")
    if not hints:
        hints.append("Check coordinator logs, worker logs, and the job status/result endpoints for more detail.")
    return hints
