package com.aiup.service.config.exception;



import com.aiup.service.domain.R;
import com.aiup.service.domain.exception.CommonException;
import com.aiup.service.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
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 org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import sun.misc.IOUtils;
import sun.nio.ch.IOUtil;

import javax.security.auth.login.AccountExpiredException;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;


/**
 * 全局异常处理器
 *
 * @author yiche
 */
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);


    /**
     * 业务异常
     */
    @ExceptionHandler(CommonException.class)
    @ResponseBody
    public R businessException(CommonException e) {
        R result = R.error();
        if (StringUtils.isNotEmpty(e.getMessage())) {
            result.setDescription(e.getMessage());
        }
        if (e.getCode() > 0) {
            result.setErrorCode(String.valueOf(e.getCode()));
        }
        result.setRetValue(e.getEntity());
        return result;
    }

    /**
     * 页面异常，跳转到错误页面
     */
    @ExceptionHandler(PageException.class)
    public String PageException(PageException e) {
        if (e.getPage() != null) {
            return e.getPage();
        }
        return "error";
    }



    @ExceptionHandler(AccountExpiredException.class)
    @ResponseBody
    public R handleAccountExpiredException(AccountExpiredException e) {
        log.warn(e.getMessage(), e);
        return R.error(e.getMessage());
    }

    /**
     * 基础异常
     */
    @ExceptionHandler(BaseException.class)
    @ResponseBody
    public R baseException(BaseException e) {
        log.warn(e.getMessage(), e);
        return R.error(e.getMessage());
    }




    @ExceptionHandler(Exception.class)
    @ResponseBody
//    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R handleException(HttpServletRequest request, Exception e) {
        String params = null;
        String method = request.getMethod();
//        if(method.equalsIgnoreCase("post")){
//            params = getBody(request);
//        }
//        else {
            params = request.getQueryString();
        //}
        String err = String.format("Refer:%s, Url:%s, method:%s,params:%s",
                request.getHeader("referer"),
                request.getRequestURL().toString(),
                method,
                params
        );
        log.error("统一异常捕获信息：" + err, e);
        return R.error("系统异常", "接口异常");
    }

    private String getBody(HttpServletRequest request){
        try {
            BufferedReader reader = request.getReader();
            StringBuilder builder = new StringBuilder();
            String line = reader.readLine();
            while (line != null) {
                builder.append(line);
                line = reader.readLine();
            }
            reader.close();
            String reqBody = builder.toString();
            return reqBody;
        }
        catch (Exception ep){
            logger.error(ep.toString());
        }
        return null ;
    }

    /**
     * 通用的接口映射异常处理方
     */
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
                                                             HttpStatus status, WebRequest request) {
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            return new ResponseEntity<>(R.error(exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), HttpStatus.OK);
        }
        if (ex instanceof MethodArgumentTypeMismatchException) {
            MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
            log.error("参数转换失败，方法：" + exception.getParameter().getMethod().getName() + "，参数：" + exception.getName()
                    + ",信息：" + exception.getLocalizedMessage());
            return new ResponseEntity<>(R.error("参数转换失败,参数：" + exception.getName()), HttpStatus.OK);
        }
        return new ResponseEntity<>(R.error("参数转换失败"), HttpStatus.OK);
    }
}
