package com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.rjconsultores.ventaboletos.utilerias.MoneyHelper;

public class ExportacaoECF {
	private List<ExportacaoECFBase> listaRegistroECF;
	
	private List<ExportacaoECFTipoCFC> listaRegistroECFTipoCFC;
	private List<ExportacaoECFTipoCCF> listaRegistroECFTipoCCF;
	private List<ExportacaoECFTipoICF> listaRegistroECFTipoICF;
	private List<ExportacaoECFTipoPRC> listaRegistroECFTipoPRC;
	
	public ExportacaoECF() {
		listaRegistroECF = new ArrayList<ExportacaoECFBase>(0);
		
		listaRegistroECFTipoCFC = new ArrayList<ExportacaoECFTipoCFC>(0);
		listaRegistroECFTipoCCF = new ArrayList<ExportacaoECFTipoCCF>(0);
		listaRegistroECFTipoICF = new ArrayList<ExportacaoECFTipoICF>(0);
		listaRegistroECFTipoPRC = new ArrayList<ExportacaoECFTipoPRC>(0);
	}

	public List<ExportacaoECFBase> getListaRegistroECF() {
		return listaRegistroECF;
	}

	public List<ExportacaoECFTipoCFC> getListaRegistroECFTipoCFC() {
		return listaRegistroECFTipoCFC;
	}

	public List<ExportacaoECFTipoCCF> getListaRegistroECFTipoCCF() {
		return listaRegistroECFTipoCCF;
	}

	public List<ExportacaoECFTipoICF> getListaRegistroECFTipoICF() {
		return listaRegistroECFTipoICF;
	}

	public List<ExportacaoECFTipoPRC> getListaRegistroECFTipoPRC() {
		return listaRegistroECFTipoPRC;
	}
	
	public void gerarListas() {
		gerarCFC();
		gerarCCF();
		gerarICF();
		gerarPRC();
	}

	private void gerarCFC() {
		listaRegistroECFTipoCFC.clear();
		
		ExportacaoECFTipoCFC registro = null;
		
		Map<String, ExportacaoECFTipoCFC> group = new HashMap<String, ExportacaoECFTipoCFC>(0); 
		
		for (ExportacaoECFBase base : listaRegistroECF) {
			String key = base.getEcf() + "-" + base.getNumeroSerie() + "-" + base.getDataEmissao() + "-" + base.getCooInicial() + "-" + base.getCooFinal() + "-" + base.getCooReducaoZ() + "-" + base.getCro() + "-" + base.getCooReducaoZ() + "-" + base.getEstabelecimento() + "-" + base.getEstabelecimentoECF() + "-" + base.getNumeroIdentificacaoECF() + "-" + base.getUfOrigem();
			
			BigDecimal totalisenta = BigDecimal.ZERO;
			BigDecimal totalvenda = BigDecimal.ZERO;
			
			if (base.getIsenta().intValue() == 1) {
				totalisenta = MoneyHelper.somar(totalisenta, base.getValorTributado());
			}
			
			totalvenda = MoneyHelper.somar(totalvenda, base.getValorTributado());
			
			if (group.containsKey(key)) {
				registro = group.get(key);
				
				totalisenta = MoneyHelper.somar(totalisenta, registro.getValorIsentas());
				totalvenda = MoneyHelper.somar(totalvenda, registro.getValorTotal());
				
			} else {
				registro = new ExportacaoECFTipoCFC();
			}
			
			registro.setEstabelecimento(base.getEstabelecimento());
			registro.setDataEmissao(base.getDataEmissao());
			registro.setNumeroIdentificacaoECF(base.getNumeroIdentificacaoECF());
			registro.setEcf(base.getEcf());
			registro.setCooReducaoZ(base.getCooReducaoZ());
			registro.setCooInicial(base.getCooInicial());
			registro.setCooFinal(base.getCooFinal());
			registro.setContadorReducao(base.getContadorReducao());
			registro.setCro(base.getCro());
			registro.setEstabelecimentoECF(base.getEstabelecimentoECF());
			registro.setNumeroSerie(base.getNumeroSerie());
			registro.setInfoPadraoBilhetePassagem(base.getInfoPadraoBilhetePassagem());			

			registro.setValorIsentas(totalisenta);
			registro.setValorTotal(totalvenda);
			
			group.put(key, registro);
		}
		
		for (Map.Entry<String, ExportacaoECFTipoCFC> entry : group.entrySet()) {
			listaRegistroECFTipoCFC.add(entry.getValue());
		}
		
		Collections.sort(listaRegistroECFTipoCFC, new Comparator<ExportacaoECFTipoCFC>(){
		    public int compare(ExportacaoECFTipoCFC e1, ExportacaoECFTipoCFC e2) {
		        String c1 = e1.getDataEmissao() + (e1.getNumeroIdentificacaoECF() == null ? "000" : e1.getNumeroIdentificacaoECF());
		        String c2 = e2.getDataEmissao() + (e2.getNumeroIdentificacaoECF() == null ? "000" : e2.getNumeroIdentificacaoECF());
		    	
		    	return c1.compareToIgnoreCase(c2);
		    }
		});
	}
	
