#flask_app/routes/utils.py
import json
import os
from functools import wraps

from flask import request, jsonify, current_app, g

from flask_app.general.llm.清除file_id import read_file_ids, delete_file_by_ids
from flask_app.general.llm.通义千问long import upload_file, qianwen_long
from flask_app.logger_setup import create_logger


def validate_request():
    """
    验证请求中的JSON数据。
    """
    if not request.is_json:
        return jsonify({'error': 'Missing JSON in request'}), 400
    file_url = request.json.get('file_url')
    zb_type = request.json.get('zb_type', 2)    #zb_type:默认按货物标解析
    if not file_url:
        return jsonify({'error': 'No file URL provided'}), 400
    try:
        zb_type = int(zb_type)
    except (ValueError, TypeError):
        return jsonify({'error': 'Invalid zb_type provided'}), 400
    return file_url, zb_type
def generate_deviation_response(tech_deviation, tech_star_deviation, business_deviation, business_star_deviation,
                                zigefuhe_deviation,proof_materials, logger):
    logger.info(f"技术偏离表: {json.dumps(tech_deviation, ensure_ascii=False, indent=4)}")
    logger.info(f"技术偏离表带星: {json.dumps(tech_star_deviation, ensure_ascii=False, indent=4)}")
    logger.info(f"商务偏离表: {json.dumps(business_deviation, ensure_ascii=False, indent=4)}")
    logger.info(f"商务偏离表带星: {json.dumps(business_star_deviation, ensure_ascii=False, indent=4)}")
    logger.info(f"资格检查偏离表: {json.dumps(zigefuhe_deviation, ensure_ascii=False, indent=4)}")
    logger.info(f"所需提交的材料: {json.dumps(proof_materials, ensure_ascii=False, indent=4)}")

    tech_deviation_response = {
        'message': 'procurement_reqs',
        'status': 'success',
        'data': json.dumps(tech_deviation, ensure_ascii=False)
    }
    tech_deviation_star_response = {
        'message': 'jishu_star_deviation',
        'status': 'success',
        'data': json.dumps(tech_star_deviation, ensure_ascii=False)
    }
    zigefuhe_deviation_response = {
        'message': 'zigefuhe_deviation',
        'status': 'success',
        'data': json.dumps(zigefuhe_deviation, ensure_ascii=False)
    }
    shangwu_deviation_response = {
        'message': 'shangwu_deviation',
        'status': 'success',
        'data': json.dumps(business_deviation, ensure_ascii=False)
    }
    shangwu_star_deviation_response = {
        'message': 'shangwu_star_deviation',
        'status': 'success',
        'data': json.dumps(business_star_deviation, ensure_ascii=False)
    }
    proof_materials_response = {
        'message': 'proof_materials',
        'status': 'success',
        'data': json.dumps(proof_materials, ensure_ascii=False)
    }

    return (
        tech_deviation_response,
        tech_deviation_star_response,
        zigefuhe_deviation_response,
        shangwu_deviation_response,
        shangwu_star_deviation_response,
        proof_materials_response
    )

def require_connection_limit():
    """装饰器：确保路由使用连接限制，并正确处理生成器函数"""
    def decorator(f):
        @wraps(f)
        def wrapped(*args, **kwargs):
            limiter = getattr(current_app, 'connection_limiter', None)
            if limiter is None:
                current_app.logger.error("ConnectionLimiter 未初始化")
                return jsonify({'error': 'Server configuration error'}), 500

            acquired = limiter.semaphore.acquire(blocking=True)
            if not acquired:
                return jsonify({
                    'error': 'Server is busy. Please try again later.',
                    'code': 503
                }), 503

            generator = f(*args, **kwargs)
            try:
                for item in generator:
                    yield item
            finally:
                limiter.semaphore.release()
        return wrapped
    return decorator

#装饰器来简化验证和日志初始化
def validate_and_setup_logger(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        # 进行请求验证
        validation_result = validate_request()
        if isinstance(validation_result, tuple):
            file_url, zb_type = validation_result

            # 根据蓝图确定子文件夹
            blueprint = request.blueprint
            subfolder_map = {
                'judge_zbfile': 'output4',
                'get_deviation': 'output3',
                'little_zbparse': 'output2',
                'upload': 'output1',
                'test_zbparse': 'test_output'
            }
            subfolder = subfolder_map.get(blueprint, 'test_output')

            # 创建 logger 和 output_folder
            create_logger(current_app, subfolder)
            # 将验证后的数据存储在 g 对象中
            g.file_url = file_url
            g.zb_type = zb_type
            return f(*args, **kwargs)
        else:
            # 验证失败，返回错误响应
            return validation_result
    return decorated_function

def perform_cleanup(output_folder, logger):
    """
    清理逻辑：删除临时文件或其他资源。
    """
    try:
        if output_folder:
            logger.info(f"正在清理输出文件夹: {output_folder}")
            file_ids = read_file_ids(output_folder)
            failed_file_ids = delete_file_by_ids(file_ids)
            if failed_file_ids:
                logger.error(f"以下文件删除失败: {failed_file_ids}")
            else:
                logger.info("清理完毕！")
    except Exception as e:
        logger.error(f"清理过程中发生异常: {str(e)}")

def create_response_normal(message, status, data=''):
    """
    创建统一格式的 JSON 响应。

    参数:
        message (str): 响应消息。
        status (str): 状态标记，'success' 或 'error'。
        data (str, optional): 响应数据。默认为空字符串。
        status_code (int, optional): HTTP 状态码。默认为 200。

    返回:
        Response: Flask 响应对象。
    """
    response = jsonify({
        'message': message,
        'status': status,
        'data': data
    })
    return response
def create_response(message, status, data):
    """
    创建一个统一格式的响应字典。

    :param message: 响应消息
    :param status: 响应状态（如 'success', 'error', 'processing'）
    :param data: 具体的数据内容
    :return: 字典格式的响应
    """
    return {
        'message': message,
        'status': status,
        'data': data
    }


def sse_format(response):
    """
    将响应格式化为 Server-Sent Events (SSE) 的格式。
    """
    return f"data: {json.dumps(response, ensure_ascii=False)}\n\n"


def log_error_unique_id(unique_id, selection=6):
    """
    记录失败调用的 unique_id 到对应的错误日志文件中。

    参数：
        unique_id (str): 唯一标识符
        selection (int): 接口选择编号，用于确定记录到哪个错误文件
    """
    error_dir = os.path.join("flask_app", "static", "output", 'error_record')
    os.makedirs(error_dir, exist_ok=True)

    # 根据 selection 映射到不同的错误文件
    error_file_map = {
        1: 'upload_error.txt',
        2: 'little_zbparse_error.txt',
        3: 'get_deviation_error.txt',
        4: 'judge_zbfile_error.txt',
        5: 'test_zbparse_error.txt'
        # 如果有更多接口，可以在这里继续添加
    }
    # 获取对应的错误文件名，如果 selection 不在映射中，则使用默认文件名
    error_file_name = error_file_map.get(selection, 'general_error.txt')
    error_file_path = os.path.join(error_dir, error_file_name)

    # 将 unique_id 写入错误文件
    with open(error_file_path, 'a', encoding='utf-8') as f:
        f.write(f"{unique_id}\n")

def is_gibberish_file(file_path):
    user_query="该文件是否为乱码文件,你的回答仅限于'是''否',不要返回其他解释性回答"
    file_id=upload_file(file_path)
    model_ans=qianwen_long(file_id,user_query)
    if '是' in model_ans:
        return True
    return False