package br.mp.mprj.portal.portlet.gestaomensagens.search;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.portlet.PortletRequest;

import com.liferay.portal.kernel.search.BooleanClauseOccur;
import com.liferay.portal.kernel.search.BooleanQuery;
import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.Hits;
import com.liferay.portal.kernel.search.ParseException;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.SearchContextFactory;
import com.liferay.portal.kernel.search.SearchEngineUtil;
import com.liferay.portal.kernel.search.SearchException;
import com.liferay.portal.kernel.search.Sort;
import com.liferay.portal.kernel.search.SortFactoryUtil;
import com.liferay.portal.kernel.search.StringQueryFactoryUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.model.User;
import com.liferay.portal.util.PortalUtil;

import br.mp.mprj.portal.portlet.gestaomensagens.search.indexer.UserIndexer;
import br.mp.mprj.portal.portlet.gestaomensagens.search.vo.UserVO;

public class UserSearch {
		
	private static final Sort[] SORT_PADRAO = {SortFactoryUtil.create("fullName_sortable", false)};
	
	public static Map<Integer , List<UserVO>> pesquisar(PortletRequest req, long companyId , int posicaoInicial , int tamanho , String ordem) 
			throws ParseException, SearchException {
		
		final List<UserVO> list = new ArrayList<UserVO>();
		Sort [] ordenacao = null;
		
		String fullName = ParamUtil.getString(req, "fullName");
		String emailAddress = ParamUtil.getString(req, "emailAddress");
		
		SearchContext sc = SearchContextFactory.
				getInstance(PortalUtil.getHttpServletRequest(req));
		
		sc.setAndSearch(true);
		sc.setEntryClassNames(UserIndexer.CLASS_NAMES);
		
		if (ordem == null || "".equals(ordem)){
			ordenacao = SORT_PADRAO;
		}else{
			Sort[] temp = {SortFactoryUtil.create(ordem, false)};
			ordenacao = temp;
		}
		
		sc.setSorts(ordenacao);
		
		BooleanQuery query = BooleanQueryFactoryUtil.create(sc);
		
		//utilizar desta definicao para, criando outro BooleanQuery para aplicar o BooleanClauseOccur, 
		//evitar resultados incorretos ao utilizar BooleanQuery.
		BooleanQuery bqEntryClassName = BooleanQueryFactoryUtil.create(sc);
		bqEntryClassName.addExactTerm(Field.ENTRY_CLASS_NAME, User.class.getName());
		
		//forcar que o entryClassName seja obrigatorio na query gerada pela API, 
		//para evitar resultados incorretos de outras entidades.
		query.add(bqEntryClassName, BooleanClauseOccur.MUST);
		
		if (Validator.isNotNull(fullName)) {
			query.addTerm("+fullName", fullName, true);
		}
		
		if (Validator.isNotNull(emailAddress)) {
			query.addTerm("+emailAddress", emailAddress, true);
		}
		
		Hits hits = SearchEngineUtil.search(sc.getSearchEngineId(), companyId, query , ordenacao  , posicaoInicial , tamanho );
		
		Map<Integer , List<UserVO>> retorno = new HashMap<>();
		if (hits.getLength() > 0) {
			//fazer o parse dos resultados
			for (Document doc : hits.getDocs()) {
				
				UserVO user = new UserVO();
				user.setUserId(GetterUtil.getLong(doc.get(Field.ENTRY_CLASS_PK)));
				user.setFullName(doc.get("fullName"));
				user.setEmailAddress(doc.get("emailAddress"));
				user.setCompanyId(GetterUtil.getLong(doc.get("companyId")));
				
				list.add(user);
			}
			
			retorno.put(hits.getLength(), list);
		}
		return retorno;
	}

	
	public static List<UserVO> pesquisar(PortletRequest req , String ids) 
			throws ParseException, SearchException {
		
		final List<UserVO> list = new ArrayList<UserVO>();
		
		
		SearchContext sc = SearchContextFactory.
				getInstance(PortalUtil.getHttpServletRequest(req));
		
		sc.setAndSearch(true);
		sc.setEntryClassNames(UserIndexer.CLASS_NAMES);
		sc.setSorts(SORT_PADRAO);
		
		StringBundler sbQuery = new StringBundler();
		
		sbQuery.append(StringPool.PLUS + Field.ENTRY_CLASS_NAME + StringPool.COLON + User.class.getName() +  " ");
		
		if (Validator.isNotNull(ids)) {
			
			String [] userIds = ids.split(" ");
			String textIds = "";
			
			for (String i : userIds){
				textIds+= " userId:" + i;
			}
			sbQuery.append(StringPool.PLUS + "("+ textIds + ")");
		}
	
		Hits hits = SearchEngineUtil.search(sc, StringQueryFactoryUtil.create(sbQuery.toString()));
		
		if (hits.getLength() > 0) {
			//fazer o parse dos resultados
			for (Document doc : hits.getDocs()) {
				
				UserVO user = new UserVO();
				user.setUserId(GetterUtil.getLong(doc.get(Field.ENTRY_CLASS_PK)));
				user.setFullName(doc.get("fullName"));
				user.setEmailAddress(doc.get("emailAddress"));
				user.setCompanyId(GetterUtil.getLong(doc.get("companyId")));
				
				list.add(user);
			}
		}
		
		return list;
	}
	
	public static UserVO pesquisarUsuario(PortletRequest req , long id) throws ParseException, SearchException {

		SearchContext sc = SearchContextFactory.getInstance(PortalUtil.getHttpServletRequest(req));

		sc.setAndSearch(true);
		sc.setEntryClassNames(UserIndexer.CLASS_NAMES);
		sc.setSorts(SORT_PADRAO);

		StringBundler sbQuery = new StringBundler();

		sbQuery.append(StringPool.PLUS + Field.ENTRY_CLASS_NAME + StringPool.COLON + User.class.getName() +  " ");

		if (Validator.isNotNull(id)) {
			sbQuery.append(StringPool.PLUS + "( userId:" + id + ")");
		}

		Hits hits = SearchEngineUtil.search(sc, StringQueryFactoryUtil.create(sbQuery.toString()));

		UserVO user = new UserVO();
		if (hits.getLength() > 0) {
			//fazer o parse dos resultados
			Document doc = hits.getDocs()[0];
			
			user.setUserId(GetterUtil.getLong(doc.get(Field.ENTRY_CLASS_PK)));
			user.setFullName(doc.get("fullName"));
		}

		return user;
	}

}
