package com.fjhx.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fjhx.constants.StatusConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.utils.AuthUtil;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class WrapperUtil {

    private Map<String, ?> condition;

    private QueryWrapper<?> wrapper;

    private WrapperUtil() {
    }

    /**
     * 初始化
     */
    public static WrapperUtil init() {
        WrapperUtil wrapperUtil = new WrapperUtil();
        wrapperUtil.wrapper = Wrappers.query();
        wrapperUtil.condition = new HashMap<>();
        return wrapperUtil;
    }

    /**
     * 初始化
     *
     * @param condition 查询条件
     */
    public static WrapperUtil init(Map<String, ?> condition) {
        WrapperUtil wrapperUtil = new WrapperUtil();
        wrapperUtil.wrapper = Wrappers.query();
        wrapperUtil.condition = condition;
        return wrapperUtil;
    }

    /**
     * 初始化
     *
     * @param condition 查询条件
     */
    public static WrapperUtil init(Map<String, ?> condition, QueryWrapper<?> wrapper) {
        WrapperUtil wrapperUtil = new WrapperUtil();
        wrapperUtil.wrapper = wrapper;
        wrapperUtil.condition = condition;
        return wrapperUtil;
    }

    /**
     * 获取wrapper
     */
    public QueryWrapper<?> getWrapper() {
        return wrapper;
    }

    /**
     * 时间段查询
     *
     * @param field 查询字段名
     */
    public WrapperUtil periodOfTime(String field) {
        Object beginTimeObj = condition.get("beginTime");
        Object endTimeObj = condition.get("endTime");
        if (ObjectUtil.isAllNotEmpty(beginTimeObj, endTimeObj)) {
            try {
                DateTime beginTime = DateUtil.beginOfDay(DateUtil.parse(beginTimeObj.toString()));
                DateTime endTime = DateUtil.endOfDay(DateUtil.parse(endTimeObj.toString()));
                wrapper.between(field, beginTime, endTime);
            } catch (Exception e) {
                throw new ServiceException("传入日期格式解析错误");
            }
        }
        return this;
    }

    /**
     * 查询未删除数据
     */
    public WrapperUtil notDelete() {
        wrapper.eq("del_flag", StatusConstant.NOT_DELETED);
        return this;
    }

    /**
     * 查询未删除数据
     *
     * @param prefix 查询字段表前缀
     */
    public WrapperUtil notDelete(String prefix) {
        if (ObjectUtil.isNotEmpty(prefix)) {
            wrapper.eq(prefix + ".del_flag", StatusConstant.NOT_DELETED);
        } else {
            wrapper.eq("del_flag", StatusConstant.NOT_DELETED);
        }
        return this;
    }

    /**
     * 查询未删除数据
     *
     * @param prefix 查询字段表前缀
     */
    public WrapperUtil notDelete(String... prefix) {
        for (String item : prefix) {
            if (ObjectUtil.isNotEmpty(prefix)) {
                wrapper.eq(item + ".del_flag", StatusConstant.NOT_DELETED);
            }
        }
        return this;
    }


    /**
     * 创建时间倒叙排序
     * <p>
     * 雪花算法生成id是顺序id，因此按时间倒叙可以按id排序，效率更高
     * <p/>
     *
     * @param prefix 查询字段表前缀
     */
    public WrapperUtil createTimeDesc(String prefix) {
        if (ObjectUtil.isNotEmpty(prefix)) {
            wrapper.orderByDesc(prefix + ".id");
        } else {
            wrapper.orderByDesc("id");
        }
        return this;
    }

    /**
     * 创建时间倒叙排序
     */
    public WrapperUtil createTimeDesc() {
        createTimeDesc(null);
        return this;
    }

    /**
     * 关键字查询
     *
     * @param fields 查询字段名
     */
    public WrapperUtil keyword(String... fields) {
        Object keyword = condition.get("keyword");
        if (ObjectUtil.isNotEmpty(keyword)) {
            wrapper.and(q -> {
                for (String field : fields) {
                    q.or().like(field, keyword);
                }
            });
        }
        return this;
    }

    /**
     * 相等
     *
     * @param field  查询字段名
     * @param mapKey 搜索条件key
     */
    public WrapperUtil eq(String field, String mapKey) {
        Object value = condition.get(mapKey);
        if (ObjectUtil.isNotEmpty(value)) {
            wrapper.eq(field, value);
        }
        return this;
    }

    /**
     * in查询
     *
     * @param field  查询字段名
     * @param mapKey 搜索条件key
     */
    public WrapperUtil in(String field, String mapKey) {
        Object value = condition.get(mapKey);
        if (ObjectUtil.isNotEmpty(value)) {
            String[] split = value.toString().split(",");
            wrapper.in(field, Arrays.asList(split));
        }
        return this;
    }

    /**
     * 相等（查询条件必填）
     *
     * @param field                  查询字段名
     * @param mapKey                 搜索条件key
     * @param exceptionSpecification 若搜索条件为空抛出的异常提示
     */
    public WrapperUtil eq(String field, String mapKey, String exceptionSpecification) {
        Object value = condition.get(mapKey);
        if (ObjectUtil.isNotEmpty(value)) {
            wrapper.eq(field, value);
        } else {
            throw new ServiceException(exceptionSpecification);
        }
        return this;
    }

    /**
     * like
     *
     * @param field  查询字段名
     * @param mapKey 搜索条件key
     */
    public WrapperUtil like(String field, String mapKey) {
        Object value = condition.get(mapKey);
        if (ObjectUtil.isNotEmpty(value)) {
            wrapper.like(field, value);
        }
        return this;
    }

    /**
     * eq租户id
     *
     * @param field
     * @return
     */
    public WrapperUtil eqTenantId(String field) {
        if (ObjectUtil.isEmpty(field)) {
            wrapper.eq("tenant_id", AuthUtil.getTenantId());
        } else {
            wrapper.eq(field + ".tenant_id", AuthUtil.getTenantId());
        }
        return this;
    }

    /**
     * eq租户id
     *
     * @return
     */
    public WrapperUtil eqTenantId() {
        wrapper.eq("tenant_id", AuthUtil.getTenantId());
        return this;
    }

}
