
package com.wx.application.base;

import cn.hutool.core.convert.Convert;
import com.google.common.collect.Maps;
import com.wx.application.util.DateUtils;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

/**
 * sql查询构建器
 */
public class SearchFilter {

    public enum Operator {
        EQ,//值相等
        NEQ, //值不等
        LIKE, //值模糊匹配
        GT, //大于
        LT, //小于
        GTE, //大于等于
        LTE,//小于等于
        IN,//在某个范围内
        NIN,//不在某个范围内
        FIELDEQ,//一个字段等于另一个字段
        FIELDNEQ,//一个字段不等于另一个字段
        ISNULL,
        ISNOTNULL,
        ISEMPTY,
        ISNOTEMPTY,
        DESC, // 降序
        DESCA,//多个字段降序
        ASC, // 升序
        ASCA,//多个字段升序
    }

    public enum Logic {
        AND, OR
    }

    /**
     * 模式
     */
    public enum Mod {
        // 条件
        condition,
        // 分组
        group
    }

    /**
     * 属性数据类型.
     */
    public enum PropertyType {
        S(String.class), // 字符串
        I(Integer.class), // 数字
        L(Long.class), // 长整型，一般用作ID查询
        N(Double.class), // 双精度
        D(Date.class), // 日期
        B(Boolean.class), // 布尔类型
        C(BigDecimal.class);

        private Class<?> clazz;

        private PropertyType(Class<?> clazz) {
            this.clazz = clazz;
        }

        public Class<?> getValue() {
            return clazz;
        }
    }

    //字段名称
    public String fieldName;
    //值
    public Object value;
    //eq ue
    public Operator operator;
    //and or
    public Logic logic;

    public SearchFilter(String fieldName, Operator operator, Object value) {
        this.fieldName = fieldName;
        this.value = value;
        this.operator = operator;
    }

    public SearchFilter(String fieldName, Operator operator, Object value, Logic logic) {
        this.fieldName = fieldName;
        this.value = value;
        this.operator = operator;
        this.logic = logic;
    }

    /**
     * 解析下map中的值,挑选符合条件的备用
     * searchParams中key的格式为OPERATOR_FIELDNAME
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static Map<String, SearchFilter> parse(Map<String, Object> searchParams) {
        Map<String, SearchFilter> filters = Maps.newHashMap();

        for (Entry<String, Object> entry : searchParams.entrySet()) {
            // 过滤掉空值
            String key = entry.getKey();
            Object value = entry.getValue();
            if (StringUtils.isBlank(value.toString())) {
                continue;
            }
            // 拆分operator与filedAttribute
            String[] names = StringUtils.split(key, "_");

            if (names.length == 2) {
                String filedName = names[1];
                String firstPart = names[0];
                String matchTypeCode = StringUtils.substring(firstPart, 0, firstPart.length() - 1);
                String propertyTypeCode = StringUtils.substring(firstPart, firstPart.length() - 1, firstPart.length());
                Operator operator = Operator.valueOf(matchTypeCode);
                Class propertyClass = Enum.valueOf(PropertyType.class, propertyTypeCode).getValue();
                
                Object obj = null;
                
                if(operator.equals(Operator.LTE) && propertyTypeCode.equals("D")) {
                	String v = DateUtils.fn1(1, value.toString());
                	obj = Convert.convert(propertyClass, v);
                } else {
                	obj = Convert.convert(propertyClass, value);
                }
                
                // 创建searchFilter
                SearchFilter filter = new SearchFilter(filedName, operator, obj);
                filters.put(key, filter);
            } else if (names.length == 3) {
                String filedName = names[1];
                String firstPart = names[0];
                String logicName = names[2];
                String matchTypeCode = StringUtils.substring(firstPart, 0, firstPart.length() - 1);
                String propertyTypeCode = StringUtils.substring(firstPart, firstPart.length() - 1, firstPart.length());
                Operator operator = Operator.valueOf(matchTypeCode);
                Logic logic = Logic.valueOf(logicName);
                //List<Object> objects = new ArrayList<Object>();
                Class propertyClass = Enum.valueOf(PropertyType.class, propertyTypeCode).getValue();
                Object obj = Convert.convert(propertyClass, value);
                ;
                //String valueString = String.valueOf(value);
                //fixme暂不支持级联
                /*if (valueString.contains("#")) {
                    String[] values = StringUtils.split(valueString, "#");
                    for (String val : values) {
                        Class propertyClass = Enum.valueOf(PropertyType.class, propertyTypeCode).getValue();
                        obj = Convert.convert(propertyClass, value);
                        objects.add(obj);
                    }
                } else {
                    String[] values = StringUtils.split(valueString, "_");
                    for (String val : values) {
                        Class propertyClass = Enum.valueOf(PropertyType.class, propertyTypeCode).getValue();
                        obj = Convert.convert(propertyClass, value);
                        objects.add(obj);
                    }
                }*/
                // 创建searchFilter
                SearchFilter filter = new SearchFilter(filedName, operator, obj, logic);
                filters.put(key, filter);
            }
        }
        return filters;
    }

}