	private void gerarCCF() {
		listaRegistroECFTipoCCF.clear();
		
		ExportacaoECFTipoCCF registro = null;
		
		for (ExportacaoECFBase base : listaRegistroECF) {
			BigDecimal valorTributado = base.getValorTributado();

			registro = new ExportacaoECFTipoCCF();
			registro.setEcf(base.getEcf());
			registro.setDataEmissao(base.getDataEmissao());
			registro.setCoo(base.getCoo());
			registro.setValorServico(valorTributado);
			registro.setDescontoGlobal(null);
			registro.setCodigoParticipante(null);
			registro.setSituacaoCOO(0); // 0 - Documento Regular; 2 - Documento Cancelado
			registro.setAcrescimo(null);
			registro.setNumFolioSistema(base.getNumFolioSistema());

			registro.setCodigoSituacaoTribColunaB(null);

			// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
			if (base.getIsenta() == 1) {
				registro.setCodigoSituacaoTribColunaB(40);
			}

			registro.setUfOrigem(base.getUfOrigem());
			registro.setMunicipioOrigem(base.getMunicipioOrigem());
			registro.setUfDestino(base.getUfDestino());

			// IM=5357; serviço IE= 6357
			if (base.getUfOrigem().equals(base.getUfDestino())) {
				registro.setCfop(5357);
			} else {
				registro.setCfop(6357);
			}

			// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
			if (registro.getCodigoSituacaoTribColunaB() == null) {
				registro.setCodigoSituacaoTribColunaB(base.getReducaoBaseCalcICMS().compareTo(BigDecimal.ZERO) == 0 ? 0 : 20);
			}

			BigDecimal valorTotal = valorTributado; 

			BigDecimal red_base_calc_icms = MoneyHelper.instanciar(base.getReducaoBaseCalcICMS());
			BigDecimal tributacao_importacao = MoneyHelper.instanciar(base.getTributacaoImportacao());
			BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;

			if (registro.getCodigoSituacaoTribColunaB() != 0) {
				if ("30|40|41|50|60".contains(registro.getCodigoSituacaoTribColunaB().toString())) {
					tributacao_importacao = BigDecimal.ZERO;
				}
			}

			if (red_base_calc_icms != null) {
				valorBaseCalculoICMS = valorTotal.subtract(valorTotal.multiply(red_base_calc_icms.divide(BigDecimal.valueOf(100d))));
			} else {
				valorBaseCalculoICMS = valorTotal;
			}

			if (base.getIsenta() == 1) {
				valorBaseCalculoICMS = null;
			}

			registro.setValorTotal(valorTotal);

			// 1 - Demais; 2 - Região Metropolitanao ou seja, quando o campo CSTB for "40", esse campo deve vir "2". Do contrário, deve vir "1"
			registro.setTributacaoICMS(registro.getCodigoSituacaoTribColunaB() == 40 ? 2 : 1);

			registro.setValorBaseCalculoICMS(valorBaseCalculoICMS);
			registro.setAliquotaICMS(tributacao_importacao);

			if (valorTotal.doubleValue() != 0) {
				listaRegistroECFTipoCCF.add(registro);
			}
		}
		
		Collections.sort(listaRegistroECFTipoCCF, new Comparator<ExportacaoECFTipoCCF>(){
		    public int compare(ExportacaoECFTipoCCF e1, ExportacaoECFTipoCCF e2) {
		        String c1 = String.format("%06d", e1.getCoo());
		        String c2 = String.format("%06d", e2.getCoo());
		    	
		        if (c1.equals("000001")) {
		        	c1 = "999999";
		        }
		    	
		        if (c2.equals("000001")) {
		        	c2 = "999999";
		        }
		        
		    	return c1.compareToIgnoreCase(c2);
		    }
		});
	}
	
