from __future__ import annotations

from importlib.resources import as_file, files
from typing import TYPE_CHECKING

from fastapi.staticfiles import StaticFiles
from starlette.exceptions import HTTPException as StarletteHTTPException

import remotivelabs.cli.studio_ui

if TYPE_CHECKING:  # pragma: no cover - typing only
    from fastapi import FastAPI


# Locate the packaged UI resources
WEB_RESOURCE = files(remotivelabs.cli.studio_ui)


class SPAStaticFiles(StaticFiles):
    """StaticFiles with SPA fallback.

    If a requested path is not found, serve the root index.html instead so that
    client-side routing in the bundled React app can handle the route.
    """

    async def get_response(self, path: str, scope):  # type: ignore[no-untyped-def]
        try:
            return await super().get_response(path, scope)
        except StarletteHTTPException as exc:
            if exc.status_code == 404:
                return await super().get_response("index.html", scope)
            raise


def mount_studio(app: "FastAPI") -> bool:
    """Mount the bundled RemotiveStudio UI to the given FastAPI app.

    Returns True if the UI was found and mounted, otherwise False.
    """
    with as_file(WEB_RESOURCE) as web_dir:
        index_file = web_dir / "index.html"
        found_studio_app = index_file.exists()
        if found_studio_app:
            app.mount("/", SPAStaticFiles(directory=str(web_dir), html=True), name="studio")
        return found_studio_app


__all__ = ["mount_studio", "SPAStaticFiles"]
