package com.rjconsultores.ventaboletos.utilerias.exportacao;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.utilerias.UtiliteriasFiscal;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPEBase;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPETipoBPE;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPETipoDPE;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPETipoOBE;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPETipoPRC;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.ExportacaoBPEVo;
import com.rjconsultores.ventaboletos.web.utilerias.spring.AppContext;

@Service("exportacaoBpe")
public class ExportacaoBpe {
	private static final Logger log = LogManager.getLogger(ExportacaoBpe.class);

	private static String VAZIO = "";
	private static String SEPARADOR = "|";

	public ExportacaoBpe() {

	}

	public String gerarArquivoBPE(final Date dataInicial, final Date dataFinal, String nomeArquivo, final String nomeEmpresa, ExportacaoBPEVo registro) {

		log.info(" Inicio --  Retorno da lista " + new Date());
		try {
			StringBuilder writer = new StringBuilder();

			ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");
			Constante contante = constanteService.buscarPorNomeConstante("IMPORT_BPE_LAYOUT_DIF");
			String valorConstante = contante == null ? null : contante.getValorconstante();

			boolean isVersao131 = StringUtils.isBlank(valorConstante) || "131".equals(valorConstante) ? true : false;
			String versaoLayout = StringUtils.isBlank(valorConstante)  || "131".equals(valorConstante) ? "131" : valorConstante;

			adicionarRegistroBPETipoCAB(writer, dataInicial, dataFinal, nomeEmpresa, nomeArquivo, versaoLayout);

			int linhas = 2;

			if (registro.getListaRegistroBaseBPE() != null && registro.getListaRegistroBaseBPE().size() == 0) {
				return null;
			}

			for (ExportacaoBPEBase ee : registro.getListaRegistroBaseBPE()) {

				for (ExportacaoBPETipoBPE tipoBPE : ee.getListaRegistroBPE()) {
					adicionarRegistroBPETipoBEP(writer, tipoBPE, isVersao131);
					linhas++;
				}

				for (ExportacaoBPETipoDPE tipoDPE : ee.getListaRegistroDPE()) {
					adicionarRegistroBPETipoDPE(writer, tipoDPE);
					linhas++;
				}

				/*
				 * Expecificado na documentação original
				 * 
				 * for (ExportacaoBPETipoOBE tipoOBE : ee.getListaRegistroOBE()) { adicionarRegistroBPETipoOBE(writer, tipoOBE); linhas++;
				 * 
				 * 
				 * for (ExportacaoBPETipoPRC tipoPRC : ee.getListaRegistroPRC()) { adicionarRegistroBPETipoRPC(writer, tipoPRC); linhas++; }
				 */
			}

			writer.append("TRA|" + linhas + UtiliteriasFiscal.QUEBRA_LINHA);

			log.info(" Fim --  Retorno da lista " + new Date());

			return writer.toString();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}

		return null;
	}

