package {{ .package }}.common.response;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.method.annotation.MapMethodProcessor;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ViewNameMethodReturnValueHandler;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Configuration
@ComponentScan("com.vs.ox")
public class WebMvcConfiguration implements WebMvcConfigurer, ApplicationContextAware {
    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
    private ApplicationContext applicationContext;

    // 删除 init 方法，在 setRequestMappingHandlerAdapter 中调用
    private void init() {
        List<HandlerMethodReturnValueHandler> returnValueHandlers =
                this.requestMappingHandlerAdapter.getReturnValueHandlers();
        if (returnValueHandlers == null) {
            return; // 避免空指针异常
        }
        Iterator<HandlerMethodReturnValueHandler> iterator = returnValueHandlers.iterator();
        List<HandlerMethodReturnValueHandler> newProcessors = new ArrayList<>();
        while (iterator.hasNext()) {
            HandlerMethodReturnValueHandler next = iterator.next();
            // 为了能在controller中直接返回map，不被默认的MapMethodProcessor拦截
            if (next instanceof MapMethodProcessor
                    ||
                    // 为了能在controller中直接返回String，不被默认的ViewNameMethodReturnValueHandler拦截
                    next instanceof ViewNameMethodReturnValueHandler) {
                continue;
            } else {
                newProcessors.add(next);
            }
        }
        this.requestMappingHandlerAdapter.setReturnValueHandlers(newProcessors);
    }

    // 使用 configureHandlerExceptionResolvers 方法
    @Override
    public void configureHandlerExceptionResolvers(
            List<HandlerExceptionResolver> exceptionResolvers) {
        ResponseJsonExceptionResolver responseJsonExceptionResolver =
                new ResponseJsonExceptionResolver();
        try {
            responseJsonExceptionResolver.afterPropertiesSet();
        } catch (Exception e) {
            e.printStackTrace();
        }
        exceptionResolvers.add(responseJsonExceptionResolver);
    }

    // 使用 addReturnValueHandlers 方法
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
        ResponseJsonMethodReturnValueHandler responseJsonMethodReturnValueHandler =
                new ResponseJsonMethodReturnValueHandler();
        responseJsonMethodReturnValueHandler.afterPropertiesSet();
        returnValueHandlers.add(responseJsonMethodReturnValueHandler);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Autowired private Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder;

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        ObjectMapper mapper = jackson2ObjectMapperBuilder.build();
        DateFormat dateFormat = mapper.getDateFormat();
        mapper.setDateFormat(new MyDateFormat(dateFormat));
        MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter =
                new MappingJackson2HttpMessageConverter(mapper);
        return mappingJsonpHttpMessageConverter;
    }

    // 删除 ServletContextListener，使用 ApplicationListener 或 BeanPostProcessor
    // 或者直接注入 RequestMappingHandlerAdapter
    @Autowired
    public void setRequestMappingHandlerAdapter(
            RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
        this.requestMappingHandlerAdapter = requestMappingHandlerAdapter;
        init(); // 在这里调用 init 方法
    }
}
