package br.com.centralit.citcorpore.ajaxForms;

import java.sql.Date;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import br.com.centralit.citajax.html.AjaxFormAction;
import br.com.centralit.citajax.html.DocumentHTML;
import br.com.centralit.citcorpore.bean.CentroResultadoDTO;
import br.com.centralit.citcorpore.bean.CidadesDTO;
import br.com.centralit.citcorpore.bean.DadosBancariosIntegranteDTO;
import br.com.centralit.citcorpore.bean.IntegranteViagemDTO;
import br.com.centralit.citcorpore.bean.JustificativaSolicitacaoDTO;
import br.com.centralit.citcorpore.bean.ProjetoDTO;
import br.com.centralit.citcorpore.bean.RequisicaoViagemDTO;
import br.com.centralit.citcorpore.bean.RoteiroViagemDTO;
import br.com.centralit.citcorpore.bean.TipoMovimFinanceiraViagemDTO;
import br.com.centralit.citcorpore.bean.UsuarioDTO;
import br.com.centralit.citcorpore.negocio.CentroResultadoService;
import br.com.centralit.citcorpore.negocio.CidadesService;
import br.com.centralit.citcorpore.negocio.DadosBancariosIntegranteService;
import br.com.centralit.citcorpore.negocio.DespesaViagemService;
import br.com.centralit.citcorpore.negocio.IntegranteViagemService;
import br.com.centralit.citcorpore.negocio.JustificativaSolicitacaoService;
import br.com.centralit.citcorpore.negocio.ProjetoService;
import br.com.centralit.citcorpore.negocio.RequisicaoViagemService;
import br.com.centralit.citcorpore.negocio.RoteiroViagemService;
import br.com.centralit.citcorpore.negocio.TipoMovimFinanceiraViagemService;
import br.com.centralit.citcorpore.util.CITCorporeUtil;
import br.com.centralit.citcorpore.util.LogoRel;
import br.com.centralit.citcorpore.util.WebUtil;
import br.com.citframework.excecao.ServiceException;
import br.com.citframework.service.ServiceLocator;
import br.com.citframework.util.Constantes;
import br.com.citframework.util.UtilI18N;


@SuppressWarnings({"rawtypes","unchecked"})
public class RelatorioAdiantamento extends AjaxFormAction {

	private UsuarioDTO usuario;

	@Override
	public void load(DocumentHTML document, HttpServletRequest request, HttpServletResponse response) throws Exception {
		if(!WebUtil.validarSeUsuarioEstaNaSessao(request, document))
			return;
	}

	@Override
	public Class getBeanClass() {
		return IntegranteViagemDTO.class;
	}

