"""只读聊天历史 HTTP API（可选依赖 fastapi/uvicorn）。"""

from __future__ import annotations

import os
from contextlib import asynccontextmanager
from pathlib import Path
from typing import Any, AsyncGenerator

from aicd.db.store import TaskStore
from aicd.home import init_home


def create_chat_read_api(*, db_path: Path, api_key: str | None) -> Any:
    from fastapi import Depends, FastAPI, Header, HTTPException, Query

    @asynccontextmanager
    async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
        store = TaskStore(db_path)
        conn = await store.connect()
        app.state.store = store
        app.state.conn = conn
        yield
        await conn.close()

    app = FastAPI(title="Aicd Chat Read API", version="1.0", lifespan=lifespan)

    async def optional_auth(
        x_api_key: str | None = Header(default=None, alias="X-API-Key"),
        authorization: str | None = Header(default=None),
    ) -> None:
        expected = (api_key or os.environ.get("AICD_API_KEY") or "").strip()
        if not expected:
            return
        got = (x_api_key or "").strip()
        if not got and authorization:
            auth = authorization.strip()
            if auth.lower().startswith("bearer "):
                got = auth[7:].strip()
        if got != expected:
            raise HTTPException(status_code=401, detail="invalid or missing API key")

    def _msg_row(r: Any) -> dict[str, Any]:
        return {
            "id": r.id,
            "session_id": r.session_id,
            "role": r.role,
            "content": r.content,
            "tool_calls_json": r.tool_calls_json,
            "created_at": r.created_at,
            "tool_call_id": r.tool_call_id,
            "tool_name": r.tool_name,
        }

    def _sum_row(r: Any) -> dict[str, Any]:
        return {
            "id": r.id,
            "session_id": r.session_id,
            "content": r.content,
            "covers_up_to_message_id": r.covers_up_to_message_id,
            "created_at": r.created_at,
        }

    @app.get("/health")
    async def health() -> dict[str, bool]:
        return {"ok": True}

    @app.get("/v1/sessions/{session_id}/messages")
    async def list_messages(
        session_id: str,
        limit: int = Query(default=200, ge=1, le=2000),
        offset: int = Query(default=0, ge=0),
        _: None = Depends(optional_auth),
    ) -> dict[str, Any]:
        store: TaskStore = app.state.store
        conn = app.state.conn
        rows = await store.list_chat_messages(
            conn, session_id, limit=limit, offset=offset
        )
        total = await store.count_chat_messages(conn, session_id)
        return {
            "session_id": session_id,
            "total": total,
            "offset": offset,
            "limit": limit,
            "messages": [_msg_row(r) for r in rows],
        }

    @app.get("/v1/sessions/{session_id}/summaries")
    async def list_summaries(
        session_id: str,
        limit: int = Query(default=50, ge=1, le=500),
        _: None = Depends(optional_auth),
    ) -> dict[str, Any]:
        store: TaskStore = app.state.store
        conn = app.state.conn
        rows = await store.list_chat_summaries(conn, session_id, limit=limit)
        return {
            "session_id": session_id,
            "summaries": [_sum_row(r) for r in rows],
        }

    return app


async def run_serve(
    *,
    home: Path | None,
    host: str,
    port: int,
    api_key: str | None,
) -> None:
    import uvicorn

    _root, layout, _cfg = init_home(home)
    db = layout["db"]
    app = create_chat_read_api(db_path=db, api_key=api_key)
    config = uvicorn.Config(app, host=host, port=port, log_level="info")
    await uvicorn.Server(config).serve()
