package br.com.centralit.citcorpore.negocio;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import br.com.centralit.citcorpore.bean.GrupoDTO;
import br.com.centralit.citcorpore.bean.SmartReportDTO;
import br.com.centralit.citcorpore.bean.SmartReportGrupoDTO;
import br.com.centralit.citcorpore.bean.UsuarioDTO;
import br.com.centralit.citcorpore.integracao.SmartReportDAO;
import br.com.centralit.citcorpore.integracao.SmartReportGrupoDAO;
import br.com.centralit.citgerencial.bean.SmartReportParameterOptionDTO;
import br.com.centralit.citgerencial.bean.SmartReportParameterOptionsDTO;
import br.com.citframework.dto.IDto;
import br.com.citframework.excecao.LogicException;
import br.com.citframework.excecao.PersistenceException;
import br.com.citframework.excecao.ServiceException;
import br.com.citframework.integracao.TransactionControler;
import br.com.citframework.integracao.TransactionControlerImpl;
import br.com.citframework.integracao.core.Page;
import br.com.citframework.integracao.core.Pageable;
import br.com.citframework.service.CrudServiceImpl;
import br.com.citframework.util.UtilDatas;
import br.com.citframework.util.UtilStrings;

@SuppressWarnings("unchecked")
public class SmartReportServiceEjb extends CrudServiceImpl implements SmartReportService {

	private SmartReportDAO dao;

	@Override
	protected SmartReportDAO getDao() {
		if (dao == null) {
			dao = new SmartReportDAO();
		}
		return dao;
	}

	@Override
	@SuppressWarnings("rawtypes")
	public List execSQL(SmartReportDTO smartReportDTO) throws Exception {
		return this.getDao().execSQL(smartReportDTO);
	}

	@Override
	public List<Map<String, Object>> executeQuery(SmartReportDTO smartReportDTO, Object[] parametros) throws Exception {
		return this.getDao().executeQuery(smartReportDTO, parametros);
	}

	@Override
	public List<String> getResultColumns(SmartReportDTO smartReportDTO, Object[] parametros) throws Exception {
		return this.getDao().getResultColumns(smartReportDTO, parametros);
	}

	@Override
	public IDto create(IDto model) throws ServiceException, LogicException {
		final SmartReportGrupoDAO smartReportGrupoDAO = new SmartReportGrupoDAO();
		final TransactionControler tc = new TransactionControlerImpl(this.getDao().getAliasDB());

		try {
			this.validaCreate(model);
			this.removeSpecialCharacter(model);

			this.getDao().setTransactionControler(tc);
			smartReportGrupoDAO.setTransactionControler(tc);

			tc.start();

			SmartReportDTO smartReportDTO = (SmartReportDTO) model;

			smartReportDTO = (SmartReportDTO) this.getDao().create(smartReportDTO);

			this.vinculaGrupos(smartReportDTO, smartReportGrupoDAO);

			tc.commit();
			tc.close();
		} catch (final Exception e) {
			this.rollbackTransaction(tc, e);
		}
		return model;
	}

	@Override
	public void update(IDto model) throws ServiceException, LogicException {
		final SmartReportGrupoDAO smartReportGrupoDAO = new SmartReportGrupoDAO();
		final TransactionControler tc = new TransactionControlerImpl(this.getDao().getAliasDB());

		try {
			this.validaCreate(model);
			this.removeSpecialCharacter(model);

			this.getDao().setTransactionControler(tc);
			smartReportGrupoDAO.setTransactionControler(tc);

			tc.start();

			final SmartReportDTO smartReportDTO = (SmartReportDTO) model;
			this.getDao().update(smartReportDTO);

			this.vinculaGrupos(smartReportDTO, smartReportGrupoDAO);

			tc.commit();
			tc.close();
		} catch (final Exception e) {
			this.rollbackTransaction(tc, e);
		}
	}

	private void removeSpecialCharacter(IDto model) {
		SmartReportDTO smartReportDTO = (SmartReportDTO) model;
		String identificacao = UtilStrings.removeCaracteresEspeciais(smartReportDTO.getIdentificacao());
		smartReportDTO.setIdentificacao(identificacao);
	}

	@Override
	public void delete(IDto model) throws ServiceException, LogicException {
		final TransactionControler tc = new TransactionControlerImpl(this.getDao().getAliasDB());

		try {
			this.validaDelete(model);
			this.getDao().setTransactionControler(tc);

			tc.start();

			final SmartReportDTO smartReportDTO = (SmartReportDTO) model;
			smartReportDTO.setDataFim(UtilDatas.getDataAtual());
			this.getDao().update(smartReportDTO);

			tc.commit();
			tc.close();
		} catch (final Exception e) {
			this.rollbackTransaction(tc, e);
		}
	}

	private void vinculaGrupos(SmartReportDTO smartReportDTO, SmartReportGrupoDAO smartReportGrupoDAO) throws PersistenceException {
		Integer idSmartReport = smartReportDTO.getIdSmartReport();
		smartReportGrupoDAO.deleteAllGruposByIdSmartReport(idSmartReport);
		Collection<SmartReportGrupoDTO> listaSmartReportGrupo = smartReportDTO.getListaGrupos();

		if (listaSmartReportGrupo != null && !listaSmartReportGrupo.isEmpty()) {
			for (final SmartReportGrupoDTO smartReportGrupoDTO : listaSmartReportGrupo) {
				smartReportGrupoDTO.setIdSmartReport(idSmartReport);
				smartReportGrupoDAO.create(smartReportGrupoDTO);
			}
		}
	}

	@Override
	public List<SmartReportDTO> findByIdsGrupoUsuarioAndIdCategoria(Collection<GrupoDTO> gruposUsuario, Integer idCategoria) throws Exception {
		return this.getDao().findByIdsGrupoUsuarioAndIdCategoria(gruposUsuario, idCategoria);
	}

	@Override
	public List<SmartReportDTO> findByIdsGrupoUsuarioAndTipoModuloExibicao(Collection<GrupoDTO> gruposUsuario, String tipoExibicao, String moduloExibicao) throws Exception {
		return this.getDao().findByIdsGrupoUsuarioAndTipoModuloExibicao(gruposUsuario, tipoExibicao, moduloExibicao);
	}

	@Override
	public Integer getTotalByIdsGrupoUsuarioAndIdCategoria(Collection<GrupoDTO> gruposUsuario, Integer idCategoria) throws Exception {
		return this.getDao().getTotalByIdsGrupoUsuarioAndIdCategoria(gruposUsuario, idCategoria);
	}

	@Override
	public Collection<SmartReportParameterOptionDTO> findParametroOptions(SmartReportParameterOptionsDTO options) throws Exception {
		return this.getDao().findParametroOptions(options);
	}

	@Override
	public Collection<SmartReportDTO> findByIdentificacao(String consulta) throws Exception {
		return this.getDao().findByIdentificacao(consulta);
	}

	@Override
	public List<SmartReportDTO> findAtivos() throws Exception {
		return this.getDao().findAtivos();
	}

	@Override
	public SmartReportDTO getByIdentificacao(String identificacao) throws Exception {
		return this.getDao().getByIdentificacao(identificacao);
	}

	@Override
	public Page<SmartReportDTO> findPaged(String filter, Pageable pageable, boolean isTotalizacao) throws Exception {
		return this.getDao().findPaged(filter, pageable, isTotalizacao);
	}

	@Override
	public List<SmartReportDTO> findAvailablesByUsuario(UsuarioDTO usuarioDTO) throws PersistenceException {
		return this.getDao().findAvailablesByUsuario(usuarioDTO);
	}
}
