package org.nl.common.domain.query;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
import lombok.Data;
import org.nl.common.enums.QueryTEnum;
import org.nl.config.MapOf;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.Type;
import java.util.Date;
import java.util.Map;

/*
 * @author ZZQ
 * @Date 2022/12/14 6:33 下午
 * 泛型必须为数据tb对应do:由mybatis管理
 */
@Data
public class BaseQuery<T> {
    /**
     * 模糊查询
     */
    private String blurry;
    /**
     * 是否启用
     */
    private Boolean is_used;
    /**
     * 创建时间范围查询
     */
    private Date start_time;
    private Date end_time;


    /**
     * 字段映射Map:指定字段对应QueryWrapper的查询类型
     *  字段与数据库字段对应，不支持驼峰
     *  @see  org.nl.common.enums.QueryTEnum
     * 通过buid构建
     */
    public Map<String, QParam> doP = MapOf.of("blurry", QParam.builder().k(new String[]{"name"}).type(QueryTEnum.LK).build()
            ,"startTime", QParam.builder().k(new String[]{"create_time"}).type(QueryTEnum.LT).build()
            ,"endTime", QParam.builder().k(new String[]{"create_time"}).type(QueryTEnum.LE).build()
            ,"sort", QParam.builder().k(new String[]{"sort"}).type(QueryTEnum.BY).build()
    );

    public QueryWrapper<T> build(){
        this.paramMapping();
        QueryWrapper<T> wrapper = new QueryWrapper<>();
        JSONObject json = (JSONObject)JSONObject.toJSON(this);
        Type[] types = ((ParameterizedTypeImpl) this.getClass().getGenericSuperclass()).getActualTypeArguments();
        Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap((Class<?>) types[0]);
        json.forEach((key, vel) -> {
            if (vel != null && !key.equals("doP")){
                QParam qParam = doP.get(key);
                if (qParam != null){
                    QueryTEnum.build(qParam.type,wrapper,qParam.k,vel);
                }else {
                    ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(key));
                    if (columnCache!=null){
                        wrapper.eq(columnCache.getColumn(),vel);
                    }
                }
            }
        });
        return wrapper;
    }

    public void paramMapping(){};
}
