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.OcorrenciaServicoRelacionadoDTO;
import br.com.centralit.citcorpore.util.Enumerados.AuditoriaAcoes;
import br.com.centralit.citcorpore.util.Enumerados.TipoServico;
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;

public class OcorrenciaServicoRelacionadoDAO extends CrudDaoDefaultImpl {

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

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

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

		listFields.add(new Field("id", "idOcorrenciaServicoRelacionado", 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("idServicoRelacionado", "idServicoRelacionadoOcorrenciaServico", false, false, false, false));
		listFields.add(new Field("nomeServicoRelacionado", "nomeServicoRelacionadoOcorrenciaServico", false, false, false, false));
		listFields.add(new Field("faseServicoRelacionado", "faseServicoRelacionadoOcorrenciaServico", false, false, false, false));
		listFields.add(new Field("statusServicoRelacionado", "statusServicoRelacionadoOcorrenciaServico", false, false, false, false));
		listFields.add(new Field("tipoServicoRelacionado", "tipoServicoRelacionadoOcorrenciaServico", false, false, false, false));

		return listFields;
	}

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

	/**
	 * @author deborah.ferreira
	 * @since 04.02.2016
	 */
	@SuppressWarnings("unchecked")
	public Collection<OcorrenciaServicoRelacionadoDTO> findOcorrenciaServicoRelacionadoByIdOcorrenciaServicoAndTipoServico(final Integer idOcorrenciaServico, final String tipoServicoRelacionado)
			throws Exception {
		final List<Condition> condicao = new ArrayList<Condition>();
		final List<Order> ordenacao = new ArrayList<Order>();
		ordenacao.add(new Order("idOcorrenciaServicoRelacionado"));
		condicao.add(new Condition("idOcorrenciaServico", idOcorrenciaServico));
		condicao.add(new Condition("tipoServicoRelacionadoOcorrenciaServico", tipoServicoRelacionado));
		List<OcorrenciaServicoRelacionadoDTO> listaOcorrenciaServicoRelacionado = (List<OcorrenciaServicoRelacionadoDTO>) super.findByCondition(condicao, ordenacao);

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

		return Collections.emptyList();
	}

	/**
	 * Cria a ocorrência de serviço dos serviços relacionados
	 * 
	 * @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 acaoOcorrenciaServico
	 *            identificador do {@link AuditoriaAcoes}
	 * @param tipoServico
	 *            tipo do serviço relacionado, identificador do
	 *            {@link TipoServico}
	 * @author deborah.ferreira
	 * @since 04.02.2016
	 */
	@SuppressWarnings("unchecked")
	public void createOcorrenciaServicoRelacionado(final Integer idOcorrenciaServico, final List<Integer> listaIdsOcorrenciaServico, final String acaoOcorrenciaServico, final String tipoServico)
			throws Exception {
		List<Object> listResultado = new ArrayList<Object>();
		StringBuilder sqlBuilder = new StringBuilder();

		sqlBuilder.append("	SELECT ");
		sqlBuilder.append("		servicoAutoRelacionamento.idServico, ");
		sqlBuilder.append("		servico.nomeServico, ");
		sqlBuilder.append("		servico.faseServico, ");
		sqlBuilder.append("		servico.statusServico, ");
		sqlBuilder.append("		servico.tipoServico ");
		sqlBuilder.append("	FROM ");
		sqlBuilder.append("		ocorrenciaServico ocorrenciaServico ");
		sqlBuilder.append("		INNER JOIN servicoAutoRelacionamento servicoAutoRelacionamento ");
		sqlBuilder.append("			ON ocorrenciaServico.idServico = servicoAutoRelacionamento.idServicoRelacionado ");
		sqlBuilder.append("		INNER JOIN servico servico ");
		sqlBuilder.append("			ON servico.idServico = servicoAutoRelacionamento.idServico ");
		sqlBuilder.append("	WHERE ");
		sqlBuilder.append("		ocorrenciaServico.idOcorrenciaServico = ? ");
		sqlBuilder.append("		AND UPPER(servico.tipoServico) = UPPER(?) ");
		sqlBuilder.append("		AND servicoAutoRelacionamento.dataFim IS NULL ");
		sqlBuilder.append("		AND (servico.deleted IS NULL OR UPPER(servico.deleted) <> UPPER('Y')) ");
		sqlBuilder.append("	ORDER  BY servicoAutoRelacionamento.idServico ");

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

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

		List<String> listRetorno = new ArrayList<String>();
		listRetorno.add("idServicoRelacionadoOcorrenciaServico");
		listRetorno.add("nomeServicoRelacionadoOcorrenciaServico");
		listRetorno.add("faseServicoRelacionadoOcorrenciaServico");
		listRetorno.add("statusServicoRelacionadoOcorrenciaServico");
		listRetorno.add("tipoServicoRelacionadoOcorrenciaServico");

		List<OcorrenciaServicoRelacionadoDTO> listaOcorrenciaServicoRelacionado = this.engine.listConvertion(OcorrenciaServicoRelacionadoDTO.class,
				listResultado, listRetorno);

		if (listaOcorrenciaServicoRelacionado != null && !listaOcorrenciaServicoRelacionado.isEmpty()) {
			for (OcorrenciaServicoRelacionadoDTO ocorrenciaServicoRelacionadoDTO : listaOcorrenciaServicoRelacionado) {
				ocorrenciaServicoRelacionadoDTO.setIdOcorrenciaServico(idOcorrenciaServico);
				if (!listaIdsOcorrenciaServico.isEmpty() && !AuditoriaAcoes.DESVINCULADO.getIdentificador().equals(acaoOcorrenciaServico)
						&& listaIdsOcorrenciaServico.contains(ocorrenciaServicoRelacionadoDTO.getIdServicoRelacionadoOcorrenciaServico())) {
					ocorrenciaServicoRelacionadoDTO.setAcaoOcorrenciaServico(acaoOcorrenciaServico);
				}
				this.create(ocorrenciaServicoRelacionadoDTO);
			}
		}

		if (!listaIdsOcorrenciaServico.isEmpty() && AuditoriaAcoes.DESVINCULADO.getIdentificador().equals(acaoOcorrenciaServico)) {
			this.createOcorrenciaServicoRelacionadoDesvinculado(idOcorrenciaServico, listaIdsOcorrenciaServico.get(0));
		}
	}

