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

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.portlet.PortletRequest;

import br.mp.mprj.portal.portlet.gestaomensagens.service.model.Mensagem;
import br.mp.mprj.portal.portlet.gestaomensagens.service.service.MensagemLocalServiceUtil;
import br.mp.mprj.portal.portlet.gestaomensagens.util.GestaoMensagensUtil;
import br.mp.mprj.portal.portlet.gestaomensagens.util.SearchUtil;

import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
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.util.GetterUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.service.ServiceContext;
import com.liferay.portal.service.ServiceContextFactory;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;

public class MensagemSearch {
	
	private static final Sort[] SORT_PADRAO = {SortFactoryUtil.create("createDate", Sort.FLOAT_TYPE ,  true)};

	
	public static Map<Integer , List<Mensagem>> pesquisar(PortletRequest req,  long companyId , 
					int posicaoInicial , int tamanho , String ordem) 
			throws SearchException, ParseException, java.text.ParseException {
		
		List<Mensagem> listaMensagem = new ArrayList<>();
		Sort [] ordenacao = null;
		
		String titulo = "";//ParamUtil.getString(req, "tituloMensagemSearch");
		String conteudo = "";//ParamUtil.getString(req, "conteudoMensagemSearch");
		String solicitante = "";//ParamUtil.getString(req, "solicitanteMensagemSearch");
		String codigo = "";//ParamUtil.getString(req, "codigoMensagemSearch");
		String status = "";//ParamUtil.getString(req, "statusMensagemSearch");
		boolean criadaPorMim = false;//ParamUtil.getBoolean(req, "criadaPorMimSearch");
		String dataSolicitacao = "";//ParamUtil.getString(req, "dataSolicitacaoSearch");
		String dataAgendamento = "";//ParamUtil.getString(req, "dataAgendamentoSearch");
		
		
		ThemeDisplay themeDisplay = (ThemeDisplay) req.getAttribute(WebKeys.THEME_DISPLAY);

		long groupId = themeDisplay.getScopeGroupId();
		String groupIdStr = String.valueOf(groupId);
		
		
		if (!"".equals(ParamUtil.getString(req, "tituloMensagemSearch"))){
			titulo = ParamUtil.getString(req, "tituloMensagemSearch");
		} else if ("".equals(ParamUtil.getString(req, "operacao"))
				&& !"".equals(ParamUtil.getString(req, "titulo"))){
			titulo = ParamUtil.getString(req, "titulo");
		}
		
		if (!"".equals(ParamUtil.getString(req, "conteudoMensagemSearch"))){
			conteudo = ParamUtil.getString(req, "conteudoMensagemSearch");
		} else if ("".equals(ParamUtil.getString(req, "operacao"))
				&& !"".equals(ParamUtil.getString(req, "conteudo"))){
			conteudo = ParamUtil.getString(req, "conteudo");
		}
		
		if (!"".equals(ParamUtil.getString(req, "solicitanteMensagemSearch"))){
			solicitante = ParamUtil.getString(req, "solicitanteMensagemSearch");
		} else if ("".equals(ParamUtil.getString(req, "operacao"))
				&& !"".equals(ParamUtil.getString(req, "solicitante"))){
			solicitante = ParamUtil.getString(req, "solicitante");
		}
		
		if (!"".equals(ParamUtil.getString(req, "codigoMensagemSearch"))){
			codigo = ParamUtil.getString(req, "codigoMensagemSearch");
		} else if ("".equals(ParamUtil.getString(req, "operacao"))
				&& !"".equals(ParamUtil.getString(req, "codigoMensagem"))){
			codigo = ParamUtil.getString(req, "codigoMensagem");
		}
		
		if (!"".equals(ParamUtil.getString(req, "statusMensagemSearch"))){
			status = ParamUtil.getString(req, "statusMensagemSearch");
		} else if ("".equals(ParamUtil.getString(req, "operacao"))
				&& !"".equals(ParamUtil.getString(req, "statusMensagem"))){
			status = ParamUtil.getString(req, "statusMensagem");
		}
		
		if (!"".equals(ParamUtil.getBoolean(req, "criadaPorMimSearch"))){
			criadaPorMim = ParamUtil.getBoolean(req, "criadaPorMimSearch");
		} else if ("".equals(ParamUtil.getString(req, "operacao"))
				&& !"".equals(ParamUtil.getBoolean(req, "criadaPorMim"))){
			criadaPorMim = ParamUtil.getBoolean(req, "criadaPorMim");
		}
		
		if (!"01/01/2000".equals(ParamUtil.getString(req, "dataSolicitacaoSearch")) &&
				!"".equals(ParamUtil.getString(req, "dataSolicitacaoSearch"))){
			dataSolicitacao = ParamUtil.getString(req, "dataSolicitacaoSearch");
		} else if ("".equals(ParamUtil.getString(req, "operacao"))
				&& !"".equals(ParamUtil.getString(req, "dataSolicitacao"))){
			dataSolicitacao = ParamUtil.getString(req, "dataSolicitacao");
		}
		
		if (!"01/01/2000".equals(ParamUtil.getString(req, "dataAgendamentoSearch")) &&
				!"".equals(ParamUtil.getString(req, "dataAgendamentoSearch"))){
			dataAgendamento = ParamUtil.getString(req, "dataAgendamentoSearch");
		} else if ("".equals(ParamUtil.getString(req, "operacao"))
				&& !"".equals(ParamUtil.getString(req, "dataAgendamento"))){
			dataAgendamento = ParamUtil.getString(req, "dataAgendamento");
		}
		
		SearchContext sc = SearchContextFactory.
				getInstance(PortalUtil.getHttpServletRequest(req));
		
		sc.setAndSearch(true);
		//sc.setEntryClassNames(MensagemIndex.CLASS_NAMES);
		
		if (ordem == null || "".equals(ordem)){
			ordenacao = SORT_PADRAO;
		}else{
			Sort[] temp = {SortFactoryUtil.create(ordem, ("desc".equals(ParamUtil.getString(req, "orderByType")) ? true : 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, Mensagem.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(titulo)) {
			query.addTerm("assunto", titulo, true , BooleanClauseOccur.MUST);
		}
		
		if (Validator.isNotNull(conteudo)) {
			query.addTerm("conteudo", conteudo, true , BooleanClauseOccur.MUST);
		}
		
		if (Validator.isNotNull(solicitante)) {
			query.addTerm("nomeSolicitante", solicitante, true , BooleanClauseOccur.MUST);
		}
		
		if (Validator.isNotNull(codigo)) {
			query.addTerm("codigoMensagem", codigo, true , BooleanClauseOccur.MUST);
		}
		
		if (Validator.isNotNull(status)) {
			query.addTerm("statusWorkflow", status, true , BooleanClauseOccur.MUST);
		}
		
		if (criadaPorMim) {
			try {
				ServiceContext serviceContext = ServiceContextFactory.getInstance(req);
				query.addTerm("userIdCriador", String.valueOf(serviceContext.getUserId()), true , BooleanClauseOccur.MUST);
			} catch (PortalException | SystemException e) {
				GestaoMensagensUtil.descartarRascunhos(req);
				throw new SearchException(e);
			}
		}
		
		//query.addTerm("ativo", "true", true , BooleanClauseOccur.MUST);
		query.addTerm("rascunho", "false", true , BooleanClauseOccur.MUST);
		query.addTerm("+groupId",groupIdStr ,  true);
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
		
		Date dataIni;
		Date dataFim;
		
		String inicioDia = " 00:00:01";
		String fimDia = " 23:59:59";
		
		if (Validator.isNotNull(dataSolicitacao) && !"01/01/2000".equals(dataSolicitacao)) {
			try {
				dataIni = sdf.parse(dataSolicitacao.concat(inicioDia));
				dataFim = sdf.parse(dataSolicitacao.concat(fimDia));

				query.addTerm("createDate","[" + SearchUtil.getDateFormat().format(dataIni) +  " TO " + SearchUtil.getDateFormat().format(dataFim)  + "]" , false, BooleanClauseOccur.MUST);
			} catch (java.text.ParseException e) {
				GestaoMensagensUtil.descartarRascunhos(req);
				throw new SearchException(e);
			}
		}
		
		if (Validator.isNotNull(dataAgendamento) && !"01/01/2000".equals(dataAgendamento)) {
			try {
				dataIni = sdf.parse(dataAgendamento.concat(inicioDia));
				dataFim = sdf.parse(dataAgendamento.concat(fimDia));

				query.addTerm("agendamento","[" + SearchUtil.getDateFormat().format(dataIni) +  " TO " + SearchUtil.getDateFormat().format(dataFim)  + "]" , false ,  BooleanClauseOccur.MUST);

			} catch (java.text.ParseException e) {
				GestaoMensagensUtil.descartarRascunhos(req);
				throw new SearchException(e);
			}
		}
		
		Hits hits = SearchEngineUtil.search(sc.getSearchEngineId(), companyId, query , ordenacao  , posicaoInicial , tamanho );
		
		//fazer o parse dos resultados
		for (Document doc : hits.getDocs()) {
			
			long mensagemId = GetterUtil.getLong(doc.get(Field.ENTRY_CLASS_PK));
			
			try {
				Mensagem mensagem = MensagemLocalServiceUtil.getMensagem(mensagemId);
				
				if (mensagem.getClonagemPai() > 0){
					mensagem.setAssunto("ALTERAÇÃO DE MENSAGEM - " + mensagem.getAssunto());
           	 	}
				
				if (!mensagem.getRascunho() && mensagem.getAssunto() != null && !"".equals(mensagem.getAssunto())){
					listaMensagem.add(mensagem);
				}
			}
			catch (SystemException|PortalException ex) {
				GestaoMensagensUtil.descartarRascunhos(req);
				throw new SearchException(ex);
			}
		}
		
		Map<Integer , List<Mensagem>> retorno = new HashMap<>();
		retorno.put(hits.getLength(), listaMensagem);
		
		req.setAttribute("criadaPorMimSearch", false);
		
		return retorno;
	}
}