	/**
	 * Busca integrantes de viagem que precisam de adiantamento
	 *
	 * @param document
	 * @param request
	 * @param response
	 * @throws Exception
	 * @author thiago.borges
	 */
	public void pesquisaRequisicoesViagem(DocumentHTML document, HttpServletRequest request, HttpServletResponse response) throws Exception {
			document.executeScript("JANELA_AGUARDE_MENU.show()");

	        IntegranteViagemDTO integranteViagemDTO = (IntegranteViagemDTO) document.getBean();
	        IntegranteViagemService integranteViagemService = (IntegranteViagemService) ServiceLocator.getInstance().getService(IntegranteViagemService.class, WebUtil.getUsuarioSistema(request));
	        RequisicaoViagemDTO requisicaoViagemDTO = new RequisicaoViagemDTO();
	        RequisicaoViagemService requisicaoViagemService = (RequisicaoViagemService) ServiceLocator.getInstance().getService(RequisicaoViagemService.class, WebUtil.getUsuarioSistema(request));
	        RoteiroViagemDTO roteiroViagemDTO = new RoteiroViagemDTO();
	        RoteiroViagemService roteiroViagemService = (RoteiroViagemService) ServiceLocator.getInstance().getService(RoteiroViagemService.class, WebUtil.getUsuarioSistema(request));
	        DadosBancariosIntegranteDTO dadosBancariosIntegranteDTO = new DadosBancariosIntegranteDTO();
	        DadosBancariosIntegranteService dadosBancariosIntegranteService = (DadosBancariosIntegranteService) ServiceLocator.getInstance().getService(DadosBancariosIntegranteService.class, WebUtil.getUsuarioSistema(request));
	        TipoMovimFinanceiraViagemDTO tipoMovimFinanceiraViagemDTO = new TipoMovimFinanceiraViagemDTO();
	        TipoMovimFinanceiraViagemService tipoMovimFinanceiraViagemService = (TipoMovimFinanceiraViagemService) ServiceLocator.getInstance().getService(TipoMovimFinanceiraViagemService.class, WebUtil.getUsuarioSistema(request));
	        DespesaViagemService despesaViagemService = (DespesaViagemService) ServiceLocator.getInstance().getService(DespesaViagemService.class, WebUtil.getUsuarioSistema(request));
	        JustificativaSolicitacaoService justificativaSolicitacaoService = (JustificativaSolicitacaoService) ServiceLocator.getInstance().getService(JustificativaSolicitacaoService.class, WebUtil.getUsuarioSistema(request));
	        JustificativaSolicitacaoDTO justificativaSolicitacaoDTO = new JustificativaSolicitacaoDTO();
	        CentroResultadoService centroResultadoService = (CentroResultadoService) ServiceLocator.getInstance().getService(CentroResultadoService.class, WebUtil.getUsuarioSistema(request));
	        CentroResultadoDTO centroResultadoDTO = new CentroResultadoDTO();
	        ProjetoService projetoService = (ProjetoService) ServiceLocator.getInstance().getService(ProjetoService.class, WebUtil.getUsuarioSistema(request));
	        ProjetoDTO projetoDTO = new ProjetoDTO();

	        tipoMovimFinanceiraViagemDTO = tipoMovimFinanceiraViagemService.buscaDiaria();

	        NumberFormat nf = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
			DecimalFormat decimal = (DecimalFormat) nf;
			decimal.applyPattern("#,##0.00");

	        UsuarioDTO usuario = WebUtil.getUsuario(request);
	        if (usuario == null) {
	            document.alert(UtilI18N.internacionaliza(request, "citcorpore.comum.sessaoExpirada"));
	            document.executeScript("window.location = '" + Constantes.getValue("SERVER_ADDRESS") + request.getContextPath() + "'");
	            return;
	        }

	        Double totalAdiantamentos = 0d;
	        Double totaisAdiantamentos = 0d;

	        //metodo que recupera a coleção dos itens da pagina referenciada
	        Collection<IntegranteViagemDTO> colIntegrantes = integranteViagemService.recuperaIntegrantesAdiantamento(integranteViagemDTO, integranteViagemDTO.getEOu());
	        CidadesService cidadesService = (CidadesService)ServiceLocator.getInstance().getService(CidadesService.class, null);
	        CidadesDTO cidadesDTO = new CidadesDTO();

	        Collection<IntegranteViagemDTO> colIntegrantesAux = new ArrayList<IntegranteViagemDTO>();

	        if(colIntegrantes != null && !colIntegrantes.isEmpty()){
		        for(IntegranteViagemDTO dto: colIntegrantes){
		        	dto = (IntegranteViagemDTO) integranteViagemService.restore(dto);
		        	roteiroViagemDTO = roteiroViagemService.findByIdIntegrante(dto.getIdIntegranteViagem());
		        	requisicaoViagemDTO = requisicaoViagemService.recuperaRequisicaoPelaSolicitacao(dto.getIdSolicitacaoServico());
		        	justificativaSolicitacaoDTO.setIdJustificativa(requisicaoViagemDTO.getIdMotivoViagem());
		        	justificativaSolicitacaoDTO = justificativaSolicitacaoService.restore(justificativaSolicitacaoDTO);
		        	centroResultadoDTO.setIdCentroResultado(requisicaoViagemDTO.getIdCentroCusto());
		        	centroResultadoDTO = centroResultadoService.restore(centroResultadoDTO);
		        	projetoDTO.setIdProjeto(requisicaoViagemDTO.getIdProjeto());
		        	projetoDTO = projetoService.restore(projetoDTO);

		        	cidadesDTO = cidadesService.findCidadeUF(roteiroViagemDTO.getOrigem());
		        	dto.setNomeOrigem(cidadesDTO.getNomeCidade()+ " - " + cidadesDTO.getNomeUf());
		        	cidadesDTO = cidadesService.findCidadeUF(roteiroViagemDTO.getDestino());
		        	dto.setNomeDestino(cidadesDTO.getNomeCidade()+ " - " + cidadesDTO.getNomeUf());
		        	dto.setIda(roteiroViagemDTO.getIda());
		        	dto.setVolta(roteiroViagemDTO.getVolta());
		        	dto.setQtdDiarias(this.calculaDiarias(roteiroViagemDTO.getIda(), roteiroViagemDTO.getVolta()));

		        	Double totalAdiantamentoIntegranteAtual = 0d;
		        	if(despesaViagemService.possuiDiaria(dto.getIdIntegranteViagem())){
		        		totalAdiantamentoIntegranteAtual += (tipoMovimFinanceiraViagemDTO.getValorPadrao()*dto.getQtdDiarias() + despesaViagemService.getTotalDespesaExtraViagem(dto.getIdIntegranteViagem()));
		        		dto.setValorAdiantamento(decimal.format(tipoMovimFinanceiraViagemDTO.getValorPadrao()));

		        		// De acordo com o item 4.3a do PO-009 deve ser acrescida uma diaria adicional.
		        		totalAdiantamentoIntegranteAtual += tipoMovimFinanceiraViagemDTO.getValorPadrao();

		        		dto.setValorTotalAdiantamento(decimal.format(totalAdiantamentoIntegranteAtual));
		        	} else {
		        		totalAdiantamentoIntegranteAtual = despesaViagemService.getTotalDespesaExtraViagem(dto.getIdIntegranteViagem());
		        		dto.setValorAdiantamento(decimal.format(0.0));
		        		dto.setValorTotalAdiantamento(decimal.format(despesaViagemService.getTotalDespesaExtraViagem(dto.getIdIntegranteViagem())));
		        	}

		        	// Verificar se o integrante tem adiantamento para ser feito
		        	if(totalAdiantamentoIntegranteAtual > 0) {
		        		totalAdiantamentos = totalAdiantamentoIntegranteAtual;
		        		totaisAdiantamentos += totalAdiantamentos;

		        		dto.setValorDespesaExtra(decimal.format(despesaViagemService.getTotalDespesaExtraViagem(dto.getIdIntegranteViagem())));

			        	dadosBancariosIntegranteDTO = dadosBancariosIntegranteService.findByIdIntegrante(dto.getIdIntegranteViagem());
			        	if(dadosBancariosIntegranteDTO != null){
			        		dto.setConta(dadosBancariosIntegranteDTO.getConta());
			        		dto.setAgencia(dadosBancariosIntegranteDTO.getAgencia());
			        		dto.setOperacao(dadosBancariosIntegranteDTO.getOperacao());
			        		dto.setCpf(dadosBancariosIntegranteDTO.getCpf());
			        		dto.setBanco(dadosBancariosIntegranteDTO.getBanco());
			        	}

			        	dto.setJustificativa(justificativaSolicitacaoDTO.getDescricaoJustificativa());
			        	dto.setCentroCusto(centroResultadoDTO.getCodigoCentroResultado());
			        	dto.setProjeto(projetoDTO.getNomeProjeto());
			        	colIntegrantesAux.add(dto);
		        	}
		        }

		        if(!colIntegrantesAux.isEmpty()) {
		        	this.imprimirRelatorio(document, request, response, colIntegrantesAux, decimal.format(totaisAdiantamentos));
		        } else {
		        	document.alert(UtilI18N.internacionaliza(request, "relatorioAdiantamento.naoHaItensParaGerarRelatorio"));
			    	document.executeScript("JANELA_AGUARDE_MENU.hide()");
			    	return;
		        }
	       }else{
	    	   document.alert(UtilI18N.internacionaliza(request, "citcorpore.comum.resultado"));
	    	   document.executeScript("JANELA_AGUARDE_MENU.hide()");
	    	   return;
	       }
	}

