package top.awinx.stu01.exception;

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.fasterxml.jackson.core.JsonParseException;

import top.awinx.stu01.common.Result;

/**
 * 全局异常处理器：统一捕获所有接口异常，返回标准Result格式
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 捕获业务异常（如账号密码错误、token无效等）
     */
    @ExceptionHandler(BusinessException.class)
    public Result<Object> handleBusinessException(BusinessException e) {
        return Result.error(e.getCode(), e.getMessage());
    }

    /**
     * 捕获参数校验异常（如@NotBlank、@Pattern触发的异常）
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Object> handleValidException(MethodArgumentNotValidException e) {
        // 获取第一个校验失败的字段提示信息
        String message = e.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
        return Result.error(400, message);
    }


    /**
     * 捕获JSON解析异常（如JSON字段名称不匹配、JSON语法错误等）
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result<Object> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        // 判断是否是JSON解析错误
        Throwable rootCause = e.getRootCause();
        if (rootCause instanceof JsonParseException) {
            return Result.error(400, "JSON格式错误，请检查：字段名需用双引号、括号匹配、无多余逗号/特殊字符");
        } else {
            return Result.error(400, "请求体格式错误，请检查JSON语法");
        }
    }

    /**
     * 捕获数据库约束异常（如非空字段为空、字段长度超出限制等）
     */
    @ExceptionHandler(DataIntegrityViolationException.class)
    public Result<Object> handleDataIntegrityException(DataIntegrityViolationException e) {
        String msg = e.getMessage();
        if (msg.contains("constraint")) {
            if (msg.contains("primary")){
                return Result.error(400, "主键冲突，请检查");
            } else if (msg.contains("unique")) {
                return Result.error(400, "唯一约束冲突，请检查");
            } else {
                return Result.error(400, "数据库约束冲突，请检查");
            }
        } else {
            return Result.error(400, "数据库操作失败，请检查");
        }
    }

    /**
     * 捕获系统异常（兜底处理）
     */
    @ExceptionHandler(Exception.class)
    public Result<Object> handleSystemException(Exception e) {
        // 系统异常返回通用提示（避免暴露敏感信息）
        e.printStackTrace();
        return Result.error(500, "服务器内部错误，请稍后重试");
    }
}
