package com.cirle.scientific.utils.page;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;

public class PageBean<T> {

	public static final int PAGERECORD = 20;
	private Integer index;

	public Integer getIndex() {
		return index;
	}

	public void setIndex(Integer index) {
		this.index = index;
	}

	/**
	 * 
	 * @param pageNumber
	 * @param pagzSize
	 * @param orders
	 *            多字段排序，key-排序字段名称 value-升序(asc)/降序(desc)命令
	 * @return
	 */
	public PageRequest buildPageRequest(int pageNumber, int pagzSize, LinkedHashMap<String, String> orders) {
		List<Order> sortOrders = new LinkedList<Order>();
		Set<Entry<String, String>> set = orders.entrySet();
		for (Entry<String, String> entry : set) {
			String key = entry.getKey();
			String val = entry.getValue();
			if ("desc".equals(val.trim().toLowerCase())) {
				sortOrders.add(new Order(Direction.DESC, key));
			} else {
				sortOrders.add(new Order(Direction.ASC, key));
			}
		}
		Sort sort = Sort.by(sortOrders);
		return PageRequest.of(pageNumber - 1, pagzSize, sort);
	}


	/** 
	 * 条件查询时动态组装条件 
	 */
	public Specification<T> buildSpecification(final Vector<Param> params, final Vector<Param> or_params){ 
	  return new Specification<T>() { 
		private static final long serialVersionUID = -4078394200942994674L;

		@Override
		  public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
			  List<Predicate> predicates = new ArrayList<Predicate>(); 
			  for (Param param : params) {
				String opt = param.getOperator();
				if ("=".equals(opt)) {
					predicates.add(cb.equal(root.<String>get(param.getParamName()),param.getParamValue())); 
				}else if (">".equals(opt)) {
					predicates.add(cb.greaterThan(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
				} else if ("<".equals(opt)) {
					predicates.add(cb.lessThan(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
				} else if (">=".equals(opt)) {
					predicates.add(cb.greaterThanOrEqualTo(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
				} else if ("<=".equals(opt)) {
					predicates.add(cb.lessThanOrEqualTo(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
				} else if ("in".equals(opt)){
					predicates.add(root.<Long>get(param.getParamName()).in(java.util.Arrays.asList(param.getParamValue().toString().split(","))));//confirmOrgNo 
				} else if ("like".equals(opt)) {
					predicates.add(cb.like(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
				} else if ("<>".equals(opt)) {
					predicates.add(cb.notEqual(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
				}
			  }
			  Predicate[] predicatesWhereArr=new Predicate[predicates.size()];				
			  Predicate predicatesWhere= cb.and(predicates.toArray(predicatesWhereArr));
			  
			  List<Predicate> listPermission=new ArrayList<>();
			  if(or_params != null){
				  for (Param param : or_params) {
					  String opt = param.getOperator();
					  if ("=".equals(opt)) {
						  listPermission.add(cb.equal(root.<String>get(param.getParamName()),param.getParamValue())); 
					  }else if (">".equals(opt)) {
						  listPermission.add(cb.greaterThan(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
					  } else if ("<".equals(opt)) {
						  listPermission.add(cb.lessThan(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
					  } else if (">=".equals(opt)) {
						  listPermission.add(cb.greaterThanOrEqualTo(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
					  } else if ("<=".equals(opt)) {
						  listPermission.add(cb.lessThanOrEqualTo(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
					  } else if ("in".equals(opt)){
						  listPermission.add(root.<Long>get(param.getParamName()).in(java.util.Arrays.asList(param.getParamValue().toString().split(","))));//confirmOrgNo 
					  } else if ("like".equals(opt)) {
						  listPermission.add(cb.like(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
					  } else if ("<>".equals(opt)) {
						  listPermission.add(cb.notEqual(root.<String>get(param.getParamName()),param.getParamValue().toString())); 
					  }
				  }
			  }
			  Predicate[] predicatesPermissionArr=new Predicate[listPermission.size()];				
			  Predicate predicatesPermission= cb.or(listPermission.toArray(predicatesPermissionArr));
			  
			  if(predicatesPermissionArr.length > 0){
				  return query.where(predicatesWhere,predicatesPermission).getRestriction();
			  }else{
				  return query.where(predicatesWhere).getRestriction();
			  }
		  }
	  }; 
	}

	/**
	 * 条件查询时动态组装条件
	 */
	public Specification<T> buildSpecification1(final Vector<Param> params){
		return new Specification<T>() {
			@Override
			public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicates = new ArrayList<Predicate>();
				for (Param param : params) {
					String opt = param.getOperator();
					if ("=".equals(opt)) {
						predicates.add(cb.equal(root.<String>get(param.getParamName()),param.getParamValue()));
					}else if (">".equals(opt)) {
						predicates.add(cb.greaterThan(root.<String>get(param.getParamName()),param.getParamValue().toString()));
					} else if ("<".equals(opt)) {
						predicates.add(cb.lessThan(root.<String>get(param.getParamName()),param.getParamValue().toString()));
					} else if (">=".equals(opt)) {
						predicates.add(cb.greaterThanOrEqualTo(root.<String>get(param.getParamName()),param.getParamValue().toString()));
					} else if ("<=".equals(opt)) {
						predicates.add(cb.lessThanOrEqualTo(root.<String>get(param.getParamName()),param.getParamValue().toString()));
					} else if ("in".equals(opt)){
						predicates.add(root.<Long>get(param.getParamName()).in(java.util.Arrays.asList(param.getParamValue().toString().split(","))));//confirmOrgNo
					} else if ("like".equals(opt)) {
						predicates.add(cb.like(root.<String>get(param.getParamName()),param.getParamValue().toString()));
					}
				}
				return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
			}
		};
	}
}
