package com.ai.da.common.config.mybatis.plus;

import cn.hutool.core.collection.CollUtil;
import com.ai.da.common.response.PageResponse;
import com.ai.da.common.response.Response;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

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


public class CommonServiceImpl<M extends CommonMapper<T>, T, E> extends ServiceImpl<M, T> {

    public PageResponse<E> voPage(QueryCriteria<T, E> criteria) {
        IPage<T> tPage = baseMapper.voPage(new Page<>(criteria.getPage(), criteria.getLimit()), criteria.buildWrapper());
        if (criteria.getMapper() != null && tPage != null && CollUtil.isNotEmpty(tPage.getRecords())) {
            List<E> convert = convert(tPage, criteria.getMapper(), criteria);
            Response<List<E>> response = Response.success(convert);
            PageResponse<E> pageResponse = new PageResponse<>(response, tPage.getCurrent(), tPage.getSize(), tPage.getTotal(), tPage.getPages());
            if (criteria.getPeekAllAfter() != null) {
                Consumer<List<E>> peekAllAfter = criteria.getPeekAllAfter();
                peekAllAfter.accept(pageResponse.getData());
            }
            return pageResponse;
        }
        PageResponse<E> pageResponse = new PageResponse<>(null, criteria.getPage(), criteria.getLimit(), 0, 0);
        if (criteria.getPeekAllAfter() != null) {
            Consumer<List<E>> peekAllAfter = criteria.getPeekAllAfter();
            peekAllAfter.accept(pageResponse.getData());
        }
        return pageResponse;
    }

    List<E> convert(IPage<T> page, Function<? super T, E> mapper, QueryCriteria<T, E> criteria) {
        if (criteria.getPeekBefore() != null && criteria.getPeekAfter() != null) {
            return page.getRecords().stream().peek(criteria.getPeekBefore()).map(mapper).peek(criteria.getPeekAfter()).collect(Collectors.toList());
        } else if (criteria.getPeekBefore() != null && criteria.getPeekAfter() == null) {
            return page.getRecords().stream().peek(criteria.getPeekBefore()).map(mapper).collect(Collectors.toList());
        } else if (criteria.getPeekBefore() == null && criteria.getPeekAfter() != null) {
            return page.getRecords().stream().map(mapper).peek(criteria.getPeekAfter()).collect(Collectors.toList());
        }
        return page.getRecords().stream().map(mapper).collect(Collectors.toList());
    }
}