	private void adicionarRegistroBPETipoCAB(final StringBuilder sb, final Date dataInicial, final Date dataFinal, final String nomeEmpresa, final String arquivo, String versaoLayout) {
		sb.append("CAB").append(SEPARADOR);
		sb.append(versaoLayout).append(SEPARADOR);
		sb.append("TotalBus").append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(new Date())).append(SEPARADOR);
		sb.append(formataCaracter(nomeEmpresa, false, 15)).append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(dataInicial)).append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(dataFinal)).append(SEPARADOR);
		sb.append(arquivo).append(SEPARADOR);
		sb.append("N");
		sb.append(UtiliteriasFiscal.QUEBRA_LINHA);
	}

	private void adicionarRegistroBPETipoBEP(final StringBuilder sb, ExportacaoBPETipoBPE tipoBPE, boolean isVersao131) {

		String tipoRegistro = "BPE";
		/**
		 * Mantis 18267
		 */
		String estabelecimento = StringUtils.isBlank(tipoBPE.getEstabelecimento()) ? VAZIO : tipoBPE.getEstabelecimento();
		String chaveEletronica = tipoBPE.getChaveEletronica();
		String serie = tipoBPE.getSerie();
		String numero = tipoBPE.getNumero();
		String dataEmissao = StringUtils.isBlank(tipoBPE.getDataEmissao()) ? VAZIO : tipoBPE.getDataEmissao();
		String dataPrestacao = StringUtils.isBlank(tipoBPE.getDataPrestacao()) ? VAZIO : tipoBPE.getDataPrestacao();
		String situacaoDocumento = tipoBPE.getSituacaoDoc();

		String valorBruto = tipoBPE.getValorBruto() == null ? VAZIO : formataValor(tipoBPE.getValorBruto(), 15);
		String valorDesconto = tipoBPE.getValorDesconto() == null ? VAZIO : formataValor(tipoBPE.getValorDesconto(), 15);
		String UFOrigem = tipoBPE.getUFOrigem();
		String muniOrigem = tipoBPE.getMunicipioOrigem();
		String UFDestino = tipoBPE.getUFDestino();
		String muniDestino = tipoBPE.getMunicipioDestino();
		String CSTCOFINS = tipoBPE.getCstCofins();
		String receitaTributavelCOFINS = tipoBPE.getReceitaTriCofins() == null ? VAZIO : formataValor(tipoBPE.getReceitaTriCofins(), 15);
		String naturezaReceitaCOFINS = VAZIO;
		String CSTPIS = tipoBPE.getCstPis();
		String receitaTributavelPIS = tipoBPE.getReceitaTriCofins() == null ? VAZIO : formataValor(tipoBPE.getReceitaTriCofins(), 15);
		String naturezaReceitaPIS = VAZIO;
		String receitaCSL1 = VAZIO;
		String receitaCSL2 = VAZIO;
		String receitaIRPJ1 = VAZIO;
		String receitaIRPJ2 = VAZIO;
		String receitaIRPJ3 = VAZIO;
		String receitaIRPJ4 = VAZIO;
		String tipoBPe = tipoBPE.getTipoBPe();
		String chaveEletRef = StringUtils.isBlank(tipoBPE.getChaveEletronicaReferencia()) ? VAZIO : tipoBPE.getChaveEletronicaReferencia();
		String codigoContabil = StringUtils.isBlank(tipoBPE.getCodigoContabil()) ? VAZIO : tipoBPE.getCodigoContabil();
		String codigoPrevidenciaria = tipoBPE.getIndContribuicaoPrevidenciaria();
		String codigoComplementar = VAZIO;
		String observacao = VAZIO;
		String codAjusteFiscal = VAZIO;
		String exclussaoBCPISCOFINS = VAZIO;
		
		String baseCalculoAjusteICMS = VAZIO;
		String aliquotaAjusteICMS = VAZIO;
		String valorAjusteICMS = VAZIO;

		sb.append(tipoRegistro).append(SEPARADOR);
		sb.append(estabelecimento).append(SEPARADOR);
		sb.append(chaveEletronica).append(SEPARADOR);
		sb.append(serie).append(SEPARADOR);
		sb.append(numero).append(SEPARADOR);
		sb.append(dataEmissao).append(SEPARADOR);
		sb.append(situacaoDocumento).append(SEPARADOR);
		sb.append(dataPrestacao).append(SEPARADOR);
		sb.append(valorBruto).append(SEPARADOR);
		sb.append(valorDesconto).append(SEPARADOR);
		sb.append(UFOrigem).append(SEPARADOR);
		sb.append(muniOrigem).append(SEPARADOR);
		sb.append(UFDestino).append(SEPARADOR);
		sb.append(muniDestino).append(SEPARADOR);
		sb.append(CSTCOFINS).append(SEPARADOR);
		sb.append(receitaTributavelCOFINS).append(SEPARADOR);
		sb.append(naturezaReceitaCOFINS).append(SEPARADOR);
		sb.append(CSTPIS).append(SEPARADOR);
		sb.append(receitaTributavelPIS).append(SEPARADOR);
		sb.append(naturezaReceitaPIS).append(SEPARADOR);
		sb.append(receitaCSL1).append(SEPARADOR);
		sb.append(receitaCSL2).append(SEPARADOR);
		sb.append(receitaIRPJ1).append(SEPARADOR);
		sb.append(receitaIRPJ2).append(SEPARADOR);
		sb.append(receitaIRPJ3).append(SEPARADOR);
		sb.append(receitaIRPJ4).append(SEPARADOR);
		sb.append(tipoBPe).append(SEPARADOR);
		sb.append(chaveEletRef).append(SEPARADOR);
		sb.append(codigoContabil).append(SEPARADOR);
		sb.append(codigoPrevidenciaria).append(SEPARADOR);
		sb.append(codigoComplementar).append(SEPARADOR);
		sb.append(observacao).append(SEPARADOR);
		sb.append(codAjusteFiscal).append(isVersao131 ? VAZIO : SEPARADOR);
		
		if(!isVersao131) {
			sb.append(exclussaoBCPISCOFINS).append(SEPARADOR);
			sb.append(baseCalculoAjusteICMS).append(SEPARADOR);
			sb.append(aliquotaAjusteICMS).append(SEPARADOR);
			sb.append(valorAjusteICMS);
		}
		
		sb.append(UtiliteriasFiscal.QUEBRA_LINHA);
	}

	private void adicionarRegistroBPETipoDPE(final StringBuilder sb, ExportacaoBPETipoDPE tipoDPE) {
		String tipoRegistro = "DBE";
		String valor = formataValor(tipoDPE.getValor(), 15);
		String CFOP = tipoDPE.getCfop();
		String CSTB = tipoDPE.getCstb();
		String CSOSNB = tipoDPE.getCsosnb();
		String baseCalculoICMS = formataValor(tipoDPE.getBaseCalculoICMS(), 15);
		String aliquotaICMS = formataValor(tipoDPE.getAliquotaICMS(), 15);
		String ICMS = formataValor(tipoDPE.getIcms(), 15);
		String isentas = formataValor(tipoDPE.getIsentas(), 15);
		String outras = formataValor(tipoDPE.getOutras(), 15);

		sb.append(tipoRegistro).append(SEPARADOR);
		sb.append(valor).append(SEPARADOR);
		sb.append(CFOP).append(SEPARADOR);
		sb.append(CSTB).append(SEPARADOR);
		sb.append(CSOSNB).append(SEPARADOR);
		sb.append(baseCalculoICMS).append(SEPARADOR);
		sb.append(aliquotaICMS).append(SEPARADOR);
		sb.append(ICMS).append(SEPARADOR);
		sb.append(isentas).append(SEPARADOR);
		sb.append(outras);
		sb.append(UtiliteriasFiscal.QUEBRA_LINHA);
	}

	/*
	 * Expecificado na documentação original
	 */
	@SuppressWarnings("unused")
	private void adicionarRegistroBPETipoOBE(final StringBuilder sb, ExportacaoBPETipoOBE tipoOBE) {
		String tipoRegistro = "OBE";
		String codigo = tipoOBE.getCodigo();
		String valor = formataValor(tipoOBE.getValor(), 15);

		sb.append(tipoRegistro).append(SEPARADOR);
		sb.append(codigo).append(SEPARADOR);
		sb.append(valor);
		sb.append(UtiliteriasFiscal.QUEBRA_LINHA);
	}

	/*
	 * Expecificado na documentação original
	 */
	@SuppressWarnings("unused")
	private void adicionarRegistroBPETipoRPC(final StringBuilder sb, ExportacaoBPETipoPRC tipoPRC) {
		String tipoRegistro = "RPC";
		String UF = tipoPRC.getUf();
		String municipio = tipoPRC.getMunicipio();
		String valor = formataValor(tipoPRC.getValor(), 15);
		String baseCalculoICMS = formataValor(tipoPRC.getBaseCalculoICMS(), 15);
		String ICMS = formataValor(tipoPRC.getIcms(), 15);

		sb.append(tipoRegistro).append(SEPARADOR);
		sb.append(UF).append(SEPARADOR);
		sb.append(municipio).append(SEPARADOR);
		sb.append(valor).append(SEPARADOR);
		sb.append(baseCalculoICMS).append(SEPARADOR);
		sb.append(ICMS);
		sb.append(UtiliteriasFiscal.QUEBRA_LINHA);
	}

	private String formataValor(final BigDecimal valor, final int tamanho) {
		if (valor == null) {
			return "0";
		} else {
			return valor.setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
		}
	}

	private String formataCaracter(String valor, boolean removeMascara, int tamanho) {
		if (valor == null) {
			valor = VAZIO;
		}
		return valor;
	}

}