package com.rjconsultores.ventaboletos.vo.busquedapacotes.transformer;

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

import org.hibernate.transform.ResultTransformer;

import com.rjconsultores.ventaboletos.enums.TipoFormapago;
import com.rjconsultores.ventaboletos.utilerias.OcdUtil;
import com.rjconsultores.ventaboletos.vo.busquedapacotes.NotaCreditoVendaPacoteVO;
import com.rjconsultores.ventaboletos.vo.busquedapacotes.OcdPacoteVO;
import com.rjconsultores.ventaboletos.vo.busquedapacotes.PagamentoVO;
import com.rjconsultores.ventaboletos.vo.caja.PagamentoCartaoVO;

public class DatosPagamentoResultTransformer implements ResultTransformer {

	private static final long serialVersionUID = 1L;

	@Override
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<PagamentoVO> transformList(List mapList) {
		Map<Long, PagamentoVO> pacotes = new HashMap<Long, PagamentoVO>();
		
		for(Object objmap : mapList ) {
			
			Map<String, Object> tupleMap = (Map<String, Object>) objmap;
			Long cajadiversospagoId = (Long) tupleMap.get("CAJADIVERSOSPAGO_ID");
			
			if(!pacotes.containsKey(cajadiversospagoId)){
				PagamentoVO pagamento = new PagamentoVO();
				setDatosPacote(pagamento, tupleMap);
				if(pagamento.getValor().signum() >= 0) { 
					pacotes.put(cajadiversospagoId, pagamento);
				}
			}
		}
				
		List<PagamentoVO> pacotesList = new ArrayList<PagamentoVO>();
		pacotesList.addAll(pacotes.values());
		Collections.sort(pacotesList, new Comparator<PagamentoVO>() {
			@Override
			public int compare(PagamentoVO o1, PagamentoVO o2) {
				return o1.getVendapacoteId().compareTo(o2.getVendapacoteId());
			}
		});
		
		return pacotesList;
	}

	@Override
	public Object transformTuple(Object[] data, String[] aliases) {
		Map<String,Object> row = new HashMap<String,Object>();
		
		for(int index = 0; index < aliases.length; index++){
			row.put(aliases[index], data[index]);
		}
		
		return row;
	}
	
	private void setDatosPacote(PagamentoVO pagamento, Map<String, Object> tupleMap) {
		pagamento.setMoeda("R$");
		pagamento.setVendapacoteId((Long) tupleMap.get("VENDAPACOTE_ID"));
		pagamento.setFormapagoId((Integer) tupleMap.get("FORMAPAGO_ID"));
		pagamento.setFormapagamento((String) tupleMap.get("DESCPAGO"));
		pagamento.setValor((BigDecimal) tupleMap.get("VALOR"));
		
		Integer tipoPago = (Integer) tupleMap.get("TIPO_PAGO");
		pagamento.setTipoFormapago(TipoFormapago.getTipoFormapagoByValor(tipoPago));
		
		if(isVentaCartaoCredito(pagamento.getTipoFormapago()) || isVentaCartaoDebito(pagamento.getTipoFormapago())) {
			PagamentoCartaoVO cartao = new PagamentoCartaoVO();
			cartao.setBandeira((String) tupleMap.get("TIPOTARJETA"));
			cartao.setNumautorizacao((String) tupleMap.get("NUMAUTORIZACION"));
			cartao.setParcelas((Integer) tupleMap.get("CANTPARCELAS"));
			cartao.setTitular((String) tupleMap.get("NOMBTITULAR"));
			cartao.setDatapagamento((Date) tupleMap.get("FECOPERACION"));
			cartao.setNumcartao((String) tupleMap.get("NUMTARJETA"));
			cartao.setNumcartao((String) tupleMap.get("NUMTARJETA"));
			cartao.setOperadoracartao((String) tupleMap.get("DESCOPERADORACARTAO"));
			
			pagamento.setCartao(cartao);
		}
		
		if(isVentaNotaCredito(pagamento.getTipoFormapago())) {
			if(tupleMap.get("NOTACREDITOVENDAPACOTE_ID") != null) {
				NotaCreditoVendaPacoteVO notacredito = new NotaCreditoVendaPacoteVO();
				notacredito.setVouchernotacredito(((Long) tupleMap.get("NOTACREDITOVENDAPACOTE_ID")).toString());
				notacredito.setNumoperacaopacotecancelamento((String) tupleMap.get("NUMOPERACAOPACOTECANCELAMENTO"));
				pagamento.setNotacredito(notacredito);
			}
			
			if(tupleMap.get("OCD_ID") != null) {
				String voucherocd = OcdUtil.generaLocalizadorOCD((String) tupleMap.get("NUMOPERACION_OCD"), (Long) tupleMap.get("OCD_ID"));
				OcdPacoteVO ocdPacote = new OcdPacoteVO();
				ocdPacote.setVoucherocd(voucherocd);
				pagamento.setOcd(ocdPacote);
			}
		}
		
	}
	
	private boolean isVentaCartaoCredito(TipoFormapago tipoFormapago) {
		return TipoFormapago.CREDITO.equals(tipoFormapago);
	}
	
	private boolean isVentaCartaoDebito(TipoFormapago tipoFormapago) {
		return TipoFormapago.DEBITO.equals(tipoFormapago);
	}
	
	private boolean isVentaNotaCredito(TipoFormapago tipoFormapago) {
		return TipoFormapago.NOTA_CREDITO.equals(tipoFormapago);
	}

}
