# 环境要求：Python 3.8+
# 依赖包：pip install openai python-dotenv requests     beautifulsoup4

import os
import json
import requests
from bs4 import BeautifulSoup
import logging
import openai
from dotenv import load_dotenv

os.environ["OPENAI_API_KEY"] = "xxxx"
os.environ["OPENAI_BASE_URL"] = "https://api.openai.com/v1"

# 加载环境变量
load_dotenv()

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def get_exchange_rate(from_currency: str, to_currency: str) -> dict:
    """
    获取指定货币对的实时汇率

    Args:
        from_currency: 源货币代码
        to_currency: 目标货币代码

    Returns:
        包含汇率信息的字典
    """
    try:
        # 调用中国银行外汇牌价API获取实时汇率数据
        response = requests.get('https://www.boc.cn/sourcedb/whpj/')
        response.raise_for_status()  # 检查HTTP错误

        # 设置正确的编码
        response.encoding = 'utf-8'

        # 解析HTML内容，提取汇率信息
        soup = BeautifulSoup(response.text, 'html.parser')

        # 查找汇率表格（中国银行外汇牌价页面的表格结构）
        # 根据实际HTML结构，表格有cellpadding="0" align="left"属性
        rate_table = soup.find('table', {'cellpadding': '0', 'align': 'left'})

        if not rate_table:
            # 如果找不到表格，尝试其他解析方法
            return {
                "success": False,
                "error": "无法解析汇率数据，网站结构可能已发生变化"
            }

        # 解析汇率数据
        rate = None
        currency_mapping = {
            "USD": "美元",
            "EUR": "欧元",
            "JPY": "日元"
        }

        # 查找包含目标货币的行
        rows = rate_table.find_all('tr')
        for row in rows:
            cells = row.find_all('td')
            if len(cells) >= 4:  # 确保有足够的列
                currency_name = cells[0].get_text(strip=True) if cells[0] else ""

                # 根据货币名称匹配
                if (from_currency == "CNY" and to_currency in currency_mapping and
                        currency_mapping[to_currency] in currency_name):
                    try:
                        # 现汇卖出价在第4列（索引3），这是100外币兑换人民币的价格
                        rate_text = cells[3].get_text(strip=True) if len(cells) > 3 else ""
                        rate_per_100 = float(rate_text)
                        # 转换为1人民币兑换多少外币
                        rate = 100 / rate_per_100
                        break
                    except (ValueError, IndexError):
                        continue
                elif (from_currency in currency_mapping and to_currency == "CNY" and
                      currency_mapping[from_currency] in currency_name):
                    try:
                        # 现汇买入价在第2列（索引1），这是100外币兑换人民币的价格
                        rate_text = cells[1].get_text(strip=True) if len(cells) > 1 else ""
                        rate_per_100 = float(rate_text)
                        # 转换为1外币兑换多少人民币
                        rate = rate_per_100 / 100
                        break
                    except (ValueError, IndexError):
                        continue

        if rate is None:
            return {
                "success": False,
                "error": f"暂不支持{from_currency}到{to_currency}的汇率查询，或API数据格式发生变化"
            }

        return {
            "success": True,
            "from_currency": from_currency,
            "to_currency": to_currency,
            "exchange_rate": round(rate, 4),
            "timestamp": "2024-12-19T10:30:00Z",
            "source": "中国银行外汇牌价"
        }

    except requests.RequestException as e:
        return {
            "success": False,
            "error": f"网络请求失败: {str(e)}"
        }
    except Exception as e:
        return {
            "success": False,
            "error": f"汇率查询失败: {str(e)}"
        }


# 定义工具描述
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_exchange_rate",
            "description": "获取指定货币对的实时汇率",
            "parameters": {
                "type": "object",
                "properties": {
                    "from_currency": {
                        "type": "string",
                        "description": "源货币代码，如CNY、USD、EUR",
                        "enum": ["CNY", "USD", "EUR", "JPY"]
                    },
                    "to_currency": {
                        "type": "string",
                        "description": "目标货币代码，如CNY、USD、EUR",
                        "enum": ["CNY", "USD", "EUR", "JPY"]
                    }
                },
                "required": ["from_currency", "to_currency"]
            }
        }
    }
]


def chat_with_function_call(user_message: str) -> str:
    """
    使用Function Call功能与AI对话

    Args:
        user_message: 用户输入的消息

    Returns:
        AI的回复
    """
    try:
        # 使用标准的OpenAI API格式
        messages = [
            {"role": "user", "content": user_message}
        ]

        print(f"发送消息: {messages}")
        print(f"工具描述: {tools}")

        # 发送消息给AI，启用Function Call
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )

        print(f"API响应类型: {type(response)}")
        print(f"API响应内容: {response}")

        # 检查响应类型
        if isinstance(response, str):
            return f"API返回字符串: {response}"

        # 检查是否有工具调用
        if hasattr(response, 'choices') and response.choices and response.choices[0].message.tool_calls:
            # 有工具调用
            tool_calls = response.choices[0].message.tool_calls

            # 添加AI的回复到消息列表
            messages.append(response.choices[0].message)

            # 处理每个工具调用
            for tool_call in tool_calls:
                function_name = tool_call.function.name
                function_args = json.loads(tool_call.function.arguments)

                if function_name == "get_exchange_rate":
                    # 执行汇率查询
                    result = get_exchange_rate(function_args["from_currency"],
                                               function_args["to_currency"])

                    # 添加工具调用结果到消息列表
                    messages.append({
                        "role": "tool",
                        "tool_call_id": tool_call.id,
                        "content": json.dumps(result, ensure_ascii=False)
                    })

            # 获取最终回复
            final_response = client.chat.completions.create(
                model="gpt-4o-mini",
                messages=messages
            )

            return final_response.choices[0].message.content
        else:
            # 没有工具调用，直接返回AI的回复
            if hasattr(response, 'choices') and response.choices:
                return response.choices[0].message.content
            else:
                return f"无法解析API响应: {response}"

    except Exception as e:
        import traceback
        return f"对话过程中出现错误: {str(e)}\n{traceback.format_exc()}"


# 测试Function Call功能
if __name__ == "__main__":
    # 测试需要调用工具的问题
    test_message = "人民币兑美元的汇率是多少？"
    print(f"用户: {test_message}")
    print(f"AI: {chat_with_function_call(test_message)}")
    print("-" * 50)

    # 测试不需要调用工具的问题
    test_message2 = "你好，今天天气怎么样？"
    print(f"用户: {test_message2}")
    print(f"AI: {chat_with_function_call(test_message2)}")
