"""
第三方API调用客户端
用于调用外部数据源接口
"""

import httpx
import logging
import json
from typing import Dict, Any, Optional, List

# 支持直接运行和模块导入两种方式
try:
    from .env_config import get_backend_base_url
except ImportError:
    from env_config import get_backend_base_url

# 获取日志记录器
logger = logging.getLogger(__name__)


class DataSourceAPIClient:
    """数据源API客户端"""
    
    def __init__(
        self, 
        base_url: Optional[str] = None,
        token: Optional[str] = None
    ):
        """
        初始化API客户端
        
        Args:
            base_url: API基础URL（默认从环境变量 BACKEND_BASE_URL 读取，如果未设置则使用 http://192.168.2.236:8088）
            token: 认证令牌（Bearer Token）
        """
        # 如果没有传入 base_url，则从环境变量读取
        if base_url is None:
            base_url = get_backend_base_url()
        
        self.base_url = base_url.rstrip('/')
        self.token = token or "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjJiYTk4ODllLWM2ZGItNDQ5YS1iZmFjLTQ2YzMxODFlODg5NCJ9.dvi8zm0LsWvJ_h9zD5blnHFRxa4z4_WBm1R487ekE7HlHzrN6dnvqhK8askqT5b1EcE8myHwRzLVMoI8UOjOrw"
        self.client = httpx.Client(timeout=30.0)
        
    def _get_headers(self) -> Dict[str, str]:
        """
        获取请求头
        
        Returns:
            请求头字典
        """
        return {
            'Authorization': f'Bearer {self.token}',
        }
    
    def get_skill_by_id(self, skill_id: str) -> Dict[str, Any]:
        """
        根据技能ID获取技能信息
        
        Args:
            skill_id: 技能ID
            
        Returns:
            API响应数据
            
        Raises:
            Exception: 请求失败时抛出
        """
        try:
            url = f"{self.base_url}/datasource/skill/getBySkillId/{skill_id}"
            
            logger.info(f"正在调用API: {url}")
            logger.info(f"请求参数 - skill_id: {skill_id}")
            
            response = self.client.get(
                url,
                headers=self._get_headers()
            )
            
            # 检查HTTP状态码
            response.raise_for_status()
            
            # 解析JSON响应
            data = response.json()
            
            logger.info(f"API调用成功: {url}")
            logger.debug(f"响应数据: {data}")
            
            return data
            
        except httpx.TimeoutException:
            error_msg = f"API请求超时: {url}"
            logger.error(error_msg)
            raise Exception(error_msg)
            
        except httpx.HTTPStatusError as e:
            error_msg = f"API请求失败 (HTTP {e.response.status_code}): {url}"
            logger.error(error_msg)
            logger.error(f"错误响应: {e.response.text}")
            raise Exception(error_msg)
            
        except httpx.RequestError as e:
            error_msg = f"API请求异常: {url}, 错误: {str(e)}"
            logger.error(error_msg)
            raise Exception(error_msg)
            
        except Exception as e:
            error_msg = f"处理API响应时出错: {str(e)}"
            logger.error(error_msg, exc_info=True)
            raise Exception(error_msg)
    
    def test_sql_with_schema(self, request_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        测试SQL语句并返回执行结果
        
        Args:
            request_data: 请求数据，包含以下字段：
                - datasourceId: 数据源ID
                - businessName: 业务名称
                - businessDescription: 业务描述
                - sqlTemplate: SQL模板
                - parameters: 参数定义
                - testParams: 测试参数
                
        Returns:
            API响应数据
            
        Raises:
            Exception: 请求失败时抛出
        """
        try:
            url = f"{self.base_url}/datasource/sqlExecutionLog/testBatchSqlWithSchema"
            
            # 构建请求头（包含Content-Type）
            headers = self._get_headers()
            headers['Content-Type'] = 'application/json'
            headers['Accept'] = '*/*'
            
            logger.info(f"正在调用测试SQL API: {url}")
            logger.info(f"请求参数: {json.dumps(request_data, ensure_ascii=False, indent=2)}")
            
            # 发送POST请求
            response = self.client.post(
                url,
                headers=headers,
                json=request_data
            )
            
            # 检查HTTP状态码
            response.raise_for_status()
            
            # 解析JSON响应
            result = response.json()
            
            logger.info(f"测试SQL API调用成功")
            logger.debug(f"响应数据: {json.dumps(result, ensure_ascii=False, indent=2)}")
            
            # 处理返回数据结构: {code, data: [{errorMessage, data}, ...], msg}
            # 检查外层 code
            if result.get("code") != 200:
                error_msg = result.get("msg", "接口返回错误")
                logger.error(f"接口返回错误: code={result.get('code')}, msg={error_msg}")
                raise Exception(error_msg)
            
            # data 是一个数组，每个元素包含 errorMessage 和 data
            data_list = result.get("data", [])
            
            # 如果不是数组，兼容旧格式
            if isinstance(data_list, dict):
                if data_list.get("errorMessage"):
                    error_msg = data_list.get("errorMessage")
                    logger.error(f"接口业务错误: {error_msg}")
                    raise Exception(error_msg)
                return data_list.get("data")
            
            # 处理数组格式，提取每个 item 的 data 并组合
            combined_data = []
            for item in data_list:
                if item.get("errorMessage"):
                    error_msg = item.get("errorMessage")
                    logger.error(f"接口业务错误: {error_msg}")
                    raise Exception(error_msg)
                item_data = item.get("data", [])
                combined_data.append(item_data)
            
            # 返回组合后的数据 [data1, data2, ...]
            return combined_data
            
        except httpx.TimeoutException:
            error_msg = f"测试SQL API请求超时: {url}"
            logger.error(error_msg)
            raise Exception(error_msg)
            
        except httpx.HTTPStatusError as e:
            error_msg = f"测试SQL API请求失败 (HTTP {e.response.status_code}): {url}"
            logger.error(error_msg)
            logger.error(f"错误响应: {e.response.text}")
            raise Exception(error_msg)
            
        except httpx.RequestError as e:
            error_msg = f"测试SQL API请求异常: {url}, 错误: {str(e)}"
            logger.error(error_msg)
            raise Exception(error_msg)
            
        except Exception as e:
            error_msg = f"处理测试SQL API响应时出错: {str(e)}"
            logger.error(error_msg, exc_info=True)
            raise Exception(error_msg)
    
    def close(self):
        """关闭HTTP客户端"""
        self.client.close()


# 创建默认客户端实例
default_client = DataSourceAPIClient()


def get_skill_by_id(skill_id: str, base_url: Optional[str] = None, token: Optional[str] = None) -> Dict[str, Any]:
    """
    便捷函数：根据技能ID获取技能信息
    
    Args:
        skill_id: 技能ID
        base_url: API基础URL（可选，默认从环境变量 BACKEND_BASE_URL 读取）
        token: 认证令牌（可选，使用默认值）
        
    Returns:
        API响应数据
    """
    if base_url or token:
        client = DataSourceAPIClient(
            base_url=base_url,
            token=token
        )
        return client.get_skill_by_id(skill_id)
    else:
        return default_client.get_skill_by_id(skill_id)


def test_sql_with_schema(request_data: Dict[str, Any], base_url: Optional[str] = None, token: Optional[str] = None) -> Dict[str, Any]:
    """
    便捷函数：测试SQL语句并返回执行结果
    
    Args:
        request_data: 请求数据，包含以下字段：
            - datasourceId: 数据源ID
            - businessName: 业务名称
            - businessDescription: 业务描述
            - sqlTemplate: SQL模板
            - parameters: 参数定义
            - testParams: 测试参数
        base_url: API基础URL（可选，默认从环境变量 BACKEND_BASE_URL 读取）
        token: 认证令牌（可选，使用默认值）
        
    Returns:
        API响应数据
    """
    if base_url or token:
        client = DataSourceAPIClient(
            base_url=base_url,
            token=token
        )
        return client.test_sql_with_schema(request_data)
    else:
        return default_client.test_sql_with_schema(request_data)


def process_skill_response(response: Dict[str, Any]) -> List[Dict[str, Any]]:
    """
    处理API响应数据，映射为businessQueries格式
    
    Args:
        response: API原始响应数据
        
    Returns:
        处理后的查询配置列表
    """
    try:
        # 提取data数组
        data_list = response.get("data", [])
        
        # 默认的员工ID参数schema
        default_employee_schema = {
            "type": "object",
            "required": ["employeeId"],
            "properties": {
                "employeeId": {
                    "type": "number",
                    "description": "员工ID，用于标识员工的唯一数字标识符",
                    "examples": [1001, 2002]
                }
            }
        }
        
        # 映射每个skill为businessQuery格式
        queries = []
        for skill in data_list:
            # 解析sqlParams字符串为JSON对象
            sql_params = json.loads(skill.get("sqlParams", "{}"))
            
            # 判断sqlParams是否为空对象
            is_empty_params = (
                not sql_params.get("properties") or 
                len(sql_params.get("properties", {})) == 0
            ) and (
                not sql_params.get("required") or 
                len(sql_params.get("required", [])) == 0
            )
            
            # 如果是空对象，使用默认的员工ID参数
            if is_empty_params:
                logger.info(f"技能 {skill.get('name')} (ID: {skill.get('id')}) 的sqlParams为空，使用默认员工ID参数")
                sql_params = default_employee_schema
            
            # 映射字段
            query = {
                "id": skill.get("id"),
                "businessName": skill.get("name"),
                "businessDescription": skill.get("description"),
                "sqlTemplate": skill.get("sqlTemplate"),
                "parameters": sql_params,
                "datasourceId": skill.get("datasourceId")
            }
            queries.append(query)
        
        logger.info(f"成功处理 {len(queries)} 条技能数据")
        return queries
        
    except Exception as e:
        logger.error(f"处理API响应数据失败: {e}", exc_info=True)
        raise

