package com.app.framework.core.support.service.impl;

import com.app.framework.core.support.mapper.CrudBaseMapper;
import com.app.framework.core.support.service.CrudBaseService;
import com.app.framework.core.support.view.grid.Paging;
import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.Map;

import static com.baomidou.mybatisplus.core.enums.SqlKeyword.*;

/**
 * Service实现类的基类
 *
 * @param <M>
 * @param <T>
 */
public class CrudBaseServiceSupport<M extends CrudBaseMapper<T>, T> extends ServiceImpl<M, T> implements CrudBaseService<T> {

    /**
     * 设置排序
     *
     * @param wrapper
     * @param paging
     */
    private void setOrderBy(Wrapper<T> wrapper, Paging paging) {
        if (wrapper == null || paging == null || StringUtils.isBlank(paging.getSort())) {
            return;
        }
        wrapper.getExpression().getOrderBy().clear();
        Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(entityClass);

        String sorts[] = paging.getSort().split(",");
        String dirs[] = null;
        if (StringUtils.isNotBlank(paging.getDir())) {
            dirs = paging.getDir().split(",");
        }
        for (int i = 0; i < sorts.length; i++) {
            String column = sorts[i], dir = "ASC";
            if (dirs != null && dirs.length > i) {
                dir = dirs[i].toUpperCase();
            }

            ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(column));
            if (columnCache == null) {
                columnCache = columnMap.values().stream().filter(e -> e.getColumn().equals(column)).findFirst().get();
            }
            if (columnCache == null) {
                throw new RuntimeException("数据库中找不到 " + column + " 映射字段");
            }
            String sqlColumn = columnCache.getColumn();
            ISqlSegment[] sqlSegments = {ORDER_BY, () -> sqlColumn, "DESC".equals(dir) ? DESC : ASC};
            wrapper.getExpression().add(sqlSegments);
        }
    }

    /**
     * 分页查询
     * @param wrapper 查询条件
     * @param paging 分页条件
     * @return
     */
    public List<T> pageList(Wrapper<T> wrapper, Paging paging) {
        this.setOrderBy(wrapper, paging);

        if (Paging.isPage(paging)) {
            Page<T> page = new Page<>(paging.getPageNo(), paging.getLimit(), paging.getIsCountPage());
            Page<T> result = this.page(page, wrapper);
            Paging.setPage(paging, result);
            return result.getRecords();
        }
        return this.list(wrapper);
    }

}
