package com.sy.coinage.config;

import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.ValueFilter;
import com.alibaba.fastjson2.support.config.FastJsonConfig;

import com.sy.coinage.core.argumentresolver.CurrentUserMethodArgumentResolver;
import com.sy.coinage.core.interceptor.TokenVerify;
import com.sy.coinage.core.interceptor.TokenInterceptor;
import com.sy.coinage.core.respconverter.MyMessageConverter;

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Autowired
    private TokenVerify tokenVerify;

    // 配置token验证
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TokenInterceptor(tokenVerify)).addPathPatterns("/**")
                        .excludePathPatterns("/swagger-resources").excludePathPatterns("/swagger-resources/**")
                        .excludePathPatterns("/v2/**");
    }

    // 配置附件下载地址
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/file/**").addResourceLocations("file:upload/file/");
        registry.addResourceHandler("/atta/**").addResourceLocations("file:upload/atta/");
        registry.addResourceHandler("/template/**").addResourceLocations("file:upload/template/");
        registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/favicon.ico").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    // 配置登录用户为请求参数
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new CurrentUserMethodArgumentResolver());
    }

    // 配置支持跨域请求
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // SpringBoot 2.6.x
        registry.addMapping("/**").allowedOriginPatterns("*")
                        .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "OPTIONS", "PATCH")
                        .allowedHeaders("token", "Content-Type", "X-Requested-With", "accept", "Origin",
                                        "Authorization", "Access-Control-Request-Method",
                                        "Access-Control-Request-Headers")
                        .allowCredentials(true).maxAge(3600);
//        registry.addMapping("/**").allowedOriginPatterns("*")
//                .allowedMethods("*")
//                .allowedHeaders("*")
//                .allowCredentials(true).maxAge(3600);
    }



    // 配置响应FastJson序列化
    @Bean
    public MyMessageConverter converter() {
        MyMessageConverter cinverter = new MyMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setWriterFeatures(JSONWriter.Feature.WriteMapNullValue, JSONWriter.Feature.WriteNullStringAsEmpty,
                        JSONWriter.Feature.WriteNullListAsEmpty, JSONWriter.Feature.WriteNullNumberAsZero);
        ValueFilter dateFilter = (Object object, String name, Object value) -> {
            try {
                Field fie = null;
                try {
                    fie = object.getClass().getDeclaredField(name);
                } catch (NoSuchFieldException e) {// 若是在子类找不到，就去父类找，向上找一级，多级继承会报错
                    try {
                        fie = object.getClass().getSuperclass().getDeclaredField(name);
                    } catch (Exception e2) {
                        // TODO: handle exception
                    }
                }
                /**
                 * 实体转JSON字符串时，根据业务需求，对于null的字段不能过滤 但是会在下面判断中报空指针异常(fie为null)，所以修改了下面代码的判断逻辑 值为null的字段返回 ""
                 * zhaojunhao 2020年3月23日16:09:35
                 */
                if (value == null && object != null && fie == null) {
                    return "";
                }
                if (value == null && object != null && Date.class.isAssignableFrom(fie.getType())) {
                    return "";
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return value;
        };
        config.setWriterFilters(dateFilter);
        config.setCharset(Charset.forName("UTF-8"));
        cinverter.setFastJsonConfig(config);
        List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON);
        cinverter.setSupportedMediaTypes(fastMediaTypes);
        cinverter.setDefaultCharset(Charset.forName("UTF-8"));
        return cinverter;
    }

    // 配置自定义响应转换
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(converter());
    }

}
