"""知识图谱API"""
from typing import Optional
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, get_current_user
from app.models.knowledge import KnowledgeBase
from app.models.knowledge_graph import KnowledgeEntity, EntityType
from app.models.user import User
from app.services.knowledge.graph_builder import GraphBuilder
from app.services.knowledge.graph_query import GraphQuery

router = APIRouter(prefix="/knowledge-bases", tags=["知识图谱"])


class EntityCreateRequest(BaseModel):
    name: str = Field(..., max_length=500)
    entity_type: str
    description: Optional[str] = None
    properties: Optional[dict] = None


def _entity_to_dict(entity: KnowledgeEntity) -> dict:
    return {
        "id": str(entity.id),
        "name": entity.name,
        "entity_type": entity.entity_type.value,
        "description": entity.description,
        "properties": entity.properties,
        "confidence": entity.confidence,
    }


@router.post("/{kb_id}/entities/batch")
async def batch_create_entities(
    kb_id: UUID,
    entities: list[EntityCreateRequest],
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """批量创建知识图谱实体"""
    if not entities:
        raise HTTPException(status_code=400, detail="实体列表不能为空")

    if len(entities) > 100:
        raise HTTPException(status_code=400, detail="单次批量创建不能超过100个实体")

    kb = await db.get(KnowledgeBase, kb_id)
    if not kb:
        raise HTTPException(status_code=404, detail="知识库不存在")

    created = []
    for entity_req in entities:
        entity = KnowledgeEntity(
            knowledge_base_id=kb_id,
            name=entity_req.name,
            entity_type=EntityType(entity_req.entity_type),
            description=entity_req.description,
            properties=entity_req.properties or {},
        )
        db.add(entity)
        created.append(entity)

    await db.commit()
    for entity in created:
        await db.refresh(entity)

    return {"created_count": len(created), "entities": [_entity_to_dict(e) for e in created]}


@router.post("/{kb_id}/graph/build")
async def build_graph(
    kb_id: UUID,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """
    从知识库构建知识图谱

    对知识库中的所有Chunks执行实体和关系抽取
    """
    return {"message": "Use /graph/build-chunk to build from specific chunk"}


@router.post("/{kb_id}/graph/build-chunk/{chunk_id}")
async def build_graph_from_chunk(
    kb_id: UUID,
    chunk_id: UUID,
    context: Optional[str] = None,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """从单个Chunk构建图谱"""
    builder = GraphBuilder()

    try:
        stats = await builder.build_from_chunk(db, str(chunk_id), context)
        return {
            "status": "success",
            "stats": stats,
        }
    except ValueError as e:
        raise HTTPException(status_code=404, detail=str(e))


@router.get("/{kb_id}/graph/statistics")
async def get_graph_statistics(
    kb_id: UUID,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """获取图谱统计信息"""
    query = GraphQuery()
    stats = await query.get_statistics(db, str(kb_id))
    return stats


@router.get("/{kb_id}/graph/entities/search")
async def search_entities(
    kb_id: UUID,
    q: str,
    entity_type: Optional[str] = None,
    limit: int = 20,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """搜索实体"""
    query = GraphQuery()
    entities = await query.search_entities(
        db, str(kb_id), q, entity_type, limit
    )
    return {"entities": entities}


@router.get("/{kb_id}/graph/entities/{entity_id}")
async def get_entity(
    kb_id: UUID,
    entity_id: UUID,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """获取实体详情"""
    query = GraphQuery()
    entity = await query.get_entity(db, str(entity_id))

    if not entity:
        raise HTTPException(status_code=404, detail="Entity not found")

    # 获取邻居
    neighbors = await query.get_entity_neighbors(db, str(entity_id))
    entity["neighbors"] = neighbors

    return entity


@router.get("/{kb_id}/graph/path")
async def find_path(
    kb_id: UUID,
    source: str,
    target: str,
    max_hops: int = 3,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """查找两个实体之间的路径"""
    query = GraphQuery()
    path = await query.get_entity_path(db, source, target, max_hops)
    return {"path": path, "hops": len(path)}