	private void gerarICF() {
		listaRegistroECFTipoICF.clear();
		
		ExportacaoECFTipoICF registro = null;
		
		Map<String, ExportacaoECFTipoICF> group = new HashMap<String, ExportacaoECFTipoICF>();
		
		for (ExportacaoECFBase base : listaRegistroECF) {
			BigDecimal valorTotal = base.getValorTributado();

			if (valorTotal == null || valorTotal.doubleValue() == 0) {
				continue;
			}

			BigDecimal red_base_calc_icms = MoneyHelper.instanciar(base.getReducaoBaseCalcICMS());
			BigDecimal porc_red_municipal = MoneyHelper.instanciar(base.getPorcReducaoMunicipal());
			BigDecimal porc_red_estadual = MoneyHelper.instanciar(base.getPorcReducaoEstadual());
			BigDecimal tributacao_importacao = MoneyHelper.instanciar(base.getTributacaoImportacao());
			BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;

			if (red_base_calc_icms != null) {
				BigDecimal aRed_base_calc_icms = MoneyHelper.dividir(red_base_calc_icms, BigDecimal.valueOf(100d));
				valorBaseCalculoICMS = MoneyHelper.subtrair(valorTotal, MoneyHelper.multiplicar(valorTotal, aRed_base_calc_icms));
			} else {
				valorBaseCalculoICMS = valorTotal;
			}

			BigDecimal valorICMSDebitado = BigDecimal.ZERO;

			if (tributacao_importacao != null) {
				BigDecimal aTributacao_importacao = MoneyHelper.dividir(tributacao_importacao, BigDecimal.valueOf(100d));
				valorICMSDebitado = MoneyHelper.multiplicar(valorBaseCalculoICMS, aTributacao_importacao);
			}

			BigDecimal valorICMSIsento = BigDecimal.ZERO;
			BigDecimal valorICMSOutros = MoneyHelper.subtrair(valorTotal, valorBaseCalculoICMS);

			String ecf = base.getEcf();
			String datamov = base.getDataEmissao();
			String ufDestino = "";
			String ufOrigem = "";
			Integer municipioOrigem = 0;
			Integer cfop = 0; // IM=5357; serviço IE= 6357

			// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
			Integer codigoSituacaoTribColunaB = null;

			if (base.getIsenta() == 1) {
				codigoSituacaoTribColunaB = 40;

				valorICMSOutros = valorTotal;
			}

			ufDestino = base.getUfDestino();
			ufOrigem = base.getUfOrigem();
			municipioOrigem = base.getMunicipioOrigem();

			// IM=5357; serviço IE= 6357
			if (base.getUfOrigem().equals(base.getUfDestino())) {
				cfop = 5357;
			} else {
				cfop = 6357;
			}

			// 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
			if (codigoSituacaoTribColunaB == null) {
				codigoSituacaoTribColunaB = base.getReducaoBaseCalcICMS().compareTo(BigDecimal.ZERO) == 0 ? 0 : 20;
			}

			if (codigoSituacaoTribColunaB == 40) {
				tributacao_importacao = BigDecimal.ZERO;
				valorBaseCalculoICMS = BigDecimal.ZERO;
				valorICMSDebitado = BigDecimal.ZERO;
				valorICMSOutros = BigDecimal.ZERO;

				valorICMSIsento = valorTotal;
			}

			String key = ecf + "|" + datamov + "|" + ufDestino + "|" + cfop.toString() + "|" + codigoSituacaoTribColunaB.toString() + "|" + municipioOrigem;

			if (group.containsKey(key)) {
				registro = group.get(key);

				valorTotal = MoneyHelper.somar(valorTotal, registro.getValorTotal());
				valorBaseCalculoICMS = MoneyHelper.somar(valorBaseCalculoICMS, registro.getValorBaseCalculoICMS());
				valorICMSDebitado = MoneyHelper.somar(valorICMSDebitado, registro.getValorICMSDebitado());
				valorICMSIsento = MoneyHelper.somar(valorICMSIsento, registro.getValorICMSIsento());
				valorICMSOutros = MoneyHelper.somar(valorICMSOutros, registro.getValorICMSOutros());
			} else {
				registro = new ExportacaoECFTipoICF();
				registro.setEcf(ecf);
				registro.setDataEmissao(datamov);
				registro.setUfDestino(ufDestino);
				registro.setCfop(cfop); // IM=5357; serviço IE= 6357
				registro.setCodigoSituacaoTribColunaB(codigoSituacaoTribColunaB); // 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
				registro.setAliquotaICMS(tributacao_importacao);
				registro.setUfOrigem(ufOrigem);
				registro.setMunicipioOrigem(municipioOrigem);

				registro.setRedutorBaseCalculoIcms(red_base_calc_icms);
				registro.setRedutorMunicipalIcms(porc_red_municipal);
				registro.setRedutorEstadualIcms(porc_red_estadual);

				group.put(key, registro);
			}

			registro.setValorTotal(valorTotal);
			registro.setValorBaseCalculoICMS(valorBaseCalculoICMS);
			registro.setValorICMSDebitado(valorICMSDebitado);
			registro.setValorICMSIsento(valorICMSIsento);
			registro.setValorICMSOutros(valorICMSOutros);
		}

		for (Map.Entry<String, ExportacaoECFTipoICF> entry : group.entrySet()) {
			if (entry.getValue().getAliquotaICMS() != null && entry.getValue().getValorBaseCalculoICMS() != null) {
				BigDecimal valorICMSDebitado = BigDecimal.ZERO;

				BigDecimal aTributacao_importacao = MoneyHelper.dividir(entry.getValue().getAliquotaICMS(), BigDecimal.valueOf(100d));
				valorICMSDebitado = MoneyHelper.multiplicar(entry.getValue().getValorBaseCalculoICMS(), aTributacao_importacao);
				
				entry.getValue().setValorICMSDebitado(valorICMSDebitado);
			}
			
			listaRegistroECFTipoICF.add(entry.getValue());
		}
		
		Collections.sort(listaRegistroECFTipoICF, new Comparator<ExportacaoECFTipoICF>(){
		    public int compare(ExportacaoECFTipoICF e1, ExportacaoECFTipoICF e2) {
		        String c1 = e1.getUfDestino();
		        String c2 = e2.getUfDestino();
		    	
		    	return c1.compareToIgnoreCase(c2);
		    }
		});
	}

