package com.rjconsultores.ventaboletos.service.impl;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rjconsultores.ventaboletos.dao.BpeDAO;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.BpeService;
import com.rjconsultores.ventaboletos.utilerias.exportacao.ExportacaoBpe;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPEVo;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.xml.BPeUtil;
import com.rjconsultores.ventaboletos.utilerias.fiscal.vo.FiscalRdi;
import com.rjconsultores.ventaboletos.vo.bpe.BPeVO;

@Service("bpeService")
public class BpeServiceImpl implements BpeService {
	private static final Logger log = LogManager.getLogger(BpeServiceImpl.class);

	@Autowired
	private BpeDAO bpeDAO;

	@Autowired
	private ExportacaoBpe exportacaoBpe;

	@Autowired
	private DataSource dataSourceRead;

	@Override
	public List<FiscalRdi> buscarBpeRDI(Date inicio, Date fim, Empresa empresa, List<Estado> estados, boolean isReceitaTerceiros, boolean consultaOtimizada) {
		Connection connection = null;
		try {
			connection = getConnectionRead();
			return bpeDAO.buscarBpeRDI(connection, inicio, fim, empresa.getEmpresaId(), estados, isReceitaTerceiros, consultaOtimizada);
		} catch (Exception e) {
			log.error("", e);
		} finally {
			try {
				if (connection != null && !connection.isClosed()) {
					connection.close();
				}
			} catch (SQLException e) {
				log.error("error fechar conexão", e);
				throw new RuntimeException(e);
			}
		}
		return null;
	}

	@Override
	public String buscarArquivoExportacaoBPE(Date inicio, Date fim, Empresa empresa, Estado estado, String nomeArquivo, boolean consultaOtimizada) {
		Connection connection = null;

		try {
			connection = getConnectionRead();
			ExportacaoBPEVo registro = bpeDAO.buscarRegistroExportacaoBpe(connection, inicio, fim, empresa.getEmpresaId(), estado.getCveestado(), consultaOtimizada, empresa.getCodContPrevidencia());

			return exportacaoBpe.gerarArquivoBPE(inicio, fim, nomeArquivo, empresa.getNombempresa(), registro);

		} finally {
			try {
				if (connection != null && !connection.isClosed()) {
					connection.close();
				}
			} catch (SQLException e) {
				log.error("error fechar conexão", e);

				throw new RuntimeException(e);
			}
		}
	}

	@Override
	public String buscarXmlBPE(String chBpe) {
		Connection connection = null;
		try {
			connection = getConnectionRead();
			return bpeDAO.buscarXmlBPE(connection, chBpe);

		} finally {
			try {
				if (connection != null && !connection.isClosed()) {
					connection.close();
				}
			} catch (SQLException e) {
				log.error("error fechar conexão", e);

				throw new RuntimeException(e);
			}
		}
	}

	private Connection getConnectionRead() {
		return DataSourceUtils.getConnection(dataSourceRead);
	}

	@Override
	@Transactional
	public List<BPeVO> buscarBPeRejeitadosContingencia(Integer empresaId, String numBpe, String chbpe, Date dtVendaInicio, Date dtVendaFim, List<Integer> estados, List<String> codigosRejeicoes) {
		return bpeDAO.buscarBPeRejeitadosContingencia(empresaId, numBpe, chbpe, dtVendaInicio, dtVendaFim, estados, codigosRejeicoes);
	}

	@Override
	@Transactional
	public void definirBPeRejeitadoSefazReenvio(List<BPeVO> bpesReenvio) throws BusinessException {
		for (BPeVO bpe : bpesReenvio) {
			bpeDAO.definirBPeRejeitadoSefazReenvio(bpe.getBpeId(), bpe.getCodstat());
		}
	}

	@Override
	public List<BPeVO> buscarBPeVendaEEventosAutorizados(Integer empresaId, Date dtVendaInicio, Date dtVendaFim, Integer estadoId) {
		return bpeDAO.buscarBPeVendaEEventosAutorizados(empresaId, dtVendaInicio, dtVendaFim, estadoId);
	}

	@Override
	public byte[] extrairXmlsBPe(List<BPeVO> bpes) {
		if(bpes != null && !bpes.isEmpty()) {
			Map<String, InputStream> arquivos = new HashMap<String, InputStream>();
			for (BPeVO bpe : bpes) {
				Map<String, InputStream> arquivo = null;
				if(StringUtils.isNotBlank(bpe.getTipoevento())) {
					arquivo = BPeUtil.convertBPeXmlRegularEventoToArquivoXml(bpe);
					arquivos.put(arquivo.entrySet().iterator().next().getKey(), arquivo.entrySet().iterator().next().getValue());
					arquivo = BPeUtil.convertBPeXmlRepostaEventoToArquivoXml(bpe);
					arquivos.put(arquivo.entrySet().iterator().next().getKey(), arquivo.entrySet().iterator().next().getValue());
				} else {
					arquivo = BPeUtil.convertBPeXmlRegularToArquivoXml(bpe);
					arquivos.put(arquivo.entrySet().iterator().next().getKey(), arquivo.entrySet().iterator().next().getValue());
					arquivo = BPeUtil.convertBPeXmlRepostaToArquivoXml(bpe);
					arquivos.put(arquivo.entrySet().iterator().next().getKey(), arquivo.entrySet().iterator().next().getValue());
				}
			}
			return BPeUtil.zipFiles(arquivos);
		}
		return null;
	}

}
