package com.rjconsultores.ventaboletos.utilerias.exportacao.bpe;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.UtiliteriasFiscal;
import com.rjconsultores.ventaboletos.utilerias.exportacao.bpe.xml.BPeUtil;

import br.inf.portalfiscal.bpe.TBPe;

public class ExportacaoBPEVo {

	static String VAZIO = "";
	static final BigDecimal ZERO = BigDecimal.ZERO;
	static int MOTIVO_CANCELACION_AGRUPACION_CORRIDA = 17;

	public class StatusBpe {
		static final String CONTIGENCIA_ENVIADA = "-1";
		static final String VENDA = "100";
		static final String CANCELAMENTO_BPE_HOMOLOGADO = "101";
		static final String SUBSTITUICAO_BPE_HOMOLOGADA = "102";
		static final String VENDA_CONTIGENCIA = "150";
		static final String EVENTOS = "135";
	}

	public class EventosBpe {
		static final String CANCELAMENTO = "110111";
		static final String NAO_EMBARQUE = "110115";
		static final String TROCA_POLTRONA = "110116";
	}

	public static class CrtBpe {
		static final Integer SIMPLES_NACIONAL = 1;
		static final Integer SIMPLES_NACIONAL_EXCESSO_RECEITA_BRUTA = 2;
		static final Integer REGIME_NORMAL = 3;
	}

	public class TipoComp {
		public static final String TARIFA = "01";
		public static final String PEDAGIO = "02";
		public static final String TAXA_EMBARQUE = "03";
		public static final String SEGURO = "04";
		public static final String TAXA_MANUTENCAO_RODOVIA = "05";
		public static final String SERVICO_VENDA_INTEGRADA = "06";
		public static final String OUTROS = "99";

	}

	private List<ExportacaoBPEBase> listaRegistroBaseBPE;

	public ExportacaoBPEVo() {
		listaRegistroBaseBPE = new ArrayList<ExportacaoBPEBase>(0);
	}

	public List<ExportacaoBPEBase> getListaRegistroBaseBPE() {
		return listaRegistroBaseBPE;
	}

	public void setListaRegistroBaseBPE(List<ExportacaoBPEBase> listaRegistroBaseBPE) {
		this.listaRegistroBaseBPE = listaRegistroBaseBPE;
	}

	public static boolean isBpeCancelado(String codstatus) {
		return (codstatus == null ? false : (codstatus.equals(StatusBpe.EVENTOS) || codstatus.equals(StatusBpe.CANCELAMENTO_BPE_HOMOLOGADO)));
	}

	public static boolean validaBPeCorridaAgrupada(ExportacaoBPEBase registro) {
		if (registro.getMotivoCancelacionId() == MOTIVO_CANCELACION_AGRUPACION_CORRIDA) {
			return true;
		} else {
			if (!StringUtils.equals(registro.getDhEmisao(), registro.getDhrecbtoBPe())
					&& registro.isActivoBPe() && StringUtils.equals(registro.getCodstatus(), StatusBpe.VENDA)) {
				return true;
			} else {
				return false;
			}
		}
	}

