package com.ningdatech.kqapi.common.handler;

import com.ningdatech.kqapi.common.exception.BizException;
import com.ningdatech.kqapi.common.model.ApiResponse;
import com.ningdatech.kqapi.common.model.Status;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
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 org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;

/**
 * <p>
 * GlobalExceptionHandler
 * </p>
 *
 * @author WendyYang
 * @since 15:16 2024/4/20
 */
@Slf4j
@ControllerAdvice
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class GlobalExceptionHandler {

    private static void printLog(Exception e) {
        log.error("当前异常为：{}", e.getMessage(), e);
    }

    @ResponseBody
    @ExceptionHandler(value = NoHandlerFoundException.class)
    public ApiResponse<Void> noHandlerFoundException(NoHandlerFoundException e) {
        printLog(e);
        return ApiResponse.ofStatus(Status.REQUEST_NOT_FOUND);
    }

    @ResponseBody
    @ExceptionHandler(value = {MethodArgumentNotValidException.class, BindException.class})
    public ApiResponse<Void> bindException(BindException e) {
        printLog(e);
        String msg = e.getAllErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(","));
        return ApiResponse.of(Status.BAD_REQUEST.getCode(), msg);
    }

    @ResponseBody
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ApiResponse<Void> constraintViolationException(ConstraintViolationException e) {
        printLog(e);
        String msg = e.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(","));
        return ApiResponse.of(Status.BAD_REQUEST.getCode(), msg);
    }

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ApiResponse<Void> handlerException(Exception e) {
        printLog(e);
        return ApiResponse.of(Status.BAD_REQUEST.getCode(), e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = AccessDeniedException.class)
    public ApiResponse<Void> accessDeniedException(AccessDeniedException e) {
        printLog(e);
        return ApiResponse.of(Status.BAD_REQUEST.getCode(), "暂无操作权限");
    }

    @ResponseBody
    @ExceptionHandler(value = BizException.class)
    public ApiResponse<Void> bizException(BizException e) {
        printLog(e);
        return ApiResponse.of(Status.BAD_REQUEST.getCode(), e.getMessage());
    }

}
