"""Knowledge Graph API 客户端。

用于与 Knowledge Graph API 进行交互。
"""

import logging
from pathlib import Path

import httpx

from hezor_common.data_model.searching import (
    VectorSearchRequest,
    VectorSearchResponse,
)
from hezor_common.transfer.base_sdk import BaseAPIClient, MetaInfo
from hezor_common.transfer.knowledge_graph_sdk.base.constants import (
    DEFAULT_API_BASE_URL,
    DEFAULT_API_KEY,
)

logger = logging.getLogger(__name__)


class KnowledgeGraphAPIClient(BaseAPIClient):
    """Knowledge Graph API 客户端。

    用于与 Knowledge Graph API 进行交互。
    继承自 BaseAPIClient，提供通用的认证和请求头管理功能。

    Examples
    --------
    >>> async with KnowledgeGraphAPIClient() as client:
    ...     response = await client.get("/endpoint")
    ...     data = response.json()
    """

    def __init__(
        self,
        base_url: str = DEFAULT_API_BASE_URL,
        timeout: float = 120.0,
        api_key: str | None = DEFAULT_API_KEY,
        meta_info: MetaInfo | None = None,
        private_key_path: str | Path | None = None,
        password: bytes | None = None,
        meta_info_expires_in: int = 3600,
    ):
        """初始化客户端。

        Parameters
        ----------
        base_url : str
            API 基础 URL
        timeout : float
            请求超时时间（秒）
        api_key : str | None
            API 密钥，用于 Bearer token 认证。如果为 None，则不添加 Authorization 头
        meta_info : MetaInfo | None
            元信息对象，用于生成请求头。如果为 None，则不添加元信息头
        private_key_path : str | Path | None
            私钥文件路径，用于 JWT 签名。如果为 None 且提供了 meta_info，将使用匿名密钥
        password : bytes | None
            私钥密码，如果私钥加密则需要提供
        meta_info_expires_in : int
            MetaInfo JWT token 过期时间（秒），默认 3600 秒
        """
        super().__init__(
            base_url=base_url,
            timeout=timeout,
            api_key=api_key,
            meta_info=meta_info,
            private_key_path=private_key_path,
            password=password,
            meta_info_expires_in=meta_info_expires_in,
        )

    async def vector_search(
        self,
        question: str,
        limit: int = 10,
        score_threshold: float = 0.5,
        offset: int = 0,
        enable_entity_extraction: bool = True,
    ) -> VectorSearchResponse:
        """执行向量搜索。

        向量搜索接口，用于直接查询向量库中的数据，支持基于语义的相似度搜索。

        Parameters
        ----------
        question : str
            搜索问题
        limit : int
            返回结果数量限制，范围 1-50，默认 10
        score_threshold : float
            相似度阈值，范围 0.0-1.0，默认 0.5
        offset : int
            结果偏移量，用于分页，默认 0
        enable_entity_extraction : bool
            是否启用实体抽取，true 为实体抽取后查询，false 为直接根据问题内容向量查询，默认 true

        Returns
        -------
        VectorSearchResponse
            搜索响应，包含按集合分组的搜索结果

        Raises
        ------
        httpx.HTTPError
            HTTP 请求失败时抛出
        ValueError
            响应数据格式错误时抛出

        Examples
        --------
        >>> async with KnowledgeGraphAPIClient() as client:
        ...     response = await client.vector_search(
        ...         question="菜品有哪些",
        ...         limit=10,
        ...         score_threshold=0.5
        ...     )
        ...     print(f"Found {len(response.search_results.entities)} entities")
        """
        path = "/api/vector/search"

        # 构造请求
        request = VectorSearchRequest(
            question=question,
            limit=limit,
            score_threshold=score_threshold,
            offset=offset,
            enable_entity_extraction=enable_entity_extraction,
        )

        logger.info(
            f"Executing vector search: question='{question}', limit={limit}, "
            f"score_threshold={score_threshold}, offset={offset}"
        )

        try:
            response = await self.post(
                path,
                json=request.model_dump(),
            )
            response.raise_for_status()

            data = response.json()
            search_response = VectorSearchResponse.model_validate(data)

            logger.info(
                f"Vector search completed: entities={len(search_response.search_results.entities)}, "
                f"relationships={len(search_response.search_results.relationships)}, "
                f"chunks={len(search_response.search_results.chunks)}, "
                f"pictures={len(search_response.search_results.pictures)}, "
                f"communities={len(search_response.search_results.communities)}"
            )
            return search_response

        except httpx.HTTPError as e:
            logger.error(f"HTTP error during vector search: {e}")
            raise
        except Exception as e:
            logger.error(f"Error parsing vector search response: {e}")
            raise ValueError(f"Invalid vector search response format: {e}") from e

    async def health_check(self) -> tuple[bool, dict]:
        """执行健康检查。

        调用 GET /api/health 端点检查服务状态。

        Returns
        -------
        tuple[bool, dict]
            - bool: 健康检查是否通过（基于 response.status == "healthy"）
            - dict: 原始健康检查响应数据

        Raises
        ------
        httpx.HTTPError
            HTTP 请求失败时抛出

        Examples
        --------
        >>> async with KnowledgeGraphAPIClient() as client:
        ...     is_healthy, health = await client.health_check()
        ...     if is_healthy:
        ...         print(f"Status: {health.get('status')}")
        """
        path = "/api/health"

        logger.info("Executing health check")

        try:
            response = await self.get(path)
            response.raise_for_status()

            data = response.json()
            is_healthy = data.get("status") == "healthy"
            logger.info(f"Health check completed: {data}, is_healthy={is_healthy}")
            return is_healthy, data

        except httpx.HTTPError as e:
            logger.error(f"HTTP error during health check: {e}")
            raise
