"""Smoke checks for a deployed hosted manager surface."""

from __future__ import annotations

from dataclasses import dataclass
from urllib.parse import urlparse

import httpx


@dataclass
class SmokeResult:
    name: str
    ok: bool
    detail: str


def run_manager_smoke_check(
    base_url: str,
    expected_origin: str | None = None,
    expected_rp_id: str | None = None,
) -> list[SmokeResult]:
    """Run read-only smoke checks against a deployed coordinator."""
    base = base_url.rstrip("/")
    if not expected_origin:
        expected_origin = base
    if not expected_rp_id:
        expected_rp_id = urlparse(base).hostname or "localhost"

    results: list[SmokeResult] = []

    # 1. Login page renders
    results.append(_check_login_page(base))

    # 2. Config endpoint returns expected origin/rp_id
    results.append(_check_config(base, expected_origin, expected_rp_id))

    # 3. Anonymous session returns expected shape
    results.append(_check_anonymous_session(base))

    return results


def _check_login_page(base: str) -> SmokeResult:
    try:
        resp = httpx.get(f"{base}/manager/login", timeout=10, follow_redirects=True)
        if resp.status_code != 200:
            return SmokeResult("login_page", False, f"HTTP {resp.status_code}")
        # Use a stable structural invariant, not exact marketing copy
        if "<form" not in resp.text.lower() and "passkey" not in resp.text.lower():
            return SmokeResult("login_page", False, "Page rendered but missing login form or passkey reference")
        return SmokeResult("login_page", True, "OK")
    except Exception as e:
        return SmokeResult("login_page", False, f"Connection failed: {e}")


def _check_config(base: str, expected_origin: str, expected_rp_id: str) -> SmokeResult:
    try:
        resp = httpx.get(f"{base}/manager/api/config", timeout=10)
        if resp.status_code != 200:
            return SmokeResult("config", False, f"HTTP {resp.status_code}")
        data = resp.json()
        origins = data.get("origins", [])
        if expected_origin not in origins:
            return SmokeResult("config", False, f"Origin mismatch: got {origins}, expected {expected_origin}")
        if data.get("rpId") != expected_rp_id:
            return SmokeResult("config", False, f"rpId mismatch: got {data.get('rpId')}, expected {expected_rp_id}")
        return SmokeResult("config", True, "OK")
    except Exception as e:
        return SmokeResult("config", False, f"Connection failed: {e}")


def _check_anonymous_session(base: str) -> SmokeResult:
    try:
        resp = httpx.get(f"{base}/manager/api/session", timeout=10)
        if resp.status_code != 200:
            return SmokeResult("session", False, f"HTTP {resp.status_code}")
        data = resp.json()
        if "authenticated" not in data:
            return SmokeResult("session", False, "Missing 'authenticated' field")
        return SmokeResult("session", True, "OK")
    except Exception as e:
        return SmokeResult("session", False, f"Connection failed: {e}")


def format_results(results: list[SmokeResult]) -> str:
    lines = []
    for r in results:
        status = "PASS" if r.ok else "FAIL"
        lines.append(f"  [{status}] {r.name}: {r.detail}")
    total_pass = sum(1 for r in results if r.ok)
    header = f"Smoke check: {total_pass}/{len(results)} passed"
    return header + "\n" + "\n".join(lines)


def manual_browser_checklist(base_url: str) -> list[str]:
    return [
        f"Open {base_url}/manager/login in a browser",
        "Bootstrap or log in with a passkey",
        "Confirm /manager dashboard loads with session",
        "Log out and verify redirect to login",
    ]


def troubleshooting_hints(results: list[SmokeResult]) -> list[str]:
    """Return targeted operator hints for any failed smoke checks."""
    hints: list[str] = []
    failed = {result.name for result in results if not result.ok}

    if "login_page" in failed:
        hints.append(
            "Verify the deployed hostname serves /manager/login and no proxy "
            "or redirect rule strips that route."
        )
    if "config" in failed:
        hints.append(
            "Compare HIVE_MANAGER_ORIGIN and HIVE_MANAGER_RP_ID against the real "
            "deployed hostname and Fly secrets."
        )
    if "session" in failed:
        hints.append(
            "Verify the manager API routes are deployed cleanly and the app can "
            "return an anonymous /manager/api/session payload."
        )

    if not hints:
        hints.append("Check the deployed app logs and compare the smoke output against docs/first-deploy-runbook.md.")

    return hints