	/**
	 * Cria a ocorrência de serviço dos serviços relacionados desvinculados
	 * 
	 * @see br.com.centralit.citcorpore.util.Enumerados.AuditoriaAcoes
	 * @param idOcorrenciaServico
	 * @param idOcorrenciaServicoDesvinculado
	 *            id do serviço relacionado que foi desvinculado
	 * @author deborah.ferreira
	 * @since 04.02.2016
	 */
	@SuppressWarnings("unchecked")
	private void createOcorrenciaServicoRelacionadoDesvinculado(final Integer idOcorrenciaServico, final Integer idServicoRelacionadoDesvinculado) throws Exception {
		List<Object> listResultado = new ArrayList<Object>();
		StringBuilder sqlBuilder = new StringBuilder();

		sqlBuilder.append("	SELECT ");
		sqlBuilder.append("		servico.idServico, ");
		sqlBuilder.append("		servico.nomeServico, ");
		sqlBuilder.append("		servico.faseServico, ");
		sqlBuilder.append("		servico.statusServico, ");
		sqlBuilder.append("		servico.tipoServico ");
		sqlBuilder.append("	FROM ");
		sqlBuilder.append("		servico servico ");
		sqlBuilder.append("	WHERE ");
		sqlBuilder.append("		servico.idServico = ? ");
		sqlBuilder.append("	ORDER  BY servico.idServico ");

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

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

		List<String> listRetorno = new ArrayList<String>();
		listRetorno.add("idServicoRelacionadoOcorrenciaServico");
		listRetorno.add("nomeServicoRelacionadoOcorrenciaServico");
		listRetorno.add("faseServicoRelacionadoOcorrenciaServico");
		listRetorno.add("statusServicoRelacionadoOcorrenciaServico");
		listRetorno.add("tipoServicoRelacionadoOcorrenciaServico");

		List<OcorrenciaServicoRelacionadoDTO> listaOcorrenciaServicoRelacionado = this.engine.listConvertion(OcorrenciaServicoRelacionadoDTO.class,
				listResultado, listRetorno);

		if (listaOcorrenciaServicoRelacionado != null && !listaOcorrenciaServicoRelacionado.isEmpty()) {
			OcorrenciaServicoRelacionadoDTO ocorrenciaServicoRelacionadoDesvinculado = listaOcorrenciaServicoRelacionado.iterator().next();
			ocorrenciaServicoRelacionadoDesvinculado.setIdOcorrenciaServico(idOcorrenciaServico);
			ocorrenciaServicoRelacionadoDesvinculado.setAcaoOcorrenciaServico(AuditoriaAcoes.DESVINCULADO.getIdentificador());
			this.create(ocorrenciaServicoRelacionadoDesvinculado);
		}
	}
}
