package com.iamberry.wechat.utils;

import com.iamberry.wechat.core.entity.page.PagedResult;
import org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Field;
import java.util.*;

public class StitchAttrUtil {

    /**
     * 组装参数时，会过滤以下参数
     * 推荐使用：addNoPro()，能够暂时过滤，不影响下次使用
     */
    public final static String noProperty[] = {
            "serialVersionUID",
            "page"
    };
    public static Set<String> propertySet = new HashSet<String>(Arrays.asList(noProperty));

    /**
     * 组装ModelAndView
     * @param object
     * @param modelAndView
     * @param url
     * @param pagedResult
     * @throws IllegalAccessException
     */
    public static void setModelAndView(Object object, ModelAndView modelAndView, String url, PagedResult<?> pagedResult) {
        StringBuilder sb = new StringBuilder(url);

        if(pagedResult.getTotal() != 0) {
            pagedResult.setPages((int) Math.ceil((double)pagedResult.getTotal()/pagedResult.getPageSize()));
        }

        sb.append("?pageSize=" + pagedResult.getPageSize());
        sb.append("&totalNum=" + pagedResult.getTotal() );
        StitchAttrUtil.setUrlByObj(sb,object);
        sb.append("&&pageNO=");

        Map<String, Object> map = StitchAttrUtil.getObjToMap(object);
        modelAndView.addAllObjects(map);

        modelAndView.addObject("page", pagedResult);
        modelAndView.addObject("url", sb.toString());

        modelAndView.addObject("pageNO", pagedResult.getPageNO());
        modelAndView.addObject("pageSize", pagedResult.getPages());
        return;
    }

    /**
     * 将obj 转为map，
     * 属性值为null的不会 put 到 Map 中
     * 属性名称在  noProperty 数组中的属性不会 put 到 Map 中
     * @param object
     * @return
     * @throws IllegalAccessException
     */
    public static Map<String, Object> getObjToMap(Object object) {
        Map<String, Object> map = new HashMap<>();
        Class<?> clazz = object.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = null;
            try {
                value = field.get(object);
            }catch (IllegalAccessException e){
            }
            if (value != null && !propertySet.contains(fieldName)) {
                map.put(fieldName, value);
            }
        }
        return map;
    }

    /**
     * 拼接url
     * @param sb
     * @param object
     * @throws IllegalAccessException
     */
    public static void setUrlByObj(StringBuilder sb,Object object){
        Class<?> clazz = object.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = null;
            try {
                value = field.get(object);
            }catch (IllegalAccessException e){
            }
            if (value != null && !propertySet.contains(fieldName)) {
                sb.append("&"+fieldName+ "=" + value.toString());
            }
        }
    }

    /**
     * 添加组装时被过滤的属性名称
     * @param pros
     */
    public static void addNoPro(String...pros){
        for(String pro : pros){
            if(pro != null && !"".equals(pro))
                propertySet.add(pro);
        }
    }

}
