"""Run with: python -m uvicorn movie_sdk:app --host 127.0.0.1 --port 8100."""

import logging
import os
from typing import Annotated

from fastapi import FastAPI, HTTPException, Path
from nebulagraph_python.client import NebulaClient

app = FastAPI(title="Movie cast service (Python SDK)")
logger = logging.getLogger(__name__)
address = os.environ.get("NEBULA_ADDRESS", "127.0.0.1:9669")
username = os.environ.get("NEBULA_USER", "root")
password = os.environ["NEBULA_PASSWORD"]


@app.get("/movies/{movie_id}/actors")
def get_actors(movie_id: Annotated[int, Path(ge=1, le=9223372036854775807)]):
    # FastAPI validates the ID as an integer before this function runs.
    # The graph path is fixed; neither query accepts arbitrary query text.
    movie_query = (
        "USE /default_schema/movie MATCH (m@Movie) "
        f"WHERE m.id = {movie_id} RETURN m.name AS movie"
    )
    actors_query = (
        "USE /default_schema/movie MATCH (a@Actor)-[:Act]->(m@Movie) "
        f"WHERE m.id = {movie_id} "
        "RETURN a.id AS actor_id, a.name AS actor ORDER BY actor_id"
    )

    client = None
    try:
        # A request owns its client and closes it before returning.
        client = NebulaClient(
            addresses=address,
            user_name=username,
            password=password,
            connect_timeout_ms=3000,
            request_timeout_ms=10000,
        )
        movies = list(client.execute(movie_query).as_primitive_by_row())
        actors = (
            list(client.execute(actors_query).as_primitive_by_row())
            if movies
            else []
        )
    except Exception as exc:
        logger.warning("Database request failed (%s)", type(exc).__name__)
        raise HTTPException(status_code=502, detail="Database request failed") from exc
    finally:
        if client is not None:
            client.close()

    if not movies:
        raise HTTPException(status_code=404, detail="Movie not found")

    return {"movie_id": movie_id, "movie": movies[0]["movie"], "actors": actors}