	private void gerarPRC() {
		listaRegistroECFTipoPRC.clear();
		
		ExportacaoECFTipoPRC registro = null;
		
		Map<String, ExportacaoECFTipoPRC> group = new HashMap<String, ExportacaoECFTipoPRC>();
		
		for (ExportacaoECFBase base : listaRegistroECF) {
			BigDecimal valorTotal = base.getValorTributado();
			
			BigDecimal red_base_calc_icms = MoneyHelper.instanciar(base.getReducaoBaseCalcICMS());
			BigDecimal tributacao_importacao = MoneyHelper.instanciar(base.getTributacaoImportacao());
			BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;

			if (tributacao_importacao != null) {
				tributacao_importacao = MoneyHelper.dividir(tributacao_importacao, BigDecimal.valueOf(100d));
			}

			if (red_base_calc_icms != null) {
				BigDecimal aRed_base_calc_icms = MoneyHelper.dividir(red_base_calc_icms, BigDecimal.valueOf(100d));
				valorBaseCalculoICMS = MoneyHelper.subtrair(valorTotal, MoneyHelper.multiplicar(valorTotal, aRed_base_calc_icms));
			} else {
				valorBaseCalculoICMS = valorTotal;
			}

			BigDecimal valorICMS = BigDecimal.ZERO;

			if (tributacao_importacao != null) {
				valorICMS = MoneyHelper.multiplicar(valorBaseCalculoICMS, tributacao_importacao);
			}

			String key = base.getEcf() + "|" + base.getDataEmissao() + "|" + base.getUfOrigem() + "|" + base.getMunicipioOrigem();

			if (group.containsKey(key)) {
				registro = group.get(key);

				registro.setValorTotal(MoneyHelper.somar(registro.getValorTotal(), valorTotal));
				registro.setValorBaseCalculoICMS(MoneyHelper.somar(registro.getValorBaseCalculoICMS(), valorBaseCalculoICMS));
				registro.setValorICMS(MoneyHelper.somar(registro.getValorICMS(), valorICMS));

			} else {
				registro = new ExportacaoECFTipoPRC();
				registro.setEcf(base.getEcf());
				registro.setDataEmissao(base.getDataEmissao());
				registro.setUfOrigem(base.getUfOrigem());
				registro.setMunicipioOrigem(base.getMunicipioOrigem());
				registro.setValorTotal(valorTotal);
				registro.setValorBaseCalculoICMS(valorBaseCalculoICMS);
				registro.setValorICMS(valorICMS);
				registro.setTributacao(tributacao_importacao);
			}

			group.put(key, registro);
		}

		for (Map.Entry<String, ExportacaoECFTipoPRC> entry : group.entrySet()) {
			listaRegistroECFTipoPRC.add(entry.getValue());
		}
		
		Collections.sort(listaRegistroECFTipoPRC, new Comparator<ExportacaoECFTipoPRC>(){
		    public int compare(ExportacaoECFTipoPRC e1, ExportacaoECFTipoPRC e2) {
		        String c1 = String.valueOf(e1.getMunicipioOrigem());
		        String c2 = String.valueOf(e2.getMunicipioOrigem());
		    	
		    	return c1.compareToIgnoreCase(c2);
		    }
		});
	}
}
