"""
施工方案审查API错误码统一定义
集中管理所有接口的错误码和错误响应格式
"""

from typing import Dict, Any
from fastapi import HTTPException
from foundation.logger.loggering import server_logger as logger

class ErrorCodes:
    """错误码常量定义"""

    # 文件上传接口错误码 (WJSC001-WJSC008)
    WJSC001 = {
        "code": "WJSC001",
        "error_type": "FILE_MISSING",
        "message": "未上传文件",
        "status_code": 400
    }

    WJSC002 = {
        "code": "WJSC002",
        "error_type": "FILE_MULTIPLE",
        "message": "仅支持单文件上传",
        "status_code": 400
    }

    WJSC003 = {
        "code": "WJSC003",
        "error_type": "FILE_REJECTED",
        "message": "格式错误、内容违规、文件为空",
        "status_code": 400
    }

    WJSC004 = {
        "code": "WJSC004",
        "error_type": "FILE_FORMAT_UNSUPPORTED",
        "message": "文件格式不支持（仅允许pdf/doc/docx）",
        "status_code": 400
    }

    WJSC005 = {
        "code": "WJSC005",
        "error_type": "FILE_SIZE_EXCEEDED",
        "message": "文件过大（最大不超过30MB）",
        "status_code": 400
    }

    WJSC006 = {
        "code": "WJSC006",
        "error_type": "PROJECT_PLAN_TYPE_INVALID",
        "message": "无效工程方案类型（未提供或未注册）",
        "status_code": 400
    }

    WJSC007 = {
        "code": "WJSC007",
        "error_type": "UNAUTHORIZED",
        "message": "认证失败（未提供或无效的Authorization）",
        "status_code": 401
    }

    WJSC008 = {
        "code": "WJSC008",
        "error_type": "INVALID_USER",
        "message": "用户标识未提供或无效",
        "status_code": 403
    }

    WJSC009 = {
        "code": "WJSC009",
        "error_type": "CALLBACK_URL_MISS",
        "message": "回调客户端地址缺失，请提供回调客户端地址",
        "status_code": 403
    }

    WJSC010 = {
        "code": "WJSC010",
        "error_type": "TASK_ALREADY_EXISTS",
        "message": "任务已存在，请勿重复提交",
        "status_code": 409
    }

    WJSC011 = {
        "code": "WJSC011",
        "error_type": "INTERNAL_ERROR",
        "message": "服务端内部错误",
        "status_code": 500
    }

    # 进度查询接口错误码 (JDLX001-JDLX006)
    JDLX001 = {
        "code": "JDLX001",
        "error_type": "MISSING_PARAMETERS",
        "message": "请求参数缺失",
        "status_code": 400
    }

    JDLX002 = {
        "code": "JDLX002",
        "error_type": "INVALID_PARAM_FORMAT",
        "message": "请求参数格式错误",
        "status_code": 400
    }

    JDLX003 = {
        "code": "JDLX003",
        "error_type": "UNAUTHORIZED",
        "message": "认证失败（未提供或无效的Authorization）",
        "status_code": 401
    }

    JDLX004 = {
        "code": "JDLX004",
        "error_type": "INVALID_USER",
        "message": "用户标识未提供或无效",
        "status_code": 403
    }

    JDLX005 = {
        "code": "JDLX005",
        "error_type": "TASK_NOT_FOUND",
        "message": "任务ID不存在或已过期",
        "status_code": 404
    }

    JDLX006 = {
        "code": "JDLX006",
        "error_type": "SERVER_INTERNAL_ERROR",
        "message": "服务端内部错误",
        "status_code": 500
    }

    # 审查结果接口错误码 (SCJG001-SCJG008)
    SCJG001 = {
        "code": "SCJG001",
        "error_type": "INVALID_TYPE",
        "message": "结果类型无效（非'summary'或'issues'）",
        "status_code": 400
    }

    SCJG002 = {
        "code": "SCJG002",
        "error_type": "MISSING_PARAM_ID",
        "message": "callback_task_id缺失",
        "status_code": 400
    }

    SCJG003 = {
        "code": "SCJG003",
        "error_type": "INVALID_ID_FORMAT",
        "message": "callback_task_id格式错误",
        "status_code": 400
    }

    SCJG004 = {
        "code": "SCJG004",
        "error_type": "UNAUTHORIZED",
        "message": "认证失败（未提供或无效的Authorization）",
        "status_code": 401
    }

    SCJG005 = {
        "code": "SCJG005",
        "error_type": "INVALID_USER",
        "message": "用户标识未提供或无效",
        "status_code": 403
    }

    SCJG006 = {
        "code": "SCJG006",
        "error_type": "TASK_NOT_FOUND",
        "message": "callback_task_id不存在或已过期",
        "status_code": 404
    }

    SCJG007 = {
        "code": "SCJG007",
        "error_type": "NO_REVIEW_RESULTS",
        "message": "无审查结果数据",
        "status_code": 404
    }

    SCJG008 = {
        "code": "SCJG008",
        "error_type": "SERVER_ERROR",
        "message": "服务端内部错误（审查结果生成失败）",
        "status_code": 500
    }


