from __future__ import annotations

import os
from pathlib import Path

from fastapi import FastAPI
from fastapi.responses import FileResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles

CONSOLE_BASE_PATH = "/niannian"


def _console_dist_candidates(nn_config: dict) -> list[Path]:
    """Docker 内模块在 site-packages，console 静态文件在 /app/console/web/dist。"""
    console_cfg = nn_config.get("console") or {}
    raw = str(console_cfg.get("static_dir", "console/web/dist")).strip()
    candidates: list[Path] = []
    env = os.environ.get("NIANNIAN_CONSOLE_DIST")
    if env:
        candidates.append(Path(env))
    path = Path(raw)
    if path.is_absolute():
        candidates.append(path)
    else:
        candidates.append(Path("/app") / raw)
        candidates.append(Path(__file__).resolve().parents[2] / raw)
    return candidates


def mount_console(app: FastAPI, nn_config: dict) -> str | None:
    """挂载 console/web/dist；SPA 路由前缀 /niannian/*。"""
    console_cfg = nn_config.get("console", {})
    if not console_cfg.get("enabled", True):
        return None
    dist: Path | None = None
    for cand in _console_dist_candidates(nn_config):
        resolved = cand.resolve()
        if resolved.is_dir() and (resolved / "index.html").is_file():
            dist = resolved
            break
    if dist is None:
        return None

    base = str(console_cfg.get("base_path", CONSOLE_BASE_PATH)).rstrip("/") or CONSOLE_BASE_PATH
    assets = dist / "assets"
    if assets.is_dir():
        app.mount(
            f"{base}/assets",
            StaticFiles(directory=str(assets)),
            name="console-assets",
        )

    index_path = dist / "index.html"

    @app.get("/", include_in_schema=False)
    async def console_root_redirect() -> RedirectResponse:
        return RedirectResponse(url=f"{base}/chat", status_code=302)

    @app.get(base, include_in_schema=False)
    async def console_base_redirect() -> RedirectResponse:
        return RedirectResponse(url=f"{base}/chat", status_code=302)

    @app.get(f"{base}/{{full_path:path}}", include_in_schema=False)
    async def console_spa(full_path: str) -> FileResponse:
        return FileResponse(index_path)

    return str(dist)
