# -*- coding: utf-8 -*-

from typing import Any
from fastapi import FastAPI, Request, status
from fastapi.exceptions import RequestValidationError, ResponseValidationError
from pydantic_validation_decorator import FieldValidationError
from starlette.responses import JSONResponse
from starlette.exceptions import HTTPException
from sqlalchemy.exc import SQLAlchemyError

from app.common.constant import RET
from app.common.response import ErrorResponse
from app.core.logger import log


class CustomException(Exception):
    """
    自定义异常基类
    """

    def __init__(
        self,
        msg: str = RET.EXCEPTION.msg,
        code: int = RET.EXCEPTION.code,
        status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR,
        data: Any | None = None,
        success: bool = False
    ) -> None:
        """
        初始化异常对象。
        
        参数:
        - msg (str): 错误消息。
        - code (int): 业务状态码。
        - status_code (int): HTTP 状态码。
        - data (Any | None): 附加数据。
        - success (bool): 是否成功标记，默认 False。
        
        返回:
        - None
        """
        super().__init__(msg)  # 调用父类初始化方法
        self.status_code = status_code
        self.code = code
        self.msg = msg
        self.data = data
        self.success = success

    def __str__(self) -> str:
        """返回异常消息
        
        返回:
        - str: 异常消息
        """
        return self.msg


def handle_exception(app: FastAPI):
    """
    注册全局异常处理器。
    
    参数:
    - app (FastAPI): 应用实例。
    
    返回:
    - None
    """
    @app.exception_handler(CustomException)
    async def CustomExceptionHandler(request: Request, exc: CustomException) -> JSONResponse:
        """
        自定义异常处理器
        
        参数:
        - request (Request): 请求对象。
        - exc (CustomException): 自定义异常实例。
        
        返回:
        - JSONResponse: 包含错误信息的 JSON 响应。
        """
        log.error(f"[自定义异常] {request.method} {request.url.path} | 错误码: {exc.code} | 错误信息: {exc.msg} | 详情: {exc.data}")
        return ErrorResponse(msg=exc.msg, code=exc.code, status_code=exc.status_code, data=exc.data)

    @app.exception_handler(HTTPException)
    async def HttpExceptionHandler(request: Request, exc: HTTPException) -> JSONResponse:
        """
        HTTP异常处理器
        
        参数:
        - request (Request): 请求对象。
        - exc (HTTPException): HTTP异常实例。
        
        返回:
        - JSONResponse: 包含错误信息的 JSON 响应。
        """
        log.error(f"[HTTP异常] {request.method} {request.url.path} | 状态码: {exc.status_code} | 错误信息: {exc.detail}")
        return ErrorResponse(msg=exc.detail, status_code=exc.status_code)

    @app.exception_handler(RequestValidationError)
    async def ValidationExceptionHandler(request: Request, exc: RequestValidationError) -> JSONResponse:
        """
        请求参数验证异常处理器
        
        参数:
        - request (Request): 请求对象。
        - exc (RequestValidationError): 请求参数验证异常实例。
        
        返回:
        - JSONResponse: 包含错误信息的 JSON 响应。
        """
        error_mapping = {
            "Field required": "请求失败，缺少必填项！",
            "value is not a valid list": "类型错误，提交参数应该为列表！", 
            "value is not a valid int": "类型错误，提交参数应该为整数！",
            "value could not be parsed to a boolean": "类型错误，提交参数应该为布尔值！",
            "Input should be a valid list": "类型错误，输入应该是一个有效的列表！"
        }
        raw_msg = exc.errors()[0].get('msg')
        msg = error_mapping.get(raw_msg, raw_msg)
        # 去掉Pydantic默认的前缀“Value error”, 仅保留具体提示内容
        if isinstance(msg, str) and msg.startswith("Value error"):
            if "," in msg:
                msg = msg.split(",", 1)[1].strip()
            else:
                msg = msg.replace("Value error", "").strip()
        log.error(f"[参数验证异常] {request.method} {request.url.path} | 错误信息: {msg} | 原始错误: {exc.errors()}")
        return ErrorResponse(msg=str(msg), status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, data=exc.body)

    @app.exception_handler(ResponseValidationError)
    async def ResponseValidationHandle(request: Request, exc: ResponseValidationError) -> JSONResponse:
        """
        响应参数验证异常处理器
        
        参数:
        - request (Request): 请求对象。
        - exc (ResponseValidationError): 响应参数验证异常实例。
        
        返回:
        - JSONResponse: 包含错误信息的 JSON 响应。
        """
        log.error(f"[响应验证异常] {request.method} {request.url.path} | 错误信息: 响应数据格式错误 | 详情: {exc.errors()}")
        return ErrorResponse(msg="服务器响应格式错误", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, data=exc.body)

    @app.exception_handler(SQLAlchemyError)
    async def SQLAlchemyExceptionHandler(request: Request, exc: SQLAlchemyError) -> JSONResponse:
        """
        数据库异常处理器
        
        参数:
        - request (Request): 请求对象。
        - exc (SQLAlchemyError): 数据库异常实例。
        
        返回:
        - JSONResponse: 包含错误信息的 JSON 响应。
        """
        error_msg = '数据库操作失败'
        exc_type = type(exc).__name__
        
        # 对于生产环境，返回通用错误消息
        log.error(f"[数据库异常] {request.method} {request.url.path} | 错误类型: {exc_type} | 错误详情: {str(exc)}")
        return ErrorResponse(msg=f'{error_msg}: {exc_type}', status_code=status.HTTP_400_BAD_REQUEST, data=str(exc))

    @app.exception_handler(ValueError)
    async def ValueExceptionHandler(request: Request, exc: ValueError) -> JSONResponse:
        """
        值异常处理器
        
        参数:
        - request (Request): 请求对象。
        - exc (ValueError): 值异常实例。
        
        返回:
        - JSONResponse: 包含错误信息的 JSON 响应。
        """
        log.error(f"[值异常] {request.method} {request.url.path} | 错误信息: {str(exc)}")
        return ErrorResponse(msg=str(exc), status_code=status.HTTP_400_BAD_REQUEST)

    @app.exception_handler(FieldValidationError)
    async def FieldValidationExceptionHandler(request: Request, exc: FieldValidationError) -> JSONResponse:
        """
        字段验证异常处理器
        
        参数:
        - request (Request): 请求对象。
        - exc (FieldValidationError): 字段验证异常实例。
        
        返回:
        - JSONResponse: 包含错误信息的 JSON 响应。
        """
        log.error(f"[字段验证异常] {request.method} {request.url.path} | 错误信息: {exc.message}")
        return ErrorResponse(msg=exc.message, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)

    @app.exception_handler(Exception)
    async def AllExceptionHandler(request: Request, exc: Exception) -> JSONResponse:
        """
        全局异常处理器
        
        参数:
        - request (Request): 请求对象。
        - exc (Exception): 异常实例。
        
        返回:
        - JSONResponse: 包含错误信息的 JSON 响应。
        """
        exc_type = type(exc).__name__
        log.error(f"[未捕获异常] {request.method} {request.url.path} | 错误类型: {exc_type} | 错误详情: {str(exc)}")
        # 对于未捕获的异常，返回通用错误信息
        return ErrorResponse(msg='服务器内部错误', status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, data=None)
