package com.rjconsultores.ventaboletos.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.rjconsultores.ventaboletos.dao.EstadoDAO;
import com.rjconsultores.ventaboletos.dao.RelatorioAgepanDAO;
import com.rjconsultores.ventaboletos.enums.TipoDescontoBPe;
import com.rjconsultores.ventaboletos.enums.TipoIdentificacionDoc;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.RelatorioAgepanService;
import com.rjconsultores.ventaboletos.utilerias.MoneyHelper;
import com.rjconsultores.ventaboletos.utilerias.TimeZoneUtil;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.OrgaoConcedente.RelatorioGratuidadeAgepanVO;

@Service("relatorioAgepanService")
public class RelatorioAgepanServiceImpl implements RelatorioAgepanService {
	
	@Autowired
	RelatorioAgepanDAO relatorioAgepanDAO;
	
	@Autowired
	EstadoDAO estadoDAO;

	@Override
	public List<RelatorioGratuidadeAgepanVO> listar(Map<String, Object> parametros) throws BusinessException {
		return relatorioAgepanDAO.listar(parametros);
	}

	@Override
	public InputStream gerarArquivoGratuidadeAgepan(Map<String, Object> parametros) throws IOException, BusinessException {
		InputStream arquivo = null;
		
		List<RelatorioGratuidadeAgepanVO> retorno = listar(parametros);
		
		arquivo = gerarArquivo(retorno);
		
		return arquivo;
	}

	private InputStream gerarArquivo(List<RelatorioGratuidadeAgepanVO> retorno) throws IOException {
		HSSFWorkbook wb = new HSSFWorkbook();
		
		criarArquivoExcel(wb, retorno);
		
		String nomeArquivo =  UsuarioLogado.getUsuarioLogado().getNombusuario()
							  + "_" + Calendar.getInstance().getTime().getTime()
							  + "_" + "arquivoAgepan";

		File fNomeArquivo = File.createTempFile(nomeArquivo, ".tmp");
		
		FileOutputStream stream = new FileOutputStream(fNomeArquivo);
		stream.flush();
		wb.write(stream);
		stream.close();

		InputStream is = new FileInputStream(fNomeArquivo);
		
		return is;
	}

	private void criarArquivoExcel(HSSFWorkbook wb, List<RelatorioGratuidadeAgepanVO> dados) {
		HSSFSheet sheet = wb.createSheet("dados");
		int contRow = 0;
		String[] cabecalho1 = new String[] {"nBP","dhEmi","xLocOrig","xLocDest","dhEmb","xNome","CPF","tpDoc","nDoc","xDoc","tpViagem","tpServico","dhViagem","prefixo","poltrona","vBP","vDesconto","tpDesconto","xDesconto","qrCodBPe"};
		String[] cabecalho2 = new String[] {"[9]","[13]","[85]","[87]","[88]","[91]","[92]","[93]","[94]","[95]","[102]","[103]","[106]","[108]","[109]","[115]","[116]","[119]","[120]","[189]"};
		criarRow(contRow++, sheet, cabecalho1);
		criarRow(contRow++, sheet, cabecalho2);
		
		for (RelatorioGratuidadeAgepanVO vo : dados) {
			String[] vetVO = transformarVOToVetor(vo);
			criarRow(contRow++, sheet, vetVO);
		}
		
		for (int i = 0; i < cabecalho1.length; i++) {
			sheet.autoSizeColumn(i);
		}
	}

