package com.zhongshu.card.server.core.handler;

import com.github.microservice.net.ResultContent;
import com.github.microservice.net.ResultException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MissingServletRequestParameterException;
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.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import java.io.IOException;
import java.util.List;

@Slf4j
@RestControllerAdvice
@ResponseBody
public class RestExceptionHandler extends DefaultHandlerExceptionResolver {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public ResultContent<String> exception(Exception exception) {
        String msg = exception.getMessage();
        log.error("绑定异常信息 ex={}", exception.getMessage(), exception);
        return ResultContent.buildFail(msg);
    }

    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.OK)
    public ResultContent<String> bindException(BindException exception) {
        String msg = exception.getMessage();
        try {
            if (exception.getBindingResult() != null) {
                List<ObjectError> list = exception.getBindingResult().getAllErrors();
                if (ObjectUtils.isNotEmpty(list) && list.size() > 0) {
                    ObjectError objectError = list.get(0);
                    if (objectError instanceof FieldError) {
                        FieldError fieldError = (FieldError) objectError;
                        msg = String.format("【%s】 %s", fieldError.getField(), fieldError.getDefaultMessage());
                    } else {
                        msg = String.format("%s", objectError.getDefaultMessage());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.error("绑定异常信息 ex1={}", exception.getMessage(), exception);
        return ResultContent.buildFail(msg);
    }

    protected ModelAndView handleMissingServletRequestParameter(MissingServletRequestParameterException ex,
                                                                HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) throws IOException {

        log.error("missing param exception,uri:{},url:{}", request.getRequestURI(), request.getRequestURL());
        return super.handleMissingServletRequestParameter(ex, request, response, handler);
    }


    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        e.printStackTrace();
        log.error("exception : {}", e);
        ModelAndView mv = new ModelAndView();
        mv.addObject("state", "Fail");
        mv.setView(new MappingJackson2JsonView());
        mv.addObject("exception", ResultException.build(e));
        mv.addObject("msg", e.getMessage());
        return mv;
    }

}
