package com.hys.app.framework.database.mybatisplus.base;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.base.MPJBaseService;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Mybatis Plus IService的拓展
 * 1. {@link IService} 为 MyBatis Plus 的基础接口，提供基础的 CRUD 能力
 * 2. {@link MPJBaseService} 为 MyBatis Plus Join 的基础接口，提供连表 Join 能力
 *
 * @author 张崧
 */
public interface BaseService<T> extends MPJBaseService<T> {

    /**
     * 根据id集合查询
     *
     * @param ids id集合
     * @return 集合
     */
    @Override
    default List<T> listByIds(Collection<? extends Serializable> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return this.getBaseMapper().selectBatchIds(ids);
    }

    /**
     * 根据某个字段in查询，并转为以该字段为key，数据库实体为value的map
     * eg：根据用户编号集合查询出多个用户，返回以用户编号为key，用户实体为value的map
     *
     * @param inValue  查询的字段值
     * @param keyField 查询的字段 & map的key
     * @return Map集合
     */
    default <K> Map<K, T> listAndConvertMap(Collection<?> inValue, SFunction<T, K> keyField) {
        return listAndConvertMap(inValue, keyField, Function.identity());
    }

    /**
     * 根据某个字段in查询，并转为以该字段为key，指定字段为value的map
     * eg：根据用户编号集合查询出多个用户，返回以用户编号为key，用户名为value的map
     *
     * @param inValue    查询的字段值
     * @param keyField   查询的字段 & map的key
     * @param valueField map的value
     * @return Map集合
     */
    default <K, V> Map<K, V> listAndConvertMap(Collection<?> inValue, SFunction<T, K> keyField, Function<T, V> valueField) {
        if (CollUtil.isEmpty(inValue)) {
            return Collections.emptyMap();
        }

        return lambdaQuery()
                .in(keyField, inValue)
                .list()
                .stream()
                .collect(Collectors.toMap(keyField, valueField));
    }

}
