package br.com.centralit.citcorpore.integracao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import br.com.centralit.citcorpore.bean.DonoNegocioDTO;
import br.com.centralit.citcorpore.bean.OcorrenciaServicoDonoNegocioDTO;
import br.com.centralit.citcorpore.util.Enumerados.AuditoriaAcoes;
import br.com.centralit.citcorpore.util.Enumerados.DonoNegocioTipo;
import br.com.citframework.integracao.Condition;
import br.com.citframework.integracao.CrudDaoDefaultImpl;
import br.com.citframework.integracao.Field;
import br.com.citframework.integracao.Order;
import br.com.citframework.util.Constantes;
import br.com.citframework.util.UtilStrings;

public class OcorrenciaServicoDonoNegocioDAO extends CrudDaoDefaultImpl {

	public OcorrenciaServicoDonoNegocioDAO() {
		super(Constantes.getValue("DATABASE_ALIAS"), null);
	}

	@Override
	public String getTableName() {
		return "OcorrenciaServicoDonoNegocio";
	}

	@Override
	public Collection<Field> getFields() {
		List<Field> listFields = new ArrayList<Field>();

		listFields.add(new Field("id", "idOcorrenciaServicoDonoNegocio", true, true, false, false));
		listFields.add(new Field("idOcorrenciaServico", "idOcorrenciaServico", false, false, false, false));
		listFields.add(new Field("acaoOcorrenciaServico", "acaoOcorrenciaServico", false, false, false, false));
		listFields.add(new Field("idDonoNegocio", "idDonoNegocioOcorrenciaServico", false, false, false, false));
		listFields.add(new Field("nomeDonoNegocio", "nomeDonoNegocioOcorrenciaServico", false, false, false, false));
		listFields.add(new Field("tipoDonoNegocio", "tipoDonoNegocioOcorrenciaServico", false, false, false, false));

		return listFields;
	}

	@Override
	public Class<OcorrenciaServicoDonoNegocioDTO> getBean() {
		return OcorrenciaServicoDonoNegocioDTO.class;
	}

	/**
	 * @author deborah.ferreira
	 * @since 04.02.2016
	 */
	@SuppressWarnings("unchecked")
	public Collection<OcorrenciaServicoDonoNegocioDTO> findOcorrenciaServicoDonoNegocioByIdOcorrenciaServico(final Integer idOcorrenciaServico) throws Exception {
		final List<Condition> condicao = new ArrayList<Condition>();
		final List<Order> ordenacao = new ArrayList<Order>();
		ordenacao.add(new Order("idOcorrenciaServicoDonoNegocio"));
		condicao.add(new Condition("idOcorrenciaServico", idOcorrenciaServico));
		List<OcorrenciaServicoDonoNegocioDTO> listaOcorrenciaServicoDonoNegocio = (List<OcorrenciaServicoDonoNegocioDTO>) super.findByCondition(condicao, ordenacao);

		if (listaOcorrenciaServicoDonoNegocio != null && !listaOcorrenciaServicoDonoNegocio.isEmpty()) {
			return listaOcorrenciaServicoDonoNegocio;
		}

		return Collections.emptyList();
	}

