import logging

from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from starlette.requests import Request

from algo_backend.exception import BasicCommonException, CommonStatusCode

from .common import BasicExceptionInterceptor

logger = logging.getLogger(__name__)


class ValidateExceptionInterceptor(BasicExceptionInterceptor):
    """
    拦截接口关于schema检验的报错，并返回约定的body
    """

    def __init__(self, exc_msg_len=None, **kwargs):
        super().__init__(**kwargs)
        self.exc_msg_len: int = exc_msg_len or 600

    def intercept(self, request: Request, exc: RequestValidationError) -> JSONResponse:
        """
        拦截接口关于schema检验的报错，并返回约定的body
        """

        reqid: str = self.get_request_id(request)
        url: str = self.extract_url(request)

        logger.error(
            f"Reqid: {reqid} | 请求体参数错误: {str(exc)[: self.exc_msg_len]}..."
        )
        if int(request.headers.get("content-length")) == 0 and request.method in (
            "POST",
            "PUT",
            "PATCH",
        ):
            e = BasicCommonException(
                CommonStatusCode.BODY_EMPTY_ERR,
                url=url,
            )
        else:
            reason: str = self.parse_request_validation_error(exc)
            e = BasicCommonException(
                CommonStatusCode.PARAM_ERROR,
                url=url,
                msg=reason,
            )

        vo = self.get_vo_type(url).from_exception(e, request_id=reqid)

        return JSONResponse(
            status_code=200,  # 或其他合适的 HTTP 状态码
            content=vo.model_dump(),  # 将 Pydantic 模型转换为字典
        )

    @staticmethod
    def parse_request_validation_error(exc: RequestValidationError):
        """
        报错润色
        RequestValidationError([{'type': 'string_type', 'loc': ('body', 'messages', 0, 'role'), 'msg': 'Input should be a valid string...[]},
        {'type': 'string_type', 'loc': ('body', 'messages', 0, 'content'), 'msg': 'Input should be a valid string', 'input': []}])
        转换结果如下：
        '请求参数错误，发现2个字段问题：messages[0].role: Input should be a valid string；messages[0].content: Input should be a valid string'
        """
        error_fields = []
        for error in exc.errors():
            loc = error["loc"]
            # 忽略第一个元素（通常是 body）
            field_path = ".".join(
                f"[{i}]" if isinstance(i, int) else i for i in loc[1:]
            ).replace(".[", "[")
            msg = error["msg"]
            error_fields.append(f"{field_path}: {msg}")
        return f"请求参数错误，发现{len(error_fields)}个字段问题：" + "；".join(
            error_fields
        )
