package top.baogutang.common.utils;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import top.baogutang.common.domain.PageParam;
import top.baogutang.common.domain.PageUtil;

import java.util.List;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: nikooh
 * @date: 2024/02/22 : 11:21
 */
@Slf4j
public class MyBatisPlusPageUtil {

    private MyBatisPlusPageUtil() {
        // private constructor
    }

    /**
     * general method of paging query
     *
     * @param queryFunction    page query function
     * @param pageParam        page param
     * @param beanCastFunction bean cast function
     * @param <T>              entity class
     * @param <U>              query parameter
     * @param <R>              return bean
     * @return pageUtils
     */
    public static <T, U extends PageParam, R> PageUtil<R> page(UnaryOperator<Page<T>> queryFunction, U pageParam, Function<T, R> beanCastFunction) {
        Page<T> pageReq = new Page<>(pageParam.getPageNum(), pageParam.getPageSize());
        Page<T> pageRes = queryFunction.apply(pageReq);
        List<R> rPageRes = pageRes.getRecords().stream()
                .map(beanCastFunction)
                .collect(Collectors.toList());
        return new PageUtil<>(pageRes.getCurrent(), pageRes.getSize(), pageRes.getTotal(), pageRes.getPages(), rPageRes);
    }

    /**
     * 默认排序
     *
     * @param orders       排序条件
     * @param queryWrapper 查询条件
     * @param <T>          T
     */
    public static <T> void defaultOrders(List<PageParam.OrderBy> orders, QueryWrapper<T> queryWrapper) {
        defaultOrder(orders, queryWrapper, null);
    }

    /**
     * 默认排序,可以指定默认排序字段
     *
     * @param orders            排序条件
     * @param queryWrapper      查询条件
     * @param defaultColumnName 指定默认排序字段列
     * @param <T>               T
     */
    public static <T, R> void defaultOrder(List<PageParam.OrderBy> orders, QueryWrapper<T> queryWrapper, SFunction<T, R> defaultColumnName) {
        if (CollUtil.isEmpty(orders)) {
            defaultOrderProcess(queryWrapper, defaultColumnName);
            return;
        }
        orders.forEach(orderBy -> {
            //默认时间倒序
            if (StringUtils.isEmpty(orderBy.getColumnName())) {
                defaultOrderProcess(queryWrapper, defaultColumnName);
            } else {
                if (orderBy.isDesc()) {
                    queryWrapper.orderByDesc(orderBy.getColumnName());
                } else {
                    queryWrapper.orderByAsc(orderBy.getColumnName());
                }
            }
        });
    }

    /**
     * @param queryWrapper      查询条件
     * @param defaultColumnName 默认排序列名
     * @param <T>               t
     * @param <R>               r
     */
    private static <T, R> void defaultOrderProcess(QueryWrapper<T> queryWrapper, SFunction<T, R> defaultColumnName) {
        if (defaultColumnName != null) {
            queryWrapper.lambda().orderByDesc(defaultColumnName);
        }
    }
}
