package cn.reghao.tnb.common.exception;

import cn.reghao.jutil.jdk.exception.ExceptionUtil;
import cn.reghao.tnb.common.web.WebResult;
import cn.reghao.tnb.common.auth.AuthException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.rpc.RpcException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
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 jakarta.servlet.http.HttpServletRequest;
import java.util.stream.Collectors;

/**
 * 全局异常处理类，处理 controller 抛出的异常
 *
 * @author reghao
 * @date 2019/03/21 10:25:49
 */
@Slf4j
@ControllerAdvice
public class ControllerExceptionHandler {
    /**
     * 处理所有 controller 上抛出的异常
     *
     * @date 2019-09-28 上午11:01
     */
    @ExceptionHandler({Exception.class})
    @ResponseBody
    public ResponseEntity<String> error(Exception e, HttpServletRequest request) {
        String uri = request.getRequestURI();
        String msg;
        if (e instanceof NullPointerException) {
            msg = ExceptionUtil.stackTrace(e);
        } else if (e instanceof RpcException) {
            log.error("RPC exception: {}", e.getMessage());
            msg = e.getMessage();
        } else {
            msg = ExceptionUtil.errorMsg(e);
        }
        log.error("{} 接口抛出异常: {}", uri, msg);

        String body = WebResult.errorWithMsg(msg);
        int status = HttpStatus.OK.value();
        //int status = HttpStatus.INTERNAL_SERVER_ERROR.value();
        if (e instanceof MethodArgumentNotValidException) {
            // 参数校验失败
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e;
            String errMsg = exception.getBindingResult().getAllErrors().stream()
                    .map(objectError -> {
                        String message = objectError.getDefaultMessage();
                        return message + "\n";
                    }).collect(Collectors.joining());
            body = WebResult.errorWithMsg(errMsg);
            /*body = exception.getBindingResult().getAllErrors().stream()
                    .map(DefaultMessageSourceResolvable::getDefaultMessage)
                    .collect(Collectors.joining());*/
        } else if (e instanceof IllegalStateException) {
            IllegalStateException exception = (IllegalStateException) e;
            Throwable throwable = exception.getCause();
            if (throwable instanceof AuthException) {
                status = HttpStatus.UNAUTHORIZED.value();
            }

            body = WebResult.errorWithMsg(throwable.getMessage());
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return ResponseEntity.status(status).headers(headers).body(body);
    }
}
