import requests
from abc import ABC
import logging
import json

# 导入 pypinyin 用于中文转拼音
try:
    import pypinyin
except ImportError:
    pypinyin = None
    logging.warning("pypinyin 模块未安装，将使用简化的命名方式")

logger = logging.getLogger(__name__)


def pinyin_to_camel(pinyin):
    """
    将中文名称转换为工具名称
    
    处理逻辑：
    1. 如果安装了 pypinyin，将中文转换为拼音，然后转为驼峰命名
    2. 如果未安装 pypinyin，将所有非字母数字字符替换为下划线
    3. 所有符号都会被替换成下划线
    
    示例:
        "你好啊" -> "tool_NiHaoA" (有pypinyin)
        "测试-工具" -> "tool_测试_工具" (无pypinyin)
        "Hello World!" -> "tool_Hello_World_" (无pypinyin)
    
    Args:
        pinyin: 输入的字符串（可能包含中文、英文、符号等）
    
    Returns:
        str: 格式化后的工具名称，以 "tool_" 开头
    """
    import re
    
    if pypinyin is None:
        # 如果 pypinyin 未安装，使用简化的命名方式
        # 将所有非字母数字字符（包括空格、符号等）替换为下划线
        cleaned = re.sub(r'[^\w]', '_', str(pinyin))
        # 移除连续的下划线
        cleaned = re.sub(r'_+', '_', cleaned)
        # 移除首尾的下划线
        cleaned = cleaned.strip('_')
        return "tool_" + cleaned if cleaned else "tool_unnamed"
    
    # 使用 pypinyin 转换中文为拼音
    pinyin_list = pypinyin.lazy_pinyin(pinyin)
    
    # 处理每个拼音单词
    processed_words = []
    for word in pinyin_list:
        # 将所有非字母数字字符替换为下划线
        cleaned_word = re.sub(r'[^\w]', '_', word)
        # 移除连续的下划线
        cleaned_word = re.sub(r'_+', '_', cleaned_word)
        # 移除首尾的下划线
        cleaned_word = cleaned_word.strip('_')
        
        if cleaned_word:
            # 首字母大写（驼峰命名）
            processed_words.append(cleaned_word.capitalize())
    
    # 拼接所有单词
    result = "".join(processed_words) if processed_words else "Unnamed"
    return "tool_" + result


class DifyAPI(ABC):
    def __init__(self, base_url: str, dify_app_sks: list, user="pp666"):
        # dify configs
        self.dify_base_url = base_url
        self.dify_app_sks = dify_app_sks
        self.user = user

        # dify app infos
        dify_app_infos = []
        dify_app_params = []
        dify_app_metas = []
        for key in self.dify_app_sks:
            dify_app_infos.append(self.get_app_info(key))
            dify_app_params.append(self.get_app_parameters(key))
            dify_app_metas.append(self.get_app_meta(key))

        logger.info(f"Dify应用参数: {dify_app_params}")
        self.dify_app_infos = dify_app_infos
        self.dify_app_params = dify_app_params
        self.dify_app_metas = dify_app_metas
        self.dify_app_names = [x["name"] for x in dify_app_infos]

    def chat_message(
        self,
        api_key,
        inputs={},
        response_mode="streaming",
        conversation_id=None,
        user="pp666",
        files=None,
    ):
        url = f"{self.dify_base_url}/workflows/run"
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        }
        data = {
            "inputs": inputs,
            "response_mode": response_mode,
            "user": user,
        }
        logger.info("Sending data to Dify API: %s", data)
        logger.info("Sending headers to Dify API: %s", headers)
        logger.info("Sending url to Dify API: %s", url)
        if conversation_id:
            data["conversation_id"] = conversation_id
        if files:
            files_data = []
            for file_info in files:
                file_path = file_info.get("path")
                transfer_method = file_info.get("transfer_method")
                if transfer_method == "local_file":
                    files_data.append(("file", open(file_path, "rb")))
                elif transfer_method == "remote_url":
                    pass
            response = requests.post(
                url,
                headers=headers,
                data=data,
                files=files_data,
                stream=response_mode == "streaming",
            )
        else:
            response = requests.post(
                url, headers=headers, json=data, stream=response_mode == "streaming"
            )
        response.raise_for_status()
        if response_mode == "streaming":
            for line in response.iter_lines():
                if line:
                    if line.startswith(b"data:"):
                        try:
                            json_data = json.loads(line[5:].decode("utf-8"))
                            yield json_data
                        except json.JSONDecodeError:
                            logger.error(f"JSON解码错误: {line}")
        else:
            return response.json()

    def upload_file(self, api_key, file_path, user="pp666"):

        url = f"{self.dify_base_url}/files/upload"
        headers = {"Authorization": f"Bearer {api_key}"}
        files = {"file": open(file_path, "rb")}
        data = {"user": user}
        response = requests.post(url, headers=headers, files=files, data=data)
        response.raise_for_status()
        return response.json()

    def stop_response(self, api_key, task_id, user="pp666"):

        url = f"{self.dify_base_url}/chat-messages/{task_id}/stop"
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        }
        data = {"user": user}
        response = requests.post(url, headers=headers, json=data)
        response.raise_for_status()
        return response.json()

    def get_app_info(self, api_key, user="pp666"):

        url = f"{self.dify_base_url}/info"
        headers = {"Authorization": f"Bearer {api_key}"}
        params = {"user": user}
        response = requests.get(url, headers=headers, params=params)
        response.raise_for_status()

        from src.utils.tool_translation import TranslationService

        response_map = response.json()
        # 翻译工具名称
        # tool_name = response_map.get("name")
        # translated_name = TranslationService.translate_tool_name(tool_name)
        # response_map["name"] = translated_name
        # # 翻译工具描述
        # tool_description = response_map.get("description")
        # translated_description = TranslationService.translate_tool_description(
        #     tool_description
        # )
        # response_map["description"] = translated_description
        tool_name = response_map.get("name")
        if tool_name:
            # translated_name = TranslationService.translate_tool_name(tool_name)
            translated_name = pinyin_to_camel(tool_name)
            response_map["name"] = translated_name
        return response_map

    def get_app_parameters(self, api_key, user="pp666"):
        url = f"{self.dify_base_url}/parameters"
        headers = {"Authorization": f"Bearer {api_key}"}
        params = {"user": user}
        response = requests.get(url, headers=headers, params=params)
        response.raise_for_status()
        return response.json()

    def get_app_meta(self, api_key, user="pp666"):
        url = f"{self.dify_base_url}/meta"
        headers = {"Authorization": f"Bearer {api_key}"}
        params = {"user": user}
        response = requests.get(url, headers=headers, params=params)
        response.raise_for_status()
        return response.json()
