package cn.axzo.workflow.core.repository.mapper;

import cn.axzo.workflow.common.model.request.BpmPageParam;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.core.common.utils.BpmnMyBatisUtils;
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.List;

public interface BaseMapperX<T> extends BaseMapper<T> {
    default BpmPageResult<T> selectPage(BpmPageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
        IPage<T> mpPage = BpmnMyBatisUtils.buildPage(pageParam);
        this.selectPage(mpPage, queryWrapper);
        return new BpmPageResult(mpPage.getRecords(), mpPage.getTotal());
    }

    default T selectOne(String field, Object value) {
        return (T) this.selectOne((Wrapper)(new QueryWrapper()).eq(field, value));
    }

    default T selectOne(SFunction<T, ?> field, Object value) {
        return (T) this.selectOne((Wrapper)(new LambdaQueryWrapper()).eq(field, value));
    }

    default T selectOne(String field1, Object value1, String field2, Object value2) {
        return (T) this.selectOne((Wrapper)((QueryWrapper)(new QueryWrapper()).eq(field1, value1)).eq(field2, value2));
    }

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

    default Long selectCount() {
        return Long.valueOf(this.selectCount(new QueryWrapper()));
    }

    default Long selectCount(String field, Object value) {
        return Long.valueOf(this.selectCount((Wrapper)(new QueryWrapper()).eq(field, value)));
    }

    default Long selectCount(SFunction<T, ?> field, Object value) {
        return Long.valueOf(this.selectCount((Wrapper)(new LambdaQueryWrapper()).eq(field, value)));
    }

    default List<T> selectList() {
        return this.selectList(new QueryWrapper());
    }

    default List<T> selectList(String field, Object value) {
        return this.selectList((Wrapper)(new QueryWrapper()).eq(field, value));
    }

    default List<T> selectList(SFunction<T, ?> field, Object value) {
        return this.selectList((Wrapper)(new LambdaQueryWrapper()).eq(field, value));
    }

    default List<T> selectList(String field, Collection<?> values) {
        return this.selectList((Wrapper)(new QueryWrapper()).in(field, values));
    }

    default List<T> selectList(SFunction<T, ?> field, Collection<?> values) {
        return this.selectList((Wrapper)(new LambdaQueryWrapper()).in(field, values));
    }

    default void insertBatch(Collection<T> entities) {
        entities.forEach(this::insert);
    }

    default void updateBatch(T update) {
        this.update(update, new QueryWrapper());
    }
}