	public Integer calculaDiarias(Date ida, Date volta) throws Exception{
		int qtdDiarias = 0;
		if(ida != null &&  volta != null){

			GregorianCalendar ini = new GregorianCalendar();
			GregorianCalendar fim = new GregorianCalendar();
			SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd");
			ini.setTime(sdf.parse(ida.toString()));
			fim.setTime(sdf.parse(volta.toString()));
			long dt1 = ini.getTimeInMillis();
			long dt2 = fim.getTimeInMillis();
			qtdDiarias = (int) ((((dt2 - dt1) / 86400000)+1));
		}

		return qtdDiarias;
	}

	public void imprimirRelatorio(DocumentHTML document, HttpServletRequest request, HttpServletResponse response, Collection<IntegranteViagemDTO> integrantes, String total) throws ServiceException, Exception {

		Map<String, Object> parametros = new HashMap<String, Object>();

		parametros.put("Logo", LogoRel.getFile());

		parametros.put("totalAdiantamentos", total);

		String caminhoJasper = CITCorporeUtil.CAMINHO_REAL_APP + Constantes.getValue("CAMINHO_RELATORIOS") + "RelatorioAdiantamento.jasper";

		String diretorioReceita = CITCorporeUtil.CAMINHO_REAL_APP + "/tempFiles";

		String diretorioRelativoOS = Constantes.getValue("SERVER_ADDRESS") + Constantes.getValue("CONTEXTO_APLICACAO") + "/tempFiles";

		JRDataSource dataSource = new JRBeanCollectionDataSource(integrantes, false);

		JasperPrint print = JasperFillManager.fillReport(caminhoJasper, parametros, dataSource);

		JasperExportManager.exportReportToPdfFile(print, diretorioReceita + "/RelatorioAdiantamento.pdf");

		document.executeScript("window.open('" + Constantes.getValue("SERVER_ADDRESS") + Constantes.getValue("CONTEXTO_APLICACAO") + "/printPDF/printPDF.jsp?url=" + diretorioRelativoOS
				+ "/RelatorioAdiantamento.pdf')");

		document.executeScript("JANELA_AGUARDE_MENU.hide()");
	}

}