	/**
	 * Cria a ocorrência de serviço dos donos de negócio
	 * 
	 * @see br.com.centralit.citcorpore.util.Enumerados.AuditoriaAcoes
	 * @param idOcorrenciaServico
	 * @param listaIdsOcorrenciaServico
	 *            lista dos ids do serviço relacionado em que houve alguma ação
	 * @param donoNegocioOcorrenciaServico
	 *            </br>
	 *            - acaoOcorrenciaServico (ver: {@link AuditoriaAcoes}) </br>
	 *            - Quando a ação for OcorrenciaServicoAcoes.Desvinculado deve
	 *            possuir todas as informações do dono do negócio desvinculado
	 * @author deborah.ferreira
	 * @since 04.02.2016
	 */
	@SuppressWarnings("unchecked")
	public void createOcorrenciaServicoDonoNegocio(final Integer idOcorrenciaServico, final List<Integer> listaIdsOcorrenciaServico, final DonoNegocioDTO donoNegocioOcorrenciaServico)
			throws Exception {
		List<Object> listResultado = new ArrayList<Object>();
		StringBuilder sqlBuilder = new StringBuilder();

		sqlBuilder.append(" SELECT ");
		sqlBuilder.append("		servicoDonoNegocio.idGrupo AS id, ");
		sqlBuilder.append("		grupo.nome, ");
		sqlBuilder.append(" 	servicoDonoNegocio.tipoDonoNegocio ");
		sqlBuilder.append(" FROM ");
		sqlBuilder.append(" 	ocorrenciaServico ocorrenciaServico ");
		sqlBuilder.append(" 	INNER JOIN servicoDonoNegocio servicoDonoNegocio ");
		sqlBuilder.append("     	ON ocorrenciaServico.idServico = servicoDonoNegocio.idServico ");
		sqlBuilder.append("     INNER JOIN grupo grupo ");
		sqlBuilder.append("     	ON grupo.idGrupo = servicoDonoNegocio.idGrupo ");
		sqlBuilder.append(" WHERE ");
		sqlBuilder.append(" 	ocorrenciaServico.idOcorrenciaServico = ? ");
		sqlBuilder.append(" 	AND grupo.dataFim IS NULL ");
		sqlBuilder.append(" UNION ");
		sqlBuilder.append(" SELECT ");
		sqlBuilder.append("		servicoDonoNegocio.idEmpregado AS id, ");
		sqlBuilder.append("		empregados.nome, ");
		sqlBuilder.append(" 	servicoDonoNegocio.tipoDonoNegocio ");
		sqlBuilder.append(" FROM ");
		sqlBuilder.append(" 	ocorrenciaServico ocorrenciaServico ");
		sqlBuilder.append(" 	INNER JOIN servicoDonoNegocio servicoDonoNegocio ");
		sqlBuilder.append("     	ON ocorrenciaServico.idServico = servicoDonoNegocio.idServico ");
		sqlBuilder.append("     INNER JOIN empregados empregados ");
		sqlBuilder.append("     	ON empregados.idEmpregado = servicoDonoNegocio.idEmpregado ");
		sqlBuilder.append(" WHERE ");
		sqlBuilder.append(" 	ocorrenciaServico.idOcorrenciaServico = ? ");
		sqlBuilder.append(" 	AND empregados.dataFim IS NULL ");
		sqlBuilder.append(" ORDER  BY id ");

		List<Object> listParametro = new ArrayList<Object>();
		listParametro.add(idOcorrenciaServico);
		listParametro.add(idOcorrenciaServico);

		listResultado = this.execSQL(sqlBuilder.toString(), listParametro.toArray());

		List<String> listRetorno = new ArrayList<String>();
		listRetorno.add("idDonoNegocioOcorrenciaServico");
		listRetorno.add("nomeDonoNegocioOcorrenciaServico");
		listRetorno.add("tipoDonoNegocioOcorrenciaServico");

		List<OcorrenciaServicoDonoNegocioDTO> listaOcorrenciaServicoDonoNegocio = this.engine.listConvertion(OcorrenciaServicoDonoNegocioDTO.class,
				listResultado, listRetorno);

		if (listaOcorrenciaServicoDonoNegocio != null && !listaOcorrenciaServicoDonoNegocio.isEmpty()) {
			for (OcorrenciaServicoDonoNegocioDTO ocorrenciaServicoDonoNegocioDTO : listaOcorrenciaServicoDonoNegocio) {
				ocorrenciaServicoDonoNegocioDTO.setIdOcorrenciaServico(idOcorrenciaServico);
				if (listaIdsOcorrenciaServico != null && !listaIdsOcorrenciaServico.isEmpty() && donoNegocioOcorrenciaServico != null
						&& !AuditoriaAcoes.DESVINCULADO.getIdentificador().equals(donoNegocioOcorrenciaServico.getAcaoDonoNegocioOcorrenciaServico())
						&& listaIdsOcorrenciaServico.contains(ocorrenciaServicoDonoNegocioDTO.getIdDonoNegocioOcorrenciaServico())
						&& ocorrenciaServicoDonoNegocioDTO.getTipoDonoNegocioOcorrenciaServico().equals(donoNegocioOcorrenciaServico.getTipoDonoNegocio())) {
					ocorrenciaServicoDonoNegocioDTO.setAcaoOcorrenciaServico(donoNegocioOcorrenciaServico.getAcaoDonoNegocioOcorrenciaServico());
				}
				this.create(ocorrenciaServicoDonoNegocioDTO);
			}
		}

		if (donoNegocioOcorrenciaServico != null && AuditoriaAcoes.DESVINCULADO.getIdentificador().equals(donoNegocioOcorrenciaServico.getAcaoDonoNegocioOcorrenciaServico())) {
			this.createOcorrenciaServicoDonoNegocioDesvinculado(idOcorrenciaServico, donoNegocioOcorrenciaServico);
		}
	}