	public static ExportacaoBPEBase gerarListas(ExportacaoBPEBase registro) {

		String indContribuicaoPrevidenciaria = StringUtils.isBlank(registro.getIndContribuicaoPrevidenciaria()) ? "00000060" : StringUtils.leftPad(registro.getIndContribuicaoPrevidenciaria(), 8, "0");
		boolean isCancelamento = isBpeCancelado(registro.getCodstatus());
		String tpDoc = isCancelamento ? "1" : (StringUtils.isBlank(registro.getChbpeSub()) ? "0" : "0");
		String numBpe = StringUtils.isBlank(registro.getNbp()) ? registro.getNumBpe() : registro.getNbp();
		String dhEmisao = registro.getDhEmisao();

		if (isCancelamento) {

			ExportacaoBPETipoBPE tipoBPE = new ExportacaoBPETipoBPE(registro.getCodEstabelecimento(),
					registro.getChbpe(), registro.getNumSerieBpe(),
					numBpe, dhEmisao, tpDoc, VAZIO, null, null,
					VAZIO, VAZIO, VAZIO, VAZIO, VAZIO, null, VAZIO, VAZIO, VAZIO,
					VAZIO, registro.getRetorno(), VAZIO);
			registro.getListaRegistroBPE().add(tipoBPE);

		} else {
			String municipioOrigem = StringUtils.substring(registro.getCmunini(), 2);
			String municipioDestino = StringUtils.substring(registro.getCmunfim(), 2);
			String estadoOrigem = registro.getUfini();
			String estadoDestino = registro.getUffim();

			boolean isInterMunicipal = estadoOrigem.equals(estadoDestino);
			String codigoContabil = isInterMunicipal ? registro.getCodigocontabilMunicipal() : registro.getCodigoContabilEstadual();

			String dataPrestacao = StringUtils.isBlank(registro.getDhemb()) ? registro.getDhrecbto()
					: DateUtil.changeFormatStringDate(registro.getDhemb(), DateUtil.formatGMT, DateUtil.formatExp);

			String vBC = null;
			String pICMS = null;
			String vICMS = null;
			String cst = null;
			String pRedBC = null;
			String vBP = null;
			String vDesconto = null;
			String vPgto = null;

			String vTxEmbarque = null;
			String vPedagio = null;
			String vSeguro = null;

			if (StringUtils.isNotBlank(registro.getPicms00())) {
				vBC = registro.getVbc00();
				pICMS = registro.getPicms00();
				vICMS = registro.getVicms00();
			} else if (StringUtils.isNotBlank(registro.getPicms20())) {
				vBC = registro.getVbc20();
				pICMS = registro.getPicms20();
				vICMS = registro.getVicms20();
				pRedBC = registro.getpRedBC();
			}

			vBP = registro.getVbp();
			vDesconto = registro.getVdesconto();
			vPgto = registro.getVpgto();

			vPedagio = (isInterMunicipal && !registro.getIndPedadioEstdual()) ? (registro.getVcomp02() == null ? "0.0" : registro.getVcomp02()) : "0.0";
			if (vPedagio.equals("0.0"))
				vPedagio = (!isInterMunicipal && !registro.getIndPedagioMunicipal()) ? (registro.getVcomp02() == null ? "0.0" : registro.getVcomp02()) : "0.0";

			vTxEmbarque = (isInterMunicipal && !registro.getIndTxEmbarqueEstadual()) ? (registro.getVcomp03() == null ? "0.0" : registro.getVcomp03()) : "0.0";
			if (vTxEmbarque.equals("0.0"))
				vTxEmbarque = (!isInterMunicipal && !registro.getIndTxEmbarqueMunicipal()) ? (registro.getVcomp03() == null ? "0.0" : registro.getVcomp03()) : "0.0";

			vSeguro = (isInterMunicipal && !registro.getIndSeguroEstadual()) ? (registro.getVcomp04() == null ? "0.0" : registro.getVcomp04()) : "0.0";
			if (vSeguro.equals("0.0"))
				vSeguro = (!isInterMunicipal && !registro.getIndSeguroMunicipal()) ? (registro.getVcomp04() == null ? "0.0" : registro.getVcomp04()) : "0.0";

			// validar cst enviado
			if (StringUtils.isNotBlank(registro.getCst00()))
				cst = registro.getCst00();
			else if (StringUtils.isNotBlank(registro.getCst20()))
				cst = registro.getCst20();
			else if (StringUtils.isNotBlank(registro.getCst45()))
				cst = registro.getCst45();
			else if (StringUtils.isNotBlank(registro.getCst90()))
				cst = registro.getCst90();
			else if (StringUtils.isNotBlank(registro.getCstoutrauf()))
				cst = registro.getCstoutrauf();
			else if (StringUtils.isNotBlank(registro.getCstsn()))
				cst = registro.getCstsn();

			String cstCofins = "01";
			String cstPis = "01";

			// dependende dos parametros
			BigDecimal valorPago = new BigDecimal(vPgto == null ? "0.0" : vPgto);
			BigDecimal txEmbarque = new BigDecimal(vTxEmbarque == null ? "0.0" : vTxEmbarque);
			BigDecimal pedagio = new BigDecimal(vPedagio == null ? "0.0" : vPedagio);
			BigDecimal seguro = new BigDecimal(vSeguro == null ? "0.0" : vSeguro);

			BigDecimal txExtras = txEmbarque.add(pedagio).add(seguro);

			BigDecimal receitaTriCofins = new BigDecimal(vBC == null ? "0.0" : vBC);
			if (pRedBC != null) {
				receitaTriCofins = valorPago.subtract(txExtras);
			}

			BigDecimal valorBruto = StringUtils.isBlank(vBP) ? registro.getValortotal() : new BigDecimal(vBP == null ? "0.0" : vBP);
			BigDecimal desconto = StringUtils.isBlank(vDesconto) ? registro.getvDesconto() : new BigDecimal(vDesconto == null ? "0.0" : vDesconto);

			String chbpeSub = registro.getChbpeSub();
			String tpBpe = StringUtils.isBlank(registro.getChbpeSub()) ? "1" : "2";

			ExportacaoBPETipoBPE tipoBPE = new ExportacaoBPETipoBPE(registro.getCodEstabelecimento(), registro.getChbpe(), registro.getNumSerieBpe(),
					numBpe, dhEmisao, tpDoc, dataPrestacao, valorBruto,
					desconto, estadoOrigem, municipioOrigem, estadoDestino, municipioDestino,
					cstCofins, receitaTriCofins, tpBpe, chbpeSub, codigoContabil,
					indContribuicaoPrevidenciaria, registro.getRetorno(), cstPis);

			registro.getListaRegistroBPE().add(tipoBPE);

			String cfop = isInterMunicipal ? "5357" : "6357";

			String csosnb = "";
			if (registro.getCrt().equals(CrtBpe.SIMPLES_NACIONAL)) {
				csosnb = CrtBpe.SIMPLES_NACIONAL.toString();
				csosnb = UtiliteriasFiscal.formataNumerico(csosnb, 3);
			} else if (registro.getCrt().equals(CrtBpe.SIMPLES_NACIONAL_EXCESSO_RECEITA_BRUTA)) {
				csosnb = CrtBpe.SIMPLES_NACIONAL_EXCESSO_RECEITA_BRUTA.toString();
				csosnb = UtiliteriasFiscal.formataNumerico(csosnb, 3);
			}

			BigDecimal baseCalculoICMS = new BigDecimal(vBC == null ? "0.0" : vBC);
			BigDecimal aliquotaICMS = new BigDecimal(pICMS == null ? "0.0" : pICMS);
			BigDecimal icms = new BigDecimal(vICMS == null ? "0.0" : vICMS);

			BigDecimal isentas = registro.getValortotal().subtract(baseCalculoICMS);
			if (pRedBC != null) {
				isentas = txExtras;
			}

			BigDecimal outras = new BigDecimal(pRedBC == null ? "0.0" : pRedBC);
			if (pRedBC != null) {
				outras = valorPago.subtract(baseCalculoICMS);
				outras = outras.subtract(isentas);
			}

			ExportacaoBPETipoDPE tipoDPE = new ExportacaoBPETipoDPE(registro.getValortotal(), cfop, cst, csosnb,
					baseCalculoICMS, aliquotaICMS, icms, isentas, outras);
			registro.getListaRegistroDPE().add(tipoDPE);

		}

		return registro;
	}