	private String[] transformarVOToVetor(RelatorioGratuidadeAgepanVO vo) {
		Map<String, Integer> dadosTimezoneParada = estadoDAO.getConfiguracoesFusoVeraoParada(vo.getOrigenId(), vo.getFechorventa()); 
		Map<String, Integer> dadosTimezonePuntoventa = estadoDAO.getConfiguracoesFusoVeraoPuntoventa(vo.getPuntoventaId(), vo.getFechorventa()); 
		
		List<String> retorno = new ArrayList<String>();

		//"nBP",
		retorno.add(vo.getNumBpe());
		
		//"dhEmi",
		String dataEmissao = TimeZoneUtil.ajustarPuntoVentaEmissaoOrigemViagemTimeZone(dadosTimezoneParada, dadosTimezonePuntoventa, vo.getFechorventa());
		retorno.add(dataEmissao);

		//"xLocOrig",
		retorno.add(vo.getOrigem());
		
		//"xLocDest",
		retorno.add(vo.getDestino());
		
		//"dhEmb",
		String dhEmbarque = TimeZoneUtil.ajustarTimeZone(dadosTimezoneParada, vo.getFechorviaje());
		retorno.add(dhEmbarque);
		
		//"xNome",
		retorno.add(StringUtils.isNotBlank(vo.getNombpasajero()) ? vo.getNombpasajero() : "");
		
		//"CPF",
		String cpf = carregarCpfBpe(vo.getDesctipodoc(), vo.getDesctipodoc2(), vo.getDescnumdoc(), vo.getDescnumdoc2());
		retorno.add(cpf);
		
		//"tpDoc",
		String descTipoDoc = carregarDescTipoDoc(vo.getDesctipodoc(), vo.getDesctipodoc2());
		TipoIdentificacionDoc identificacionDoc = TipoIdentificacionDoc.getTipo(descTipoDoc);
		String tpDoc = "5";
		if(identificacionDoc != null) {
			if (identificacionDoc.equals(TipoIdentificacionDoc.RG)) {
				tpDoc = "1";
			} else if (identificacionDoc.equals(TipoIdentificacionDoc.PASPT)) {
				tpDoc = "3";
			} else if (identificacionDoc.equals(TipoIdentificacionDoc.CN)) {
				tpDoc = "4";
			}
		}
		retorno.add(tpDoc);
		
		//"nDoc",
		String nDoc = carregarNumDoc(vo.getDescnumdoc(), vo.getDescnumdoc2());
		retorno.add(nDoc);
		
		//"xDoc",
		retorno.add("");
		
		//"tpViagem",
		retorno.add(vo.getCorridaextra());
		
		//"tpServico",
		retorno.add(vo.getTiposervicobpe());
		
		//"dhViagem",
		String dhViagem = TimeZoneUtil.ajustarTimeZone(dadosTimezoneParada, vo.getFechorviaje());
		retorno.add(dhViagem);
		
		//"prefixo",
		retorno.add(vo.getPrefixo());
		
		//"poltrona",
		retorno.add(vo.getNumasiento());
		
		//"vBP",
		retorno.add(MoneyHelper.arredondar(vo.getTotalbase()).toString());
		
		if(MoneyHelper.isMaior(vo.getDesconto(), BigDecimal.ZERO)) {
			//"vDesconto",
			retorno.add(MoneyHelper.arredondar(vo.getDesconto()).toString());
		
			//"tpDesconto",
			TipoDescontoBPe tipoDescontoBPe = null;
			if(StringUtils.isNotBlank(vo.getDescontobpe())) {
				tipoDescontoBPe = TipoDescontoBPe.valueOf(vo.getDescontobpe());
			}
			if(tipoDescontoBPe == null) {
				tipoDescontoBPe = TipoDescontoBPe.TARIFA_PROMOCIONAL;
			}
			retorno.add(tipoDescontoBPe.getValor());

			//"xDesconto",
			retorno.add(tipoDescontoBPe.getDescricao());
			
		} else {
			retorno.add("");
			retorno.add("");
			retorno.add("");
		}
		
		//"qrCodBPe"		
		retorno.add(vo.getChbpe());
		
		return retorno.toArray(new String[retorno.size()]);
	}

	private void criarRow(int numRow, HSSFSheet sheet, String[] dados) {
		int numColumn = 0;
		HSSFRow row = sheet.createRow(numRow);
		for (String dado : dados) {
			HSSFCell cell = row.createCell(numColumn++);
			cell.setCellValue(dado);
		}
	}
	
	private String carregarCpfBpe(String desctipodoc, String desctipodoc2, String descnumdoc, String descnumdoc2) {
		String cpfBpe = null;
		TipoIdentificacionDoc identificacionDoc = TipoIdentificacionDoc.getTipo(desctipodoc);
		if(identificacionDoc != null && (TipoIdentificacionDoc.CPF.equals(identificacionDoc) || TipoIdentificacionDoc.CNPJ.equals(identificacionDoc))) {
			cpfBpe = descnumdoc;
		}
		identificacionDoc = TipoIdentificacionDoc.getTipo(desctipodoc2);
		if(identificacionDoc != null && (TipoIdentificacionDoc.CPF.equals(identificacionDoc) || TipoIdentificacionDoc.CNPJ.equals(identificacionDoc))) {
			cpfBpe = descnumdoc2;
		}
		cpfBpe = cpfBpe == null ? "" : cpfBpe.trim().replaceAll("\\D", "");
		
		return cpfBpe;
	}

	private String carregarNumDoc(String descnumdoc, String descnumdoc2) {
		String lDescDoc = null;
		if(StringUtils.isNotBlank(descnumdoc)){
			lDescDoc = descnumdoc;
		}
		if(StringUtils.isBlank(lDescDoc)){
			lDescDoc = descnumdoc2;
		}
		return lDescDoc == null ? "" : lDescDoc.trim().replaceAll("\\D", "");
	}

	private String carregarDescTipoDoc(String desctipodoc, String desctipodoc2) {
		String lDescTipoDoc = null;
		if(StringUtils.isNotBlank(desctipodoc)){
			lDescTipoDoc = desctipodoc;
		}
		if(StringUtils.isBlank(lDescTipoDoc)) {
			lDescTipoDoc = desctipodoc2;
		}
		return lDescTipoDoc != null ? lDescTipoDoc.trim() : "";
	}	
}
