"""
SFM (Seismograph Field Module) Proxy Router

Proxies requests from terra-view to the standalone SFM backend service.
SFM runs on port 8200 and handles MiniMate Plus seismograph communication
and event database queries.

SFM endpoints are at root level (e.g. /db/units, /device/info) — no /api/ prefix.
"""

from fastapi import APIRouter, HTTPException, Request, Response
import httpx
import logging
import os

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/sfm", tags=["sfm"])

# SFM backend URL - configurable via environment variable
SFM_BASE_URL = os.getenv("SFM_BASE_URL", "http://localhost:8200")


@router.get("/health")
async def check_sfm_health():
    """
    Check if the SFM backend service is reachable and healthy.
    """
    try:
        async with httpx.AsyncClient(timeout=5.0) as client:
            response = await client.get(f"{SFM_BASE_URL}/health")

            if response.status_code == 200:
                data = response.json()
                return {
                    "status": "ok",
                    "sfm_status": "connected",
                    "sfm_url": SFM_BASE_URL,
                    "sfm_response": data
                }
            else:
                return {
                    "status": "degraded",
                    "sfm_status": "error",
                    "sfm_url": SFM_BASE_URL,
                    "detail": f"SFM returned status {response.status_code}"
                }

    except httpx.ConnectError:
        return {
            "status": "error",
            "sfm_status": "unreachable",
            "sfm_url": SFM_BASE_URL,
            "detail": "Cannot connect to SFM backend. Is it running?"
        }
    except Exception as e:
        return {
            "status": "error",
            "sfm_status": "error",
            "sfm_url": SFM_BASE_URL,
            "detail": str(e)
        }


# HTTP catch-all — proxies everything else to SFM backend
@router.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH"])
async def proxy_to_sfm(path: str, request: Request):
    """
    Proxy all requests to the SFM backend service.

    SFM endpoints have no /api/ prefix — target URL is {SFM_BASE_URL}/{path}.
    Timeout is 60s to allow for live device round-trips (event downloads can
    take 30-45s for a full event list).
    """
    # Build target URL — SFM endpoints live at root, not /api/
    target_url = f"{SFM_BASE_URL}/{path}"

    # Forward query params
    query_params = dict(request.query_params)

    # Read body for mutation requests
    body = None
    if request.method in ["POST", "PUT", "PATCH"]:
        try:
            body = await request.body()
        except Exception as e:
            logger.error(f"Failed to read request body: {e}")
            body = None

    # Strip hop-by-hop headers
    headers = dict(request.headers)
    headers_to_exclude = ["host", "content-length", "transfer-encoding", "connection"]
    proxy_headers = {k: v for k, v in headers.items() if k.lower() not in headers_to_exclude}

    logger.info(f"Proxying {request.method} {path} → SFM: {target_url}")

    try:
        async with httpx.AsyncClient(timeout=60.0) as client:
            response = await client.request(
                method=request.method,
                url=target_url,
                params=query_params,
                headers=proxy_headers,
                content=body
            )
            return Response(
                content=response.content,
                status_code=response.status_code,
                headers=dict(response.headers),
                media_type=response.headers.get("content-type")
            )

    except httpx.ConnectError:
        logger.error(f"Failed to connect to SFM backend at {SFM_BASE_URL}")
        raise HTTPException(
            status_code=503,
            detail=f"SFM backend service unavailable. Is SFM running on {SFM_BASE_URL}?"
        )
    except httpx.TimeoutException:
        logger.error(f"Timeout connecting to SFM backend at {SFM_BASE_URL}")
        raise HTTPException(
            status_code=504,
            detail="SFM backend timeout"
        )
    except Exception as e:
        logger.error(f"Error proxying to SFM: {e}")
        raise HTTPException(
            status_code=500,
            detail=f"Failed to proxy request to SFM: {str(e)}"
        )
