import asyncio
import json
import logging
from contextlib import asynccontextmanager
from pathlib import Path
from typing import Any, AsyncGenerator

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

from nyahome.router import admin_router, aii_router, chatroom_router, file_router, webui_router

logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(_: FastAPI) -> AsyncGenerator[None, Any]:
    # 在生命周期函数内先加载环境变量，再局部导入 nyahome 核心模块
    logger.info("🚀 服务启动中...")

    from nyahome.config import config_manager
    from nyahome.core.otp_store import email_otp_memory_store
    from nyahome.core.send_email import email_sender_queue
    from nyahome.core.task import init_admin_user
    from nyahome.database import create_db

    create_db()
    await asyncio.gather(init_admin_user(), config_manager.async_load_config())
    email_sender_queue.start()
    email_otp_memory_store.start()
    logger.info("🌸 server 启动完成。")

    try:
        yield
    except Exception as e:
        logger.error(f"捕获到无法处理的异常，NyaHome 即将结束 - {e}")
    finally:
        logger.info("🌕 服务关闭中...")


app = FastAPI(title="🌸 NyaHome ~", lifespan=lifespan)

app.include_router(webui_router)
app.include_router(chatroom_router, prefix="/api")
app.include_router(admin_router, prefix="/api")
app.include_router(file_router, prefix="/api")
app.include_router(aii_router, prefix="/api")

app.mount("/nyahome", StaticFiles(directory=Path.cwd() / "public"), name="public")
app.mount("/download", StaticFiles(directory=Path.cwd() / ".nyahome/contents"), name="upload")

# noinspection PyTypeChecker
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


def save_openapi_json(save_path: str | Path) -> None:
    try:
        from docstring_parser import DocstringStyle
    except ImportError as e:
        raise RuntimeError("开发依赖 docstring_parser 不存在，请使用 git clone 方式克隆 NyaHome。") from e

    from nyahome.cli.openapi_docstring import enrich_openapi_from_docstrings

    # 增强 openapi docstring 参数文档提取
    enrich_openapi_from_docstrings(app, docstring_style=DocstringStyle.GOOGLE)

    with open(save_path, "w") as f:
        json.dump(app.openapi(), f, indent=2)
