package com.xxx.base.springframework.core.web.exception;


import com.xxx.base.springframework.constant.vo.ErrorResponseData;
import com.xxx.base.springframework.constant.vo.ResponseData;
import com.xxx.base.springframework.core.web.exception.enums.CoreExceptionEnum;
import com.xxx.base.springframework.util.MessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

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


@RestControllerAdvice
@Slf4j
public class DefaultExceptionHandler {

    /**
     * 拦截各个服务的具体异常
     */
    @ExceptionHandler(ApiServiceException.class)
    @ResponseStatus(HttpStatus.OK)
    public ResponseData apiService(ApiServiceException e) {
        log.error("服务具体异常:", e);
        ErrorResponseData errorResponseData = new ErrorResponseData(e.getCode(), e.getErrorMessage());
        return errorResponseData;
    }

    /**
     * 拦截业务异常
     */
    @ExceptionHandler(ServiceException.class)
    @ResponseStatus(HttpStatus.OK)
    public ResponseData notFount(ServiceException e) {
        if (e.getCode() != 501 && e.getCode() != 502) {
            log.info("业务异常:", e);
        }
        return new ErrorResponseData(e.getCode(), e.getErrorMessage());
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public ResponseData serverError(Exception e) {
        log.error("运行时异常:", e);
        return new ErrorResponseData(CoreExceptionEnum.SERVICE_ERROR.getCode(), MessageUtil.get("SERVER_ERROR"));
    }


    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    public ResponseData parameterException(Exception e, HttpServletRequest request) {
        log.error("参数错误,url=" + request.getRequestURI(), e);
        return new ErrorResponseData(CoreExceptionEnum.PARAM_ERROR.getCode(), MessageUtil.get("PARAM_ERROR"));
    }

    /**
     * 用来处理bean validation异常
     *
     * @param ex
     * @return
     */
//    @ExceptionHandler(ConstraintViolationException.class)
//    @ResponseBody
//    public ResponseData resolveConstraintViolationException(ConstraintViolationException ex) {
//        ex.printStackTrace();
//        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
//        if (constraintViolations.size() > 0) {
//            StringBuilder msgBuilder = new StringBuilder();
//            for (ConstraintViolation constraintViolation : constraintViolations) {
//                msgBuilder.append(constraintViolation.getMessage()).append(",");
//            }
//            String errorMessage = msgBuilder.toString();
//            if (errorMessage.length() > 1) {
//                errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
//            }
//            return ResponseData.error(MessageUtil.get(errorMessage));
//        }
//        return ResponseData.error(MessageUtil.get(ex.getMessage()));
//    }
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseData resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        ex.printStackTrace();
        List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
        if (objectErrors.size() > 0) {
            StringBuilder msgBuilder = new StringBuilder();
            for (ObjectError objectError : objectErrors) {
                msgBuilder.append(objectError.getDefaultMessage()).append(",");
            }
            String errorMessage = msgBuilder.toString();
            if (errorMessage.length() > 1) {
                errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
            }
            return ResponseData.error(MessageUtil.get(errorMessage));
        }
        return ResponseData.error(MessageUtil.get(ex.getMessage()));
    }
}
