import ast
import os
import re
from functools import wraps

import PyPDF2
from ratelimit import sleep_and_retry, limits
import requests
from flask_app.general.读取文件.clean_pdf import extract_common_header, clean_page_content

@sleep_and_retry
@limits(calls=9, period=1)  # 每秒最多调用20次，qpm=1200万，两个服务器分流，每个10  //吃满可能有问题，改为9
def rate_limiter():
    pass  # 这个函数本身不执行任何操作，只用于限流

# 创建一个共享的装饰器
def shared_rate_limit(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        rate_limiter()  # 通过共享的限流器
        return func(*args, **kwargs)
    return wrapper

def extract_error_details(error_message):
    """
    从错误消息中提取错误代码和内部错误代码。
    假设错误消息的格式包含 'Error code: XXX - {...}'
    """
    # 提取数值型错误代码
    error_code_match = re.search(r'Error code:\s*(\d+)', error_message)
    error_code = int(error_code_match.group(1)) if error_code_match else None

    # 提取内部错误代码字符串（如 'data_inspection_failed'）
    error_code_string = None
    error_dict_match = re.search(r'Error code:\s*\d+\s*-\s*(\{.*\})', error_message)
    if error_dict_match:
        error_dict_str = error_dict_match.group(1)
        try:
            # 使用 ast.literal_eval 解析字典字符串
            error_dict = ast.literal_eval(error_dict_str)
            error_code_string = error_dict.get('error', {}).get('code')
            print(error_code_string)
        except Exception as e:
            print(f"解析错误消息失败: {e}")

    return error_code, error_code_string


def get_total_tokens(text):
    """
    调用 API 计算给定文本的总 Token 数量。  注：doubao的计算方法！与qianwen不一样
    返回：
    - int: 文本的 total_tokens 数量。
    """
    # API 请求 URL
    url = "https://ark.cn-beijing.volces.com/api/v3/tokenization"

    # 获取 API 密钥
    doubao_api_key = os.getenv("DOUBAO_API_KEY")
    if not doubao_api_key:
        raise ValueError("DOUBAO_API_KEY 环境变量未设置")

    # 请求头
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + doubao_api_key
    }
    model = "ep-20241119121710-425g6"
    # 请求体
    payload = {
        "model": model,
        "text": [text]  # API 文档中要求 text 是一个列表
    }

    try:
        response = requests.post(url, headers=headers, json=payload)
        response.raise_for_status()
        response_data = response.json()
        total_tokens=response_data["data"][0]["total_tokens"]
        return total_tokens
    except Exception as e:
        print(f"获取 Token 数量失败：{e}")
        return 0

def pdf2txt(file_path):
    common_header = extract_common_header(file_path)
    # print(f"公共抬头：{common_header}")
    # print("--------------------正文开始-------------------")
    result = ""
    with open(file_path, 'rb') as file:
        reader = PyPDF2.PdfReader(file)
        num_pages = len(reader.pages)
        # print(f"Total pages: {num_pages}")
        for page_num in range(num_pages):
            page = reader.pages[page_num]
            text = page.extract_text()
            if text:
                # print(f"--------第{page_num}页-----------")
                cleaned_text = clean_page_content(text,common_header)
                # print(cleaned_text)
                result += cleaned_text
                # print(f"Page {page_num + 1} Content:\n{cleaned_text}")
            else:
                print(f"Page {page_num + 1} is empty or text could not be extracted.")
        directory = os.path.dirname(os.path.abspath(file_path))
        output_path = os.path.join(directory, 'extract.txt')
        # 将结果保存到 extract.txt 文件中
        try:
            with open(output_path, 'w', encoding='utf-8') as output_file:
                output_file.write(result)
            print(f"提取内容已保存到: {output_path}")
        except IOError as e:
            print(f"写入文件时发生错误: {e}")
        # 返回保存的文件路径
        return output_path

def read_txt_to_string(file_path):
    """
    读取txt文件内容并返回一个包含所有内容的字符串，保持原有格式。

    参数:
    - file_path (str): txt文件的路径

    返回:
    - str: 包含文件内容的字符串
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:  # 确保使用适当的编码
            content = file.read()  # 使用 read() 保持文件格式
        return content
    except FileNotFoundError:
        return "错误：文件未找到。"
    except Exception as e:
        return f"错误：读取文件时发生错误。详细信息：{e}"

def generate_full_user_query(file_path, prompt_template):
    """
    根据文件路径和提示词模板生成完整的user_query。

    参数：
    - file_path (str): 需要解析的文件路径。
    - prompt_template (str): 包含{full_text}占位符的提示词模板。

    返回：
    - str: 完整的user_query。
    """
    # 假设extract_text_by_page已经定义，用于提取文件内容
    full_text=read_txt_to_string(file_path)
    # 格式化提示词，将提取的文件内容插入到模板中
    user_query = prompt_template.format(full_text=full_text)
    return user_query