"""
数据库管理平台 API 调用客户端
用于调用数据库管理平台的所有 API 接口
"""

import httpx
import json
import os
from typing import Dict, Any, Optional

from .env_config import get_api_key, get_base_url
from .logger_config import get_logger

logger = get_logger(__name__)

# 默认超时配置（秒）
DEFAULT_TIMEOUT = 30.0


class AgileDBAPIClient:
    """数据库管理平台 API 客户端"""
    
    def __init__(
        self, 
        base_url: Optional[str] = None,
        api_key: Optional[str] = None,
        default_timeout: float = DEFAULT_TIMEOUT,
    ):
        """
        初始化 API 客户端
        
        Args:
            base_url: API 基础 URL（默认从环境变量 AGILE_DB_BASE_URL 读取）
            api_key: API 密钥（默认从环境变量 AGILE_DB_API_KEY 读取）
            default_timeout: 请求超时时间（秒），默认 30 秒
        """
        if base_url is None:
            base_url = get_base_url()
        
        if api_key is None:
            api_key = get_api_key()
        
        self.base_url = base_url.rstrip('/')
        self.api_key = api_key
        self.default_timeout = default_timeout
        self._client: Optional[httpx.Client] = None
        
        logger.info(f"[客户端初始化] base_url={self.base_url}")
    
    @property
    def client(self) -> httpx.Client:
        """懒加载 HTTP 客户端"""
        if self._client is None:
            self._client = httpx.Client(timeout=self.default_timeout)
        return self._client
        
    def _get_headers(self, extra_headers: Optional[Dict[str, str]] = None) -> Dict[str, str]:
        """获取请求头"""
        headers = {
            'Authorization': self.api_key if self.api_key.startswith('Bearer ') else f'Bearer {self.api_key}',
        }
        if extra_headers:
            headers.update(extra_headers)
        return headers
    
    def _build_url(self, path: str) -> str:
        """构建完整 URL"""
        if path.startswith('http://') or path.startswith('https://'):
            return path
        return f"{self.base_url}{path}"
    
    def _handle_response(self, response: httpx.Response, url: str) -> Dict[str, Any]:
        """统一处理 API 响应"""
        logger.info(f"[API响应] HTTP {response.status_code}")
        
        if response.status_code == 204:
            return {"success": True, "data": None}
        
        response.raise_for_status()
        
        try:
            data = response.json()
        except json.JSONDecodeError:
            # 非 JSON 响应（如文件下载）
            return {"success": True, "data": response.content, "raw": True}
        
        # 检查平台 API 的 {code, msg} 格式
        if isinstance(data, dict) and 'code' in data:
            if data['code'] != 200:
                error_msg = data.get('msg', '未知错误')
                logger.error(f"[API错误] {error_msg}")
                raise Exception(error_msg)
        
        return data
    
    def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """发送 GET 请求"""
        url = self._build_url(path)
        try:
            logger.info(f"[API请求] GET {url}")
            response = self.client.get(url, headers=self._get_headers(), params=params)
            return self._handle_response(response, url)
        except httpx.TimeoutException:
            raise Exception(f"API 请求超时: {url}")
        except httpx.HTTPStatusError as e:
            raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}")
        except httpx.RequestError as e:
            raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")

    def post(self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """发送 POST 请求"""
        url = self._build_url(path)
        try:
            logger.info(f"[API请求] POST {url}")
            headers = self._get_headers({'Content-Type': 'application/json'})
            response = self.client.post(url, headers=headers, json=json_data, params=params)
            return self._handle_response(response, url)
        except httpx.TimeoutException:
            raise Exception(f"API 请求超时: {url}")
        except httpx.HTTPStatusError as e:
            raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}")
        except httpx.RequestError as e:
            raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")

    def put(self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """发送 PUT 请求"""
        url = self._build_url(path)
        try:
            logger.info(f"[API请求] PUT {url}")
            headers = self._get_headers({'Content-Type': 'application/json'})
            response = self.client.put(url, headers=headers, json=json_data, params=params)
            return self._handle_response(response, url)
        except httpx.TimeoutException:
            raise Exception(f"API 请求超时: {url}")
        except httpx.HTTPStatusError as e:
            raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}")
        except httpx.RequestError as e:
            raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")

    def delete(self, path: str, params: Optional[Dict[str, Any]] = None, json_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """发送 DELETE 请求"""
        url = self._build_url(path)
        try:
            logger.info(f"[API请求] DELETE {url}")
            headers = self._get_headers()
            if json_data is not None:
                headers['Content-Type'] = 'application/json'
            response = self.client.delete(url, headers=headers, params=params, json=json_data)
            return self._handle_response(response, url)
        except httpx.TimeoutException:
            raise Exception(f"API 请求超时: {url}")
        except httpx.HTTPStatusError as e:
            raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}")
        except httpx.RequestError as e:
            raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")

    def upload(self, path: str, files: Dict[str, Any], params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """发送文件上传请求（multipart/form-data）"""
        url = self._build_url(path)
        try:
            logger.info(f"[API请求] UPLOAD {url}")
            # 文件上传不需要 Content-Type，httpx 会自动设置 multipart/form-data
            headers = self._get_headers()
            response = self.client.post(url, headers=headers, files=files, params=params)
            return self._handle_response(response, url)
        except httpx.TimeoutException:
            raise Exception(f"API 请求超时: {url}")
        except httpx.HTTPStatusError as e:
            raise Exception(f"API 请求失败 (HTTP {e.response.status_code}): {url}")
        except httpx.RequestError as e:
            raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")

    def close(self):
        """关闭 HTTP 客户端"""
        if self._client is not None:
            self._client.close()
            self._client = None
    
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        return False


# 懒加载的默认客户端
_default_client: Optional[AgileDBAPIClient] = None


def get_default_client() -> AgileDBAPIClient:
    """获取默认客户端（懒加载）"""
    global _default_client
    if _default_client is None:
        _default_client = AgileDBAPIClient()
    return _default_client
