package com.fdkankan.common.exception;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.ServerCode;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.response.ResultData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 全局异常处理器
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 处理未知异常
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResultData exceptionHandler(HttpServletRequest httpServletRequest, Exception e) {
        log.error("服务错误:", e);
        return ResultData.error(ServerCode.SYSTEM_ERROR.code(), ExceptionUtil.stacktraceToString(e, 3000));
    }

    /**
     * 校验错误拦截处理
     */
    @ResponseBody
    @ExceptionHandler({BindException.class,MethodArgumentNotValidException.class})
    public ResultData validationBodyException(Exception exception) {
        BindingResult result = null;
        if(exception instanceof MethodArgumentNotValidException){
            result = ((MethodArgumentNotValidException) exception).getBindingResult();
        }
        if(exception instanceof BindException){
            result = ((BindException) exception).getBindingResult();
        }
        String message = "";
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            if (errors != null) {
                errors.forEach(p -> {
                    FieldError fieldError = (FieldError) p;
                    log.error("参数校验错误：类:{},字段：{},错误信息：{}",fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
                });
                if (errors.size() > 0) {
                    FieldError fieldError = (FieldError) errors.get(0);
                    message = fieldError.getDefaultMessage();
                }
            }
        }
        return ResultData.error(ErrorCode.PARAM_FORMAT_ERROR.code(), message);
    }


    /**
     * 处理业务异常
     */
    @ResponseBody
    @ExceptionHandler(value = BusinessException.class)
    public ResultData businessExceptionHandler(HttpServletRequest httpServletRequest, BusinessException e) {
        log.info("业务异常code:" + e.getCode() + "msg:" + e.getMessage());
        return ResultData.error(e.getCode(), e.getMessage());
    }
}
