#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
通用第三方API管理器
支持多种不同类型的第三方API，包括需要签名和不需要签名的API
"""

import os
import hashlib
import requests
import logging
from datetime import datetime
from typing import Dict, Any, Optional, Union
import json
import time
import urllib.parse
from .api_config import api_config

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class UniversalAPIManager:
    """通用第三方API管理器"""
    
    def __init__(self):
        """初始化API管理器"""
        self.config = api_config
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Universal-API-Manager/1.0',
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        })
    
    def _get_provider_config(self, provider: str) -> Dict[str, Any]:
        """获取API提供商配置"""
        config = self.config.get_api_config(provider)
        if not config:
            raise ValueError(f"未找到API提供商配置: {provider}")
        return config
    
    def _get_endpoint_config(self, provider: str, endpoint: str) -> Dict[str, Any]:
        """获取端点配置"""
        endpoint_config = self.config.get_endpoint_config(provider, endpoint)
        if not endpoint_config:
            raise ValueError(f"未找到端点配置: {provider}.{endpoint}")
        return endpoint_config
    
    def _generate_chinaz_sign(self, date: datetime = None) -> str:
        """
        生成站长之家API签名
        
        Args:
            date: 指定日期，默认为当前日期
            
        Returns:
            str: 32位MD5签名
        """
        if date is None:
            date = datetime.now()
        
        # 格式化日期为YYYYMMDD
        date_str = date.strftime("%Y%m%d")
        
        # 构建签名字符串
        sign_str = f"634xz{date_str}"
        
        # 生成MD5哈希
        md5_hash = hashlib.md5(sign_str.encode('utf-8')).hexdigest()
        
        return md5_hash
    
    def _build_url(self, provider: str, endpoint: str, params: Dict[str, Any]) -> str:
        """
        构建完整的API请求URL
        
        Args:
            provider: API提供商
            endpoint: 端点名称
            params: 请求参数
            
        Returns:
            str: 完整的URL
        """
        provider_config = self._get_provider_config(provider)
        endpoint_config = self._get_endpoint_config(provider, endpoint)
        
        base_url = provider_config['base_url']
        path = endpoint_config['path']
        method = endpoint_config['method']
        
        # 构建完整URL
        full_url = f"{base_url}{path}"
        
        # 处理参数
        if method.upper() == 'GET' and params:
            # 对于GET请求，将参数添加到URL中
            query_string = urllib.parse.urlencode(params)
            full_url = f"{full_url}?{query_string}"
        
        return full_url
    
    def _validate_params(self, provider: str, endpoint: str, params: Dict[str, Any]) -> None:
        """
        验证请求参数
        
        Args:
            provider: API提供商
            endpoint: 端点名称
            params: 请求参数
            
        Raises:
            ValueError: 缺少必需参数时抛出异常
        """
        endpoint_config = self._get_endpoint_config(provider, endpoint)
        required_params = endpoint_config.get('required_params', [])
        
        missing_params = []
        for param in required_params:
            if param not in params or params[param] is None:
                missing_params.append(param)
        
        if missing_params:
            raise ValueError(f"缺少必需参数: {', '.join(missing_params)}")
    
    def _prepare_params(self, provider: str, endpoint: str, params: Dict[str, Any]) -> Dict[str, Any]:
        """
        准备请求参数，根据不同的API类型添加必要的参数
        
        Args:
            provider: API提供商
            endpoint: 端点名称
            params: 原始参数
            
        Returns:
            Dict[str, Any]: 处理后的参数
        """
        provider_config = self._get_provider_config(provider)
        prepared_params = params.copy()
        
        # 根据不同的API提供商添加特定参数
        if provider == 'chinaz':
            # 站长之家API需要签名
            if 'sign' not in prepared_params:
                prepared_params['sign'] = self._generate_chinaz_sign()
        
        elif provider == 'xiaohongshu':
            # 小红书接口使用 JustOneAPI 平台，需要 token 参数
            if 'token' not in prepared_params or not prepared_params['token']:
                api_key = provider_config.get('api_key')
                if api_key:
                    prepared_params['token'] = api_key

        elif provider == 'jizhiliao':
            # 极致聊接口需要 key，默认从配置读取
            if 'key' not in prepared_params or not prepared_params['key']:
                api_key = provider_config.get('api_key')
                if api_key:
                    prepared_params['key'] = api_key
            if 'verifycode' not in prepared_params:
                default_verifycode = provider_config.get('verifycode')
                if default_verifycode is not None:
                    prepared_params['verifycode'] = default_verifycode
        
        return prepared_params
    
    def make_request(self, 
                    provider: str,
                    endpoint: str,
                    params: Dict[str, Any] = None,
                    timeout: int = 60,
                    retries: int = 3) -> Dict[str, Any]:
        """
        发送API请求
        
        Args:
            provider: API提供商名称
            endpoint: 端点名称
            params: 请求参数
            timeout: 超时时间（秒）
            retries: 重试次数
            
        Returns:
            Dict[str, Any]: API响应数据
        """
        params = params or {}
        
        # 验证参数
        self._validate_params(provider, endpoint, params)
        
        # 准备参数
        prepared_params = self._prepare_params(provider, endpoint, params)
        
        # 获取端点配置
        endpoint_config = self._get_endpoint_config(provider, endpoint)
        method = endpoint_config['method'].upper()
        
        # 构建URL
        url = self._build_url(provider, endpoint, prepared_params)
        
        logger.info(f"发送{method}请求到: {url}")
        
        # 发送请求
        for attempt in range(retries + 1):
            try:
                if method == 'GET':
                    response = self.session.get(url, timeout=timeout)
                elif method == 'POST':
                    response = self.session.post(url, json=prepared_params, timeout=timeout)
                else:
                    raise ValueError(f"不支持的HTTP方法: {method}")
                
                # 检查响应状态
                response.raise_for_status()
                
                # 解析响应
                try:
                    result = response.json()
                except json.JSONDecodeError:
                    result = {'raw_response': response.text}
                
                logger.info(f"API请求成功: {provider}.{endpoint}")
                return result
                
            except requests.exceptions.RequestException as e:
                logger.warning(f"API请求失败 (尝试 {attempt + 1}/{retries + 1}): {e}")
                if attempt == retries:
                    logger.error(f"API请求最终失败: {provider}.{endpoint}")
                    return {
                        'error': True,
                        'message': f"API请求失败: {str(e)}",
                        'provider': provider,
                        'endpoint': endpoint
                    }
                time.sleep(2 ** attempt)  # 指数退避
    
    # 站长之家API的便捷方法
    def query_copyright_software(self, company_name: str, chinaz_ver: str = "1") -> Dict[str, Any]:
        """查询企业软件著作权"""
        params = {
            'entName': company_name,
            'pageNo': '1',
            'range': '100',
            'ChinazVer': chinaz_ver
        }
        return self.make_request('chinaz', 'copyright_software', params)

    def query_patent_info(self, company_name: str, chinaz_ver: str = "1") -> Dict[str, Any]:
        """查询企业专利信息"""
        params = {
            'searchKey': company_name,
            'pageNo': '1',
            'range': '100',
            'searchType': '0',
            'ChinazVer': chinaz_ver
        }
        return self.make_request('chinaz', 'patent', params)

    def query_judicial_data(self, company_name: str, chinaz_ver: str = "1") -> Dict[str, Any]:
        """查询司法综合数据"""
        params = {
            'q': company_name,
            'pageNo': '1',
            'ChinazVer': chinaz_ver
        }
        return self.make_request('chinaz', 'judgement', params)
    
    # 小红书便捷方法
    def get_xiaohongshu_note_detail(self, note_id: str) -> Dict[str, Any]:
        """
        获取小红书笔记详情
        
        Args:
            note_id: 笔记ID
            
        Returns:
            Dict[str, Any]: 笔记详情数据
        """
        params = {'noteId': note_id}
        
        return self.make_request('xiaohongshu', 'xiaohongshu_note_detail', params)

    # 极致聊便捷方法
    def search_jizhiliao_index(
        self,
        keyword: str,
        mode: int = 2,
        business_type: int = 8192,
        sub_search_type: int = 0,
        key: Optional[str] = None,
        verifycode: Optional[str] = None,
    ) -> Dict[str, Any]:
        """执行极致聊指数搜索"""
        params: Dict[str, Any] = {
            'keyword': keyword,
            'mode': mode,
            'BusinessType': business_type,
            'sub_search_type': sub_search_type,
        }
        if key is not None:
            params['key'] = key
        if verifycode is not None:
            params['verifycode'] = verifycode

        return self.make_request('jizhiliao', 'index_search', params)

    # 通用方法
    def list_providers(self) -> list:
        """列出所有可用的API提供商"""
        return self.config.list_providers()
    
    def list_endpoints(self, provider: str) -> list:
        """列出指定提供商的所有端点"""
        return self.config.list_endpoints(provider)
    
    def get_endpoint_info(self, provider: str, endpoint: str) -> Dict[str, Any]:
        """获取端点详细信息"""
        return self._get_endpoint_config(provider, endpoint)
    
    def set_api_key(self, provider: str, api_key: str) -> None:
        """设置API密钥"""
        self.config.set_api_key(provider, api_key)
    
    def add_endpoint(self, 
                    provider: str,
                    endpoint_name: str,
                    path: str,
                    method: str = 'GET',
                    description: str = '',
                    required_params: list = None,
                    optional_params: list = None) -> None:
        """添加新的API端点"""
        self.config.add_endpoint(
            provider=provider,
            endpoint_name=endpoint_name,
            path=path,
            method=method,
            description=description,
            required_params=required_params,
            optional_params=optional_params
        )


# 创建全局实例
universal_api = UniversalAPIManager()