	/**
	 * Cria a ocorrência de serviço do dono de negócio desvinculado
	 * 
	 * @see br.com.centralit.citcorpore.util.Enumerados.AuditoriaAcoes
	 * @param idOcorrenciaServico
	 * @param donoNegocioDesvinculado
	 * @author deborah.ferreira
	 * @since 04.02.2016
	 */
	@SuppressWarnings("unchecked")
	private void createOcorrenciaServicoDonoNegocioDesvinculado(final Integer idOcorrenciaServico, final DonoNegocioDTO donoNegocioDesvinculado) throws Exception {
		List<Object> listResultado = new ArrayList<Object>();
		StringBuilder sqlBuilder = new StringBuilder();
		List<Object> listParametro = new ArrayList<Object>();

		if (donoNegocioDesvinculado.getIdEmpregado() != null) {
			sqlBuilder.append("	SELECT ");
			sqlBuilder.append("		empregados.nome ");
			sqlBuilder.append("	FROM ");
			sqlBuilder.append("		empregados empregados ");
			sqlBuilder.append("	WHERE ");
			sqlBuilder.append("		empregados.idEmpregado = ? ");
			sqlBuilder.append("		AND empregados.dataFim IS NULL ");

			listParametro.add(donoNegocioDesvinculado.getIdEmpregado());
		} else if (donoNegocioDesvinculado.getIdGrupo() != null) {
			sqlBuilder.append("	SELECT ");
			sqlBuilder.append("		grupo.nome ");
			sqlBuilder.append("	FROM ");
			sqlBuilder.append("		grupo grupo ");
			sqlBuilder.append("	WHERE ");
			sqlBuilder.append("		grupo.idGrupo = ? ");
			sqlBuilder.append("		AND grupo.dataFim IS NULL ");

			listParametro.add(donoNegocioDesvinculado.getIdGrupo());
		}

		if (UtilStrings.isNotVazio(sqlBuilder.toString())) {
			listResultado = this.execSQL(sqlBuilder.toString(), listParametro.toArray());

			List<String> listRetorno = new ArrayList<String>();
			listRetorno.add("nomeDonoNegocioOcorrenciaServico");

			List<OcorrenciaServicoDonoNegocioDTO> listaOcorrenciaServicoDonoNegocio = this.engine.listConvertion(OcorrenciaServicoDonoNegocioDTO.class,
					listResultado, listRetorno);

			if (listaOcorrenciaServicoDonoNegocio != null && !listaOcorrenciaServicoDonoNegocio.isEmpty()) {
				OcorrenciaServicoDonoNegocioDTO ocorrenciaServicoDonoNegocioDTO = listaOcorrenciaServicoDonoNegocio.iterator().next();
				Integer idDonoNegocio = DonoNegocioTipo.EMPREGADO.getIdentificador().equals(donoNegocioDesvinculado.getTipoDonoNegocio()) ? donoNegocioDesvinculado.getIdEmpregado()
						: donoNegocioDesvinculado.getIdGrupo();
				ocorrenciaServicoDonoNegocioDTO.setIdOcorrenciaServico(idOcorrenciaServico);
				ocorrenciaServicoDonoNegocioDTO.setAcaoOcorrenciaServico(AuditoriaAcoes.DESVINCULADO.getIdentificador());
				ocorrenciaServicoDonoNegocioDTO.setIdDonoNegocioOcorrenciaServico(idDonoNegocio);
				ocorrenciaServicoDonoNegocioDTO.setTipoDonoNegocioOcorrenciaServico(donoNegocioDesvinculado.getTipoDonoNegocio());
				this.create(ocorrenciaServicoDonoNegocioDTO);
			}
		}
	}
}
