package cn.iocoder.yudao.framework.mybatis.core.mapper;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 在 MyBatis Plus 的 BaseMapper 的基础上拓展，提供更多的能力
 * @author Administrator
 */
public interface AbstractMapper<T> extends BaseMapper<T> {
    /***
     * 分页查询
     * @param vo
     * @param object
     * @return
     */
    default PageResult<T> selectPage(PageVO vo, Object object) {
        return PageResult.empty();
    }

    /***
     * 分页查询
     * @param vo
     * @param queryWrapper
     * @return
     */
    default PageResult<T> selectPage(PageVO vo, @Param("ew") Wrapper<T> queryWrapper) {
        // MyBatis Plus 查询
        IPage<T> mpPage = MyBatisUtils.buildPage(vo);
        selectPage(mpPage, queryWrapper);
        // 转换返回
        return PageResult.of(mpPage);
    }

    /***
     * 分页查询
     * @param pageParam
     * @param queryWrapper
     * @return
     */
    default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
        // MyBatis Plus 查询
        IPage<T> mpPage = MyBatisUtils.buildPage(pageParam);
        selectPage(mpPage, queryWrapper);
        // 转换返回
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal(), mpPage.getSize(), mpPage.getCurrent(), mpPage.getPages());
    }

    /***
     * 根据字段名查询
     * @param field
     * @param value
     * @return
     */
    default T selectOne(String field, Object value) {
        return selectOne(new QueryWrapper<T>().eq(field, value));
    }

    /***
     * 根据字段名查询
     * @param field
     * @param value
     * @return
     */
    default T selectOne(SFunction<T, ?> field, Object value) {
        return selectOne(new LambdaQueryWrapper<T>().eq(field, value));
    }

    /***
     * 根据字段名查询
     * @param field1
     * @param value1
     * @param field2
     * @param value2
     * @return
     */
    default T selectOne(String field1, Object value1, String field2, Object value2) {
        return selectOne(new QueryWrapper<T>().eq(field1, value1).eq(field2, value2));
    }

    /***
     * 根据字段名查询
     * @param field1
     * @param value1
     * @param field2
     * @param value2
     * @return
     */
    default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
        return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
    }

    default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2, SFunction<T, ?> field3, Object value3) {
        return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
    }

    /***
     * 查询记录数
     * @return
     */
    default Long selectCount() {
        return selectCount(new QueryWrapper<T>());
    }


    /***
     * 查询记录数
     * @param field
     * @param value
     * @return
     */
    default Long selectCount(String field, Object value) {
        return selectCount(new QueryWrapper<T>().eq(field, value));
    }

    /***
     * 查询记录数
     * @param field
     * @param value
     * @return
     */
    default Long selectCount(SFunction<T, ?> field, Object value) {
        return selectCount(new LambdaQueryWrapper<T>().eq(field, value));
    }

    /***
     * 查询列表
     * @return
     */
    default List<T> selectList() {
        return selectList(new QueryWrapper<>());
    }

    /***
     * 查询列表
     * @param object
     * @return
     */
    default List<T> selectList(Object object) {
        return Collections.EMPTY_LIST;
    }

    /***
     * 查询列表
     * @param field
     * @param value
     * @return
     */
    default List<T> selectList(String field, Object value) {
        return selectList(new QueryWrapper<T>().eq(field, value));
    }

    /***
     * 查询列表
     * @param field
     * @param value
     * @return
     */
    default List<T> selectList(SFunction<T, ?> field, Object value) {
        return selectList(new LambdaQueryWrapper<T>().eq(field, value));
    }

    /****
     * 查询列表
     * @param field
     * @param values
     * @return
     */
    default List<T> selectList(String field, Collection<?> values) {
        return selectList(new QueryWrapper<T>().in(field, values));
    }

    /***
     * 查询列表
     * @param field
     * @param values
     * @return
     */
    default List<T> selectList(SFunction<T, ?> field, Collection<?> values) {
        return selectList(new LambdaQueryWrapper<T>().in(field, values));
    }

    /***
     * 批量插入
     * @param entities
     */
    default void insertBatch(Collection<T> entities) {
        // TODO 芋艿：修改成支持批量的
        entities.forEach(this::insert);
    }

    /***
     * 批量更新
     * @param update
     */
    default void updateBatch(T update) {
        update(update, new QueryWrapper<>());
    }

    /***
     * 批量更新
     * @param entities
     */
    default void updateBatch(Collection<T> entities) {
        entities.forEach(this::updateById);
    }
}
