package com.wx.application.exception;

import com.baomidou.kaptcha.exception.KaptchaException;
import com.baomidou.kaptcha.exception.KaptchaIncorrectException;
import com.baomidou.kaptcha.exception.KaptchaNotFoundException;
import com.baomidou.kaptcha.exception.KaptchaTimeoutException;
import com.wx.application.base.ErrorCodeEnum;
import com.wx.application.base.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.core.annotation.Order;
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 java.util.Locale;

import static com.wx.application.base.ErrorCodeEnum.PARAM_ERROR;


@ControllerAdvice
@Slf4j
@Order(1)
public class GlobalExceptionHandler {

    @Autowired
    private MessageSource messageSource;

    /**
     * 全局统一异常处理
     */
    @ExceptionHandler(value = {CommonException.class, Exception.class})
    @ResponseBody
    public ResponseData handler(Exception e) {
        // 获取local国际化信息
        Locale locale = LocaleContextHolder.getLocale();
        // 国际化message信息
        String msg = null;
        String errCode = null;
        try {
            errCode = e.getMessage();
            msg = messageSource.getMessage(e.getMessage(), null, locale);
        } catch (NoSuchMessageException ex) {
            errCode = e.getClass().getSimpleName();
            msg = e.getMessage();
        }
        log.error("全局异常捕获: {}", msg, e);
        return ResponseData.ERROR(errCode, msg, null);
    }

    /**
     * 全局统一异常处理
     */
    @ExceptionHandler(value = KaptchaException.class)
    @ResponseBody
    public ResponseData handler(KaptchaException e) {
        // 获取local国际化信息
        Locale locale = LocaleContextHolder.getLocale();
        // 国际化message信息
        String msg = null;
        String errCode = null;
        try {
            if (e instanceof KaptchaIncorrectException) {
                errCode = "KAPTCHA_INCORRECT";
            } else if (e instanceof KaptchaNotFoundException) {
                errCode = "KAPTCHA_NOT_FOUND";
            } else if (e instanceof KaptchaTimeoutException) {
                errCode = "KAPTCHA_TIMEOUT";
            } else {
                errCode = "KAPTCHA_ERROR";
            }
            msg = messageSource.getMessage(errCode, null, locale);
        } catch (NoSuchMessageException ex) {
            errCode = ErrorCodeEnum.SYSTEM_ERROR.toString();
            msg = e.getMessage();
        }
        log.error("全局异常捕获: {}", msg, e);
        return ResponseData.ERROR(errCode, msg, null);
    }

    /**
     * 全局统一异常处理
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseData handler(MethodArgumentNotValidException e) {
        String errorMessage = e.getBindingResult().getAllErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage).reduce((s1, s2) -> s1.concat(",").concat(s2)).get();
        log.error("入参异常捕获: {}", errorMessage, e);
        return ResponseData.ERROR(PARAM_ERROR, errorMessage, null);
    }
}
