package com.liangjian.dataplatform.member.service;

import com.liangjian.dataplatform.member.util.dynamic.DynamicParams;
import com.liangjian.dataplatform.member.util.dynamic.SortDirection;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import javax.persistence.criteria.Predicate;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by huangziqi on 2019/12/17
 */
public abstract class DynamicQueryService<T> {

    public abstract JpaSpecificationExecutor<T> getJpaRepository();

    protected Specification<T> getDynamicSpecification(DynamicParams params) {
        Specification<T> specification = (root, criteriaQuery, criteriaBuilder) ->
                criteriaBuilder.and(params.getFilters()
                        .stream()
                        .map(i -> i.toJpaSpecification(root, criteriaBuilder))
                        .toArray(Predicate[]::new));
        return specification;
    }

    public Page<T> queryPageByCondition(DynamicParams params) {
        Pageable pageable = null;
        if(params.getSortField() != null && !params.getSortField().isEmpty()) {
            SortDirection sortDirection = params.getSortDirection() == null ? SortDirection.ASC : params.getSortDirection();
            pageable = PageRequest.of(params.getPage() - 1, params.getSize(), sortDirection.toJpaPageSort(), params.getSortField());
        } else {
            pageable = PageRequest.of(params.getPage() - 1, params.getSize());
        }
        Specification<T> specification = getDynamicSpecification(params);
        Page<T> paged = getJpaRepository().findAll(specification, pageable);
        return paged;
    }

    public List<T> queryListByCondition(DynamicParams params) {
        List<T> list = null;
        Specification<T> specification = getDynamicSpecification(params);
        if(params.getSortField() != null && !params.getSortField().isEmpty()) {
            SortDirection sortDirection = params.getSortDirection() == null ? SortDirection.ASC : params.getSortDirection();
            list = getJpaRepository().findAll(specification, Sort.by(sortDirection.toJpaPageSort(),params.getSortField()));
        } else {
            list = getJpaRepository().findAll(specification);
        }
        return list;
    }
}
