package com.seer.teach.common.exception;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import com.seer.teach.common.ResultBean;
import com.seer.teach.common.enums.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import jakarta.validation.ConstraintViolationException;
import java.io.IOException;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理通用业务异常。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(CommonException.class)
    public ResultBean<?> handleOrderException(CommonException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(e.getResultCode().getCode(), e.getMessage());
    }

    /**
     * 处理微信不在线异常。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(value = WeChatNotOnlineException.class)
    @ResponseBody
    public ResultBean weChatNotOnlineExceptionHandler(WeChatNotOnlineException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(9999, e.getMessage());
    }

    /**
     * 处理请求 LLM 失败异常。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(value = RequestLlmFailException.class)
    @ResponseBody
    public ResultBean requestLlmFailExceptionHandler(RequestLlmFailException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.REQUEST_LLM_FAIL);
    }

    /**
     * 处理未知异常。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultBean exception(Exception e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.INTERNAL_SERVER_ERROR.getCode(), e.getMessage());
    }

    /**
     * 处理微信登录失败异常。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(value = WxLoginException.class)
    @ResponseBody
    public ResultBean WxLoginException(WxLoginException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.WX_LOGIN_FAIL.getCode(), e.getMessage());
    }

    /**
     * 处理文件上传失败异常。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(value = FileUploadException.class)
    @ResponseBody
    public ResultBean handleFileUploadException(FileUploadException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.FILE_UPLOAD_ERROR.getCode(), e.getMessage());
    }

    /**
     * 处理 AI 解析失败异常。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(value = ResourceAccessException.class)
    @ResponseBody
    public ResultBean handlerResourceAccessException(ResourceAccessException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.AI_CORRECT_ERROR);
    }

    /**
     * 处理参数校验失败异常（ConstraintViolationException）。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ResultBean handlerConstraintViolation(ConstraintViolationException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(999, (e.getMessage().substring(e.getMessage().indexOf(":") + 1)));
    }

    /**
     * 处理图片上传失败异常（IOException）。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(IOException.class)
    @ResponseBody
    public ResultBean handlerIoException(ConstraintViolationException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.FILE_UPLOAD_ERROR.getCode(), e.getMessage());
    }

    /**
     * 处理参数绑定校验失败异常（MethodArgumentNotValidException）。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultBean handlerException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(999, (e.getMessage().substring(e.getMessage().lastIndexOf("["), e.getMessage().lastIndexOf("]"))));
    }

    /**
     * 处理文件上传大小超过限制异常。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResultBean handleMaxSizeException(MaxUploadSizeExceededException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.FILE_TOO_LARGE);
    }

    /**
     * 处理文件上传失败异常（MultipartException）。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(MultipartException.class)
    public ResultBean handleMultipartException(MultipartException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.FILE_UPLOAD_ERROR);
    }

    /**
     * 处理未登录异常（NotLoginException）。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(NotLoginException.class)
    @ResponseBody
    public ResultBean handlerNotLoginException(NotLoginException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.PLEASE_LOGIN);
    }

    /**
     * 处理权限不足异常（NotPermissionException）。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(NotPermissionException.class)
    @ResponseBody
    public ResultBean handlerPermissionException(NotPermissionException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(ResultCodeEnum.PERMISSION_DENIED);
    }

    /**
     * 处理自定义数据异常（DataErrorException）。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(DataErrorException.class)
    @ResponseBody
    public ResultBean handlerDataError(DataErrorException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(999, e.getMessage());
    }

    /**
     * 处理运行时异常（RuntimeException）。
     *
     * @param e 异常对象
     * @return 统一响应结果
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public ResultBean handlerRuntimeException(RuntimeException e) {
        log.error(e.getMessage(),e);
        return ResultBean.error(999, e.getMessage());
    }
}