def create_http_exception(error_code: Dict[str, Any], custom_message: str = None) -> HTTPException:
    """
    创建HTTP异常

    Args:
        error_code: 错误码字典
        custom_message: 自定义错误消息，可选

    Returns:
        HTTPException: FastAPI异常对象
    """
    detail = {
        "code": error_code["code"],
        "error_type": error_code["error_type"],
        "message": custom_message or error_code["message"]
    }

    return HTTPException(
        status_code=error_code["status_code"],
        detail=detail
    )


def create_server_error(error_code: str, original_error: Exception) -> HTTPException:
    """
    创建服务器内部错误异常

    Args:
        error_code: 错误码 (如 "WJSC008", "JDLX006", "SCJG008")
        original_error: 原始异常

    Returns:
        HTTPException: FastAPI异常对象
    """
    error_map = {
        "WJSC011": ErrorCodes.WJSC011,
        "JDLX006": ErrorCodes.JDLX006,
        "SCJG008": ErrorCodes.SCJG008
    }

    error_config = error_map.get(error_code, ErrorCodes.WJSC008)
    message = f"{error_config['message']}: {str(original_error)}"

    return create_http_exception(error_config, message)


# 便捷的错误创建函数
class FileUploadErrors:
    """文件上传接口错误"""

    @staticmethod
    def file_missing():
        logger.error(ErrorCodes.WJSC001)
        return create_http_exception(ErrorCodes.WJSC001)

    @staticmethod
    def file_multiple():
        logger.error(ErrorCodes.WJSC002)
        return create_http_exception(ErrorCodes.WJSC002)

    @staticmethod
    def file_rejected(message: str = None):
        logger.error(ErrorCodes.WJSC003)
        return create_http_exception(ErrorCodes.WJSC003, message)

    @staticmethod
    def file_format_unsupported():
        logger.error(ErrorCodes.WJSC004)
        return create_http_exception(ErrorCodes.WJSC004)

    @staticmethod
    def file_size_exceeded():
        logger.error(ErrorCodes.WJSC005)
        return create_http_exception(ErrorCodes.WJSC005)

    @staticmethod
    def project_plan_type_invalid():
        logger.error(ErrorCodes.WJSC006)
        return create_http_exception(ErrorCodes.WJSC006)

    @staticmethod
    def unauthorized():
        logger.error(ErrorCodes.WJSC007)
        return create_http_exception(ErrorCodes.WJSC007)
    
    @staticmethod
    def invalid_user():
        logger.error(ErrorCodes.WJSC008)
        return create_http_exception(ErrorCodes.WJSC008)
    
    @staticmethod
    def callback_url_missing():
        logger.error(ErrorCodes.WJSC009)
        return create_http_exception(ErrorCodes.WJSC009)


    @staticmethod
    def task_already_exists():
        logger.error(ErrorCodes.WJSC010)
        return create_http_exception(ErrorCodes.WJSC010)

    
    @staticmethod
    def internal_error(original_error: Exception):
        logger.error(ErrorCodes.WJSC011)
        return create_server_error("WJSC011", original_error)


class TaskProgressErrors:
    """进度查询接口错误"""

    @staticmethod
    def missing_parameters():
        logger.error(ErrorCodes.JDLX001)
        return create_http_exception(ErrorCodes.JDLX001)

    @staticmethod
    def invalid_param_format():
        logger.error(ErrorCodes.JDLX002)
        return create_http_exception(ErrorCodes.JDLX002)

    @staticmethod
    def unauthorized():
        logger.error(ErrorCodes.JDLX003)
        return create_http_exception(ErrorCodes.JDLX003)

    @staticmethod
    def invalid_user():
        logger.error(ErrorCodes.JDLX004)
        return create_http_exception(ErrorCodes.JDLX004)

    @staticmethod
    def task_not_found():
        logger.error(ErrorCodes.JDLX005)
        return create_http_exception(ErrorCodes.JDLX005)

    @staticmethod
    def server_internal_error(original_error: Exception):
        logger.error(ErrorCodes.JDLX006, original_error)
        return create_server_error("JDLX006", original_error)


class ReviewResultsErrors:
    """审查结果接口错误"""

    @staticmethod
    def invalid_type():
        logger.error(ErrorCodes.SCJG001)
        return create_http_exception(ErrorCodes.SCJG001)

    @staticmethod
    def missing_param_id():
        logger.error(ErrorCodes.SCJG002)
        return create_http_exception(ErrorCodes.SCJG002)

    @staticmethod
    def invalid_id_format():
        logger.error(ErrorCodes.SCJG003)
        return create_http_exception(ErrorCodes.SCJG003)

    @staticmethod
    def unauthorized():
        logger.error(ErrorCodes.SCJG004)
        return create_http_exception(ErrorCodes.SCJG004)

    @staticmethod
    def invalid_user():
        logger.error(ErrorCodes.SCJG005)
        return create_http_exception(ErrorCodes.SCJG005)

    @staticmethod
    def task_not_found():
        logger.error(ErrorCodes.SCJG006)
        return create_http_exception(ErrorCodes.SCJG006)

    @staticmethod
    def no_review_results():
        logger.error(ErrorCodes.SCJG007)
        return create_http_exception(ErrorCodes.SCJG007)

    @staticmethod
    def server_error(original_error: Exception):
        logger.error(ErrorCodes.SCJG008)
        return create_server_error("SCJG008", original_error)