import requests
from typing import List, Any, Dict

from alayaflow.clients.alayamem.base_client import BaseAlayaMemClient
from alayaflow.clients.alayamem.types import (
    HybridQueryResponse,
    GetProfileResponse,
    UpdateProfileResponse,
)


class HttpAlayaMemClient(BaseAlayaMemClient):

    def __init__(self, base_url: str):
        """Initialize the HTTP client with base URL"""
        self.base_url = base_url.rstrip('/')

    def query_file(self, user_id, message, limit=10, use_query_params=False):
        """ 查询文件内容 - POST 请求 """
        query_content = self._msg_content(message)
        params = {
                "query": query_content,
                "user_id": user_id,
                "limit": limit
            }   
        return self._post_with_params("/memory/query_file", params)
   

    def commit_turn(self, session_id, user_text, assistant_text, user_id=None, window_size=10):
        """ 提交多轮对话记录 - POST 请求 """
        payload = {
            "session_id": session_id,
            "user_text": user_text,
            "assistant_text": assistant_text,
            "window_size": window_size
        }
        if user_id:
            payload["user_id"] = user_id
        return self._post("/memory/commit_turn", payload)

    def turns(self, session_id, user_id=None, limit=10):
        """ 查询对话历史记录 - GET 请求 """
        params = {
            "session_id": session_id,
            "limit": limit
        }
        if user_id:
            params["user_id"] = user_id
        return self._get("/memory/turns", params)

    def summary(self, session_id, user_id=None):
        """ 查询会话摘要 - GET 请求 """
        params = {
            "session_id": session_id,
        }
        if user_id:
            params["user_id"] = user_id
        return self._get("/memory/summary", params)

    def profile(self, user_id):
        """ 查询用户画像 - GET 请求 """
        return self._get("/memory/profile", {
            "user_id": user_id,
        })

    def hybrid_query(self, query: str, user_id: str, limit: int = 10) -> HybridQueryResponse:
        """
        混合检索 - POST 请求
        
        Args:
            query: 查询文本
            user_id: 用户ID
            limit: 返回结果数量，默认 10
            
        Returns:
            HybridQueryResponse: 包含以下字段的字典：
                - msg (str): 固定为 "hybrid_query"
                - results (dict): 检索结果，包含：
                    - ids (List[List[str]]): 文档ID列表
                    - documents (List[List[str]]): 文档内容列表
                    - metadatas (List[List[Dict]]): 元数据列表，包含文件信息
                    - distances (List[List[float]]): 距离列表
                - query (str): 查询文本
                - user_id (str): 用户ID
                - count (int): 返回结果数量
                
        Example:
            >>> response = client.hybrid_query("人工智能", "user123", limit=10)
            >>> documents = response["results"]["documents"]
            >>> for doc_list in documents:
            ...     print(doc_list[0])  # 打印第一个文档内容
        """
        payload = {
            "query": query,
            "user_id": user_id,
            "limit": limit
        }
        return self._post("/memory/hybrid_query", payload)

    def get_profile(self, user_id: str, profile_id: str) -> GetProfileResponse:
        """
        获取用户画像 - GET 请求
        
        Args:
            user_id: 用户ID
            profile_id: 画像ID
            
        Returns:
            GetProfileResponse: 包含以下字段的字典：
                - code (int): 状态码，0 表示成功
                - msg (str): 消息，通常为 "success"
                - data (dict): 画像数据，包含：
                    - profile_id (str): 画像ID
                    - user_id (str): 用户ID
                    - name (str): 画像名称
                    - type (str | None): 画像类型，可能为 null
                    - created_at (float): 创建时间戳
                    - updated_at (float): 更新时间戳
                    - content (dict): 画像内容，键值对形式
                    
        Example:
            >>> response = client.get_profile("user123", "pf_xxx")
            >>> content = response["data"]["content"]
            >>> print(content)
        """
        path = f"/api/v1/users/{user_id}/profiles/{profile_id}"
        return self._get(path, {})

    def update_profile(
        self, 
        user_id: str, 
        profile_id: str, 
        content: Dict[str, Any] = None,
        name: str = None,
        profile_type: str = None
    ) -> UpdateProfileResponse:
        """
        更新用户画像 - PUT 请求
        注意：content 字段会完全替换原有内容
        
        Args:
            user_id: 用户ID
            profile_id: 画像ID
            content: 要更新的画像内容，字典格式（可选）
            name: 新的画像名称（可选）
            profile_type: 新的画像类型（可选）
            
        Returns:
            UpdateProfileResponse: 包含以下字段的字典：
                - code (int): 状态码，0 表示成功
                - msg (str): 消息，通常为 "success"
                - data (dict): 更新后的画像数据，包含：
                    - profile_id (str): 画像ID
                    - user_id (str): 用户ID
                    - name (str): 画像名称
                    - type (str | None): 画像类型，可能为 null
                    - created_at (float): 创建时间戳
                    - updated_at (float): 更新时间戳
                    - content (dict): 画像内容，键值对形式
                
        Example:
            >>> content = {"name": "李四", "age": 25, "gender": "女"}
            >>> response = client.update_profile("user123", "pf_xxx", content=content)
            >>> print(response["msg"])
        """
        path = f"/api/v1/users/{user_id}/profiles/{profile_id}"
        payload = {}
        if content is not None:
            payload["content"] = content
        if name is not None:
            payload["name"] = name
        if profile_type is not None:
            payload["type"] = profile_type
        return self._put(path, payload)


    # ---------- 私有辅助方法 ----------
    def _get(self, path: str, params: dict, timeout: int = 30):
        """发送 GET 请求，参数作为 query string"""
        resp = requests.get(f"{self.base_url}{path}", params=params, timeout=timeout)
        resp.raise_for_status()
        return resp.json()

    def _post(self, path: str, payload: dict, timeout: int = 30):
        """发送 POST 请求，参数作为 JSON Body"""
        resp = requests.post(f"{self.base_url}{path}", json=payload, timeout=timeout)
        resp.raise_for_status()
        return resp.json()

    def _post_with_params(self, path: str, params: dict, timeout: int = 30):
        """发送 POST 请求，参数作为 Query Parameters"""
        resp = requests.post(f"{self.base_url}{path}", params=params, timeout=timeout)
        resp.raise_for_status()
        return resp.json()

    def _put(self, path: str, payload: dict, timeout: int = 30):
        """发送 PUT 请求，参数作为 JSON Body"""
        resp = requests.put(f"{self.base_url}{path}", json=payload, timeout=timeout)
        resp.raise_for_status()
        return resp.json()

    def _msg_content(self, msg):
        # 支持字典格式
        if isinstance(msg, dict):
            return msg.get("content", str(msg))
        # 支持对象格式
        return msg.content if hasattr(msg, "content") else str(msg)
