"""HTTP routes for codectx."""

from fastapi import APIRouter, HTTPException
from fastapi.responses import HTMLResponse

from codectx.db.repository import CodeRepository
from common.version import __version__


def build_router(repository: CodeRepository) -> APIRouter:
    """Create API routes bound to a repository instance."""
    router = APIRouter(prefix="/api")

    @router.get("/stats")
    async def stats() -> dict[str, object]:
        return repository.get_stats().to_dict()

    @router.get("/version")
    async def version() -> dict[str, str]:
        return {"version": __version__}

    @router.get("/files")
    async def files(limit: int = 100, offset: int = 0) -> list[dict[str, object]]:
        return repository.list_files(limit=limit, offset=offset)

    @router.get("/files/{file_id}/entities")
    async def file_entities(file_id: int) -> list[dict[str, object]]:
        return repository.get_entities_by_file_ids([file_id])

    @router.get("/entities")
    async def entities(query: str = "", limit: int = 20) -> list[dict[str, object]]:
        if query:
            return repository.search_entities(query, limit=limit)
        with repository.session_factory() as session:
            pass
        # Return empty list without query to avoid full table scan
        return repository.search_entities("", limit=limit) if query else []

    @router.get("/entities/search")
    async def search_entities(q: str, limit: int = 20) -> list[dict[str, object]]:
        return repository.search_entities(q, limit=limit)

    @router.get("/entities/{entity_id}")
    async def entity(entity_id: int) -> dict[str, object]:
        payload = repository.get_entity_by_id(entity_id)
        if payload is None:
            raise HTTPException(status_code=404, detail="entity not found")
        return payload

    @router.get("/entities/{entity_id}/code")
    async def entity_code(entity_id: int) -> dict[str, object]:
        payload = repository.get_entity_code(entity_id)
        if payload is None:
            raise HTTPException(status_code=404, detail="entity not found")
        return payload

    @router.get("/entities/{entity_id}/calls")
    async def entity_calls(entity_id: int) -> dict[str, object]:
        entity = repository.get_entity_by_id(entity_id)
        if entity is None:
            raise HTTPException(status_code=404, detail="entity not found")
        qualified = entity.get("qualified_name") or entity.get("name", "")
        result = repository.get_call_graph(qualified)
        return result or {"entity": qualified, "outgoing": [], "incoming": []}

    @router.get("/graph")
    async def graph(limit: int = 500) -> dict[str, object]:
        """Force-directed graph visualization data: nodes=entities, edges=relations."""
        files = repository.list_files(limit=limit)
        file_ids = [f["id"] for f in files]
        entities_list = repository.get_entities_by_file_ids(file_ids)
        relations = repository.get_relations_by_entity_ids([e["id"] for e in entities_list])
        return {
            "nodes": [
                {
                    "id": e["id"],
                    "label": e.get("qualified_name") or e["name"],
                    "type": e.get("type", ""),
                    "file_id": e.get("file_id"),
                }
                for e in entities_list[:limit]
            ],
            "edges": [
                {
                    "source": r["source_entity_id"],
                    "target": r["target_entity_id"],
                    "type": r["relation_type"],
                }
                for r in relations
            ],
        }

    @router.get("/tree")
    async def tree(prefix: str = "") -> dict[str, object]:
        """Directory hierarchy tree of all indexed files."""
        return repository.get_directory_tree(root_prefix=prefix)

    @router.get("/dir")
    async def dir_detail(path: str) -> dict[str, object]:
        """Files and entity counts for a directory prefix."""
        files = repository.list_files(limit=10000)
        matched = [f for f in files if f["path"].replace("\\", "/").startswith(path.replace("\\", "/"))]
        file_ids = [f["id"] for f in matched]
        entity_counts = repository.get_file_entity_counts(file_ids)
        return {
            "path": path,
            "files": [
                {**f, "entity_count": entity_counts.get(f["id"], 0)}
                for f in matched
            ],
        }

    @router.get("/versions")
    async def versions() -> list[dict[str, object]]:
        """List all indexed code versions."""
        return repository.list_versions()

    @router.get("/versions/diff/{old_version}")
    async def version_diff(old_version: str) -> list[dict[str, object]]:
        """Show files changed between old_version and latest."""
        return repository.get_changed_files(old_version)

    return router