	/*
	 * Apos a Implementação dos novos campos na taleta BPE na venda não utilizar mais este metodo para importação de dados BPe
	 */
	@Deprecated
	public static ExportacaoBPEBase gerarListasXML(ExportacaoBPEBase registro) {

		String indContribuicaoPrevidenciaria = StringUtils.isBlank(registro.getIndContribuicaoPrevidenciaria()) ? "00000060" : StringUtils.leftPad(registro.getIndContribuicaoPrevidenciaria(), 8, "0");

		boolean isCancelamento = isBpeCancelado(registro.getCodstatus());

		String numBpe = registro.getNumBpe();
		String tpDoc = isCancelamento ? "1" : (StringUtils.isBlank(registro.getChbpeSub()) ? "0" : "0");
		String dhEmisao = registro.getDhEmisao();

		if (isCancelamento) {
			ExportacaoBPETipoBPE tipoBPE = new ExportacaoBPETipoBPE(registro.getCodEstabelecimento(), registro.getChbpe(), registro.getNumSerieBpe(),
					numBpe, dhEmisao, tpDoc, VAZIO, null, null,
					VAZIO, VAZIO, VAZIO, VAZIO, VAZIO, null, VAZIO, VAZIO, VAZIO,
					VAZIO, registro.getRetorno(), VAZIO);

			registro.getListaRegistroBPE().add(tipoBPE);

		} else {

			TBPe tbpe = null;
			String xml = StringUtils.isNotBlank(registro.getXmlAnterior()) ? registro.getXmlAnterior() : registro.getXml();

			if (StringUtils.isNotBlank(xml))
				tbpe = BPeUtil.convertXmlToBpe(xml);

			String municipioOrigem = StringUtils.substring((StringUtils.isNotBlank(xml) ? tbpe.getInfBPe().getIde().getCMunIni() : registro.getMunicipioOrigem()), 2);
			String municipioDestino = StringUtils.substring((StringUtils.isNotBlank(xml) ? tbpe.getInfBPe().getIde().getCMunFim() : registro.getMunicipioDestino()), 2);
			String estadoOrigem = (StringUtils.isNotBlank(xml) ? tbpe.getInfBPe().getIde().getUFIni().value() : registro.getEstadoOrigem());
			String estadoDestino = (StringUtils.isNotBlank(xml) ? tbpe.getInfBPe().getIde().getUFFim().value() : registro.getEstadoDestino());

			boolean isInterMunicipal = estadoOrigem.equals(estadoDestino);
			String codigoContabil = isInterMunicipal ? registro.getCodigocontabilMunicipal() : registro.getCodigoContabilEstadual();
			numBpe = StringUtils.isNotBlank(xml) ? tbpe.getInfBPe().getIde().getNBP() : registro.getNumBpe();
			String dataPrestacao = StringUtils.isBlank(xml) ? registro.getDhrecbto()
					: DateUtil.changeFormatStringDate(tbpe.getInfBPe().getInfPassagem().getDhEmb(), DateUtil.formatGMT, DateUtil.formatExp);

			String vBC = null;
			String pICMS = null;
			String vICMS = null;
			String cst = null;
			String pRedBC = null;
			String vBP = null;
			String vDesconto = null;
			String vPgto = null;

			String vTxEmbarque = null;
			String vPedagio = null;
			String vSeguro = null;

			if (StringUtils.isNotBlank(xml)) {
				if (tbpe.getInfBPe().getImp().getICMS().getICMS00() != null) {
					vBC = tbpe.getInfBPe().getImp().getICMS().getICMS00().getVBC();
					pICMS = tbpe.getInfBPe().getImp().getICMS().getICMS00().getPICMS();
					vICMS = tbpe.getInfBPe().getImp().getICMS().getICMS00().getVICMS();
				} else if (tbpe.getInfBPe().getImp().getICMS().getICMS20() != null) {
					vBC = tbpe.getInfBPe().getImp().getICMS().getICMS20().getVBC();
					pICMS = tbpe.getInfBPe().getImp().getICMS().getICMS20().getPICMS();
					vICMS = tbpe.getInfBPe().getImp().getICMS().getICMS20().getVICMS();
					pRedBC = tbpe.getInfBPe().getImp().getICMS().getICMS20().getPRedBC();
				}

				if (tbpe.getInfBPe().getInfValorBPe() != null) {
					vBP = tbpe.getInfBPe().getInfValorBPe().getVBP();
					vDesconto = tbpe.getInfBPe().getInfValorBPe().getVDesconto();
					vPgto = tbpe.getInfBPe().getInfValorBPe().getVPgto();

					for (TBPe.InfBPe.InfValorBPe.Comp comp : tbpe.getInfBPe().getInfValorBPe().getComp()) {

						if (comp.getTpComp().equals(TipoComp.PEDAGIO)) {
							vPedagio = (isInterMunicipal && !registro.getIndPedadioEstdual()) ? (comp.getVComp() == null ? "0.0" : comp.getVComp()) : "0.0";
							if (vPedagio.equals("0.0"))
								vPedagio = (!isInterMunicipal && !registro.getIndPedagioMunicipal()) ? (comp.getVComp() == null ? "0.0" : comp.getVComp()) : "0.0";
						}

						if (comp.getTpComp().equals(TipoComp.TAXA_EMBARQUE)) {
							vTxEmbarque = (isInterMunicipal && !registro.getIndTxEmbarqueEstadual()) ? (comp.getVComp() == null ? "0.0" : comp.getVComp()) : "0.0";
							if (vTxEmbarque.equals("0.0"))
								vTxEmbarque = (!isInterMunicipal && !registro.getIndTxEmbarqueMunicipal()) ? (comp.getVComp() == null ? "0.0" : comp.getVComp()) : "0.0";
						}

						if (comp.getTpComp().equals(TipoComp.SEGURO)) {
							vSeguro = (isInterMunicipal && !registro.getIndSeguroEstadual()) ? (comp.getVComp() == null ? "0.0" : comp.getVComp()) : "0.0";
							if (vSeguro.equals("0.0"))
								vSeguro = (!isInterMunicipal && !registro.getIndSeguroMunicipal()) ? (comp.getVComp() == null ? "0.0" : comp.getVComp()) : "0.0";
						}
					}
				}

				// validar cst enviado
				if (tbpe.getInfBPe().getImp().getICMS().getICMS00() != null)
					cst = tbpe.getInfBPe().getImp().getICMS().getICMS00().getCST();
				else if (tbpe.getInfBPe().getImp().getICMS().getICMS20() != null)
					cst = tbpe.getInfBPe().getImp().getICMS().getICMS20().getCST();
				else if (tbpe.getInfBPe().getImp().getICMS().getICMS45() != null)
					cst = tbpe.getInfBPe().getImp().getICMS().getICMS45().getCST();
				else if (tbpe.getInfBPe().getImp().getICMS().getICMS90() != null)
					cst = tbpe.getInfBPe().getImp().getICMS().getICMS90().getCST();
				else if (tbpe.getInfBPe().getImp().getICMS().getICMSOutraUF() != null)
					cst = tbpe.getInfBPe().getImp().getICMS().getICMSOutraUF().getCST();
				else if (tbpe.getInfBPe().getImp().getICMS().getICMSSN() != null)
					cst = tbpe.getInfBPe().getImp().getICMS().getICMSSN().getCST();

			}

			String cstCofins = "01";
			String cstPis = "01";

			// dependende dos parametros
			BigDecimal valorPago = new BigDecimal(vPgto == null ? "0.0" : vPgto);
			BigDecimal txEmbarque = new BigDecimal(vTxEmbarque == null ? "0.0" : vTxEmbarque);
			BigDecimal pedagio = new BigDecimal(vPedagio == null ? "0.0" : vPedagio);
			BigDecimal seguro = new BigDecimal(vSeguro == null ? "0.0" : vSeguro);

			BigDecimal txExtras = txEmbarque.add(pedagio).add(seguro);

			BigDecimal receitaTriCofins = new BigDecimal(vBC == null ? "0.0" : vBC);
			if (pRedBC != null) {
				receitaTriCofins = valorPago.subtract(txExtras);
			}

			BigDecimal valorBruto = StringUtils.isBlank(xml) ? registro.getValortotal() : new BigDecimal(vBP == null ? "0.0" : vBP);
			BigDecimal desconto = StringUtils.isBlank(xml) ? registro.getvDesconto() : new BigDecimal(vDesconto == null ? "0.0" : vDesconto);

			String chbpeSub = StringUtils.isBlank(xml) ? "" : (tbpe.getInfBPe().getInfBPeSub() == null ? "" : tbpe.getInfBPe().getInfBPeSub().getChBPe());
			String tpBpe = StringUtils.isBlank(xml) ? "" : (StringUtils.isBlank(tbpe.getInfBPe().getInfBPeSub() == null ? "" : tbpe.getInfBPe().getInfBPeSub().getChBPe()) ? "1" : "2");

			ExportacaoBPETipoBPE tipoBPE = new ExportacaoBPETipoBPE(registro.getCodEstabelecimento(), registro.getChbpe(), registro.getNumSerieBpe(),
					numBpe, dhEmisao, tpDoc, dataPrestacao, valorBruto,
					desconto, estadoOrigem, municipioOrigem, estadoDestino, municipioDestino,
					cstCofins, receitaTriCofins, tpBpe, chbpeSub, codigoContabil,
					indContribuicaoPrevidenciaria, registro.getRetorno(), cstPis);

			registro.getListaRegistroBPE().add(tipoBPE);

			String cfop = isInterMunicipal ? "5357" : "6357";

			String csosnb = "";
			if (registro.getCrt().equals(CrtBpe.SIMPLES_NACIONAL)) {
				csosnb = CrtBpe.SIMPLES_NACIONAL.toString();
				csosnb = UtiliteriasFiscal.formataNumerico(csosnb, 3);
			} else if (registro.getCrt().equals(CrtBpe.SIMPLES_NACIONAL_EXCESSO_RECEITA_BRUTA)) {
				csosnb = CrtBpe.SIMPLES_NACIONAL_EXCESSO_RECEITA_BRUTA.toString();
				csosnb = UtiliteriasFiscal.formataNumerico(csosnb, 3);
			}

			BigDecimal baseCalculoICMS = new BigDecimal(vBC == null ? "0.0" : vBC);
			BigDecimal aliquotaICMS = new BigDecimal(pICMS == null ? "0.0" : pICMS);
			BigDecimal icms = new BigDecimal(vICMS == null ? "0.0" : vICMS);

			BigDecimal isentas = registro.getValortotal().subtract(baseCalculoICMS);
			if (pRedBC != null) {
				isentas = txExtras;
			}

			BigDecimal outras = new BigDecimal(pRedBC == null ? "0.0" : pRedBC);
			if (pRedBC != null) {
				outras = valorPago.subtract(baseCalculoICMS);
				outras = outras.subtract(isentas);
			}

			ExportacaoBPETipoDPE tipoDPE = new ExportacaoBPETipoDPE(registro.getValortotal(), cfop, cst, csosnb,
					baseCalculoICMS, aliquotaICMS, icms, isentas, outras);
			registro.getListaRegistroDPE().add(tipoDPE);

		}

		return registro;
	}

}
