package com.app.exception;

import com.app.dto.Result;
import com.app.feign.dto.BotMsg;
import com.app.feign.dto.MarkdownMsg;
import com.app.service.WeChatWorkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
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.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

/**
 * 功能描述：
 * todo
 *
 * @Auther: 梁展鹏
 * @Date: 2018/7/24 11:38
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionController {

    @Autowired
    private WeChatWorkService weChatWorkService;

    @ExceptionHandler(BusinessException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<Result> handleBusinessException(BusinessException businessException) {
        return new ResponseEntity(new Result().serverError(businessException.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /**
     * 功能描述：参数合法性校验异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Result> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        return new ResponseEntity(new Result().serverError(e.getBindingResult().getFieldError().getDefaultMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    protected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        StringBuilder sb = new StringBuilder();
        if (ex.hasErrors()) {
            List<FieldError> list = ex.getFieldErrors();
            for (FieldError fieldError : list) {
                sb.append(fieldError.getField())
                        .append("=[")
                        .append(fieldError.getRejectedValue())
                        .append("]")
                        .append(fieldError.getDefaultMessage())
                        .append(",");
            }
        } else {
            sb.append(ex.getMessage());
        }

        /* 生成返回结果 */
        return new ResponseEntity<>(new Result().serverError(sb.toString()), HttpStatus.BAD_REQUEST);
    }

    /**
     * 功能描述：找不到资源(未找到处理器异常)
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<Result> noHandlerFoundExceptionHander(Exception exception) {
        return new ResponseEntity<>(new Result().serverError("接口不存在"), HttpStatus.NOT_FOUND);
    }
//
//    /**
//     * 功能描述：权限不足
//     *
//     * @param exception
//     * @return
//     */
//    @ExceptionHandler(AccessDeniedException.class)
//    public ResponseEntity<Result> accessDeniedExceptionHander(Exception exception) {
//        return new ResponseEntity<>(new Result().serverError("拒绝访问"), HttpStatus.FORBIDDEN);
//    }
//
//    /**
//     * 功能描述：请求方式错误
//     *
//     * @param exception
//     * @return
//     */
//    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
//    public ResponseEntity<Result> httpRequestMethodNotSupportedExceptionHandler(Exception exception) {
//        return new ResponseEntity<>(new Result().serverError("请求方式错误"), HttpStatus.BAD_REQUEST);
//    }
//

    /**
     * 功能描述：controller参数异常/缺少
     *
     * @param exception
     * @return
     */
    @ExceptionHandler({
            MissingServletRequestParameterException.class,
            MethodArgumentTypeMismatchException.class,
//            RequestRejectedException.class
    })
    public ResponseEntity<Result> missingServletRequestParameterException(Exception exception) {
        return new ResponseEntity<>(new Result().serverError("参数异常"), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Result> handleException(Exception e) {
        StringWriter stringWriter = new StringWriter();
        e.printStackTrace(new PrintWriter(stringWriter));
        BotMsg botMsg = new BotMsg(new MarkdownMsg().setContent(stringWriter.toString().substring(0, 4096)));
        weChatWorkService.sendGlobalExceptionRobot(botMsg);

        log.error(e.getMessage(), e); // 系统繁忙,请稍后再试
        return new ResponseEntity(new Result().serverError(e.getMessage()), HttpStatus.SERVICE_UNAVAILABLE);
    }

//    /**
//     * 功能描述：单次上传文件过大
//     *
//     * @param exception
//     * @return
//     */
//    @ExceptionHandler(MaxUploadSizeExceededException.class)
//    public ResponseEntity<Result> maxUploadSizeExceededException(Exception exception) {
//        return new ResponseEntity<>(new Result().serverError("文件过大"), HttpStatus.INTERNAL_SERVER_ERROR);
//    }
//
//    /**
//     * 功能描述：抛出错误前，打印错误日志
//     *
//     * @param exception
//     * @return
//     */
//    @ExceptionHandler(Exception.class)
//    @ResponseStatus(HttpStatus.BAD_REQUEST)
//    public ResponseEntity<Result> exceptionHander(Exception exception) {
//        log.error(exception.getMessage(), exception);
//
//        if (exception instanceof org.springframework.web.servlet.NoHandlerFoundException) {
//            return new ResponseEntity<>(new Result().serverError(exception.getMessage()), HttpStatus.NOT_FOUND);
//        } else {
//            return new ResponseEntity<>(new Result().serverError(exception.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
//        }
//
//        return new ResponseEntity<Result>(new Result().serverError("服务异常, 请联系客服"), HttpStatus.INTERNAL_SERVER_ERROR);
//    }
//
//    /**
//     * 功能描述：捕捉控制器里面自己抛出的所有异常
//     *
//     * @param request
//     * @param ex
//     * @return
//     */
//    @ResponseStatus(HttpStatus.BAD_REQUEST)
//    public ResponseEntity<Result> globalException(HttpServletRequest request, Throwable ex) {
//        log.error(ex.getMessage(), ex);
//        return new ResponseEntity<>(new Result().serverError(ex.getMessage(), null), getStatus(request));
//    }
//
//    private HttpStatus getStatus(HttpServletRequest request) {
//        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
//        if (statusCode == null) {
//            return HttpStatus.INTERNAL_SERVER_ERROR;
//        }
//
//        return HttpStatus.valueOf(statusCode);
//    }

}
