package com.rjconsultores.ventaboletos.rest.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.dao.ConstanteDAO;
import com.rjconsultores.ventaboletos.dao.DispositivoEmbarcadaDAO;
import com.rjconsultores.ventaboletos.dao.EmpresaDAO;
import com.rjconsultores.ventaboletos.dao.PuntoVentaDAO;
import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.entidad.CtrlSerieEmbarcada;
import com.rjconsultores.ventaboletos.entidad.DispositivoEmbarcada;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.EmpresaImposto;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.entidad.FormaPagoDet;
import com.rjconsultores.ventaboletos.entidad.InscricaoEstadual;
import com.rjconsultores.ventaboletos.entidad.PtoVtaSeguro;
import com.rjconsultores.ventaboletos.entidad.PtovtaCatInd;
import com.rjconsultores.ventaboletos.entidad.PtovtaEmpresa;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.rest.bean.ParamsSincronizarDispositivo;
import com.rjconsultores.ventaboletos.rest.service.exception.ServiceEmbarcadaException;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.vo.embarcada.DispositivoEmbarcadaVO;
import com.rjconsultores.ventaboletos.vo.embarcada.EmpresaVO;
import com.rjconsultores.ventaboletos.vo.embarcada.EstadoDispositivoEmbarcadaVO;
import com.rjconsultores.ventaboletos.vo.embarcada.FormaPagamentoVO;
import com.rjconsultores.ventaboletos.vo.embarcada.InscricaoEstadualVO;
import com.rjconsultores.ventaboletos.vo.embarcada.SeguroTaxaEmbarqueVO;
import com.rjconsultores.ventaboletos.vo.embarcada.TiposPassagensBloqueadasVO;
import com.rjconsultores.ventaboletos.web.utilerias.spring.AppContext;

@Service("sincronizarService")
public class SincronizarService {

	// @ReadOnlyConnection
	// Essa operação tem que ser realizada no banco de produção para não correr risco de sincronnia em relação ao número BPe
	public DispositivoEmbarcadaVO getDispositivoEmbarcada(ParamsSincronizarDispositivo params) throws ServiceEmbarcadaException {
		DispositivoEmbarcadaDAO dispositivoEmbarcadaDAO = (DispositivoEmbarcadaDAO)AppContext.getApplicationContext().getBean("dispositivoEmbarcadaDAO");
		EmpresaDAO empresaDAO = (EmpresaDAO)AppContext.getApplicationContext().getBean("empresaDAO");
		PuntoVentaDAO puntoVentaDAO = (PuntoVentaDAO)AppContext.getApplicationContext().getBean("puntoVentaDAO");
		DispositivoEmbarcada dispositivo = dispositivoEmbarcadaDAO.buscarImei(params.getImei());
		ConstanteDAO constanteDAO = (ConstanteDAO)AppContext.getApplicationContext().getBean("constanteDAO");
		
		if (dispositivo == null){
			DispositivoEmbarcadaVO dispositivoVo = new DispositivoEmbarcadaVO();
			dispositivoVo.setMsg("Dispositivo não encontrado");
			return dispositivoVo;
		}
		
		PuntoVenta puntoVenta = puntoVentaDAO.obtenerID(dispositivo.getPuntoVenta().getPuntoventaId().intValue());
		Empresa empresa = empresaDAO.obtenerID(dispositivo.getEmpresa().getEmpresaId().intValue());
		
		DispositivoEmbarcadaVO vo = new DispositivoEmbarcadaVO();
		vo.setDispositivoId(dispositivo.getDispositivoEmbarcadaId());
		vo.setBaixado(dispositivo.getIndDispBaixado() ? 1 : 0);
		vo.setBloqueado(dispositivo.getIndDispBloqueado() ? 1 : 0);
		vo.setDescAgencia(puntoVenta.getNombpuntoventa());
		vo.setNumagencia(puntoVenta.getNumPuntoVenta());
		vo.setDescEmpresa(empresa.getNombempresa());
		vo.setDescEquipamento(dispositivo.getDescricao());
		vo.setIdAgencia(dispositivo.getPuntoVenta().getPuntoventaId().longValue());
		vo.setIdempresa(dispositivo.getEmpresa().getEmpresaId().longValue());
		vo.setManutencao(dispositivo.getIndDispManutencao() ? 1 : 0);
		vo.setCnpjAgencia(puntoVenta.getNumDoCPuntoVenta());
		vo.setEnderecoAgencia(puntoVenta.getDireccioncalle()+", nº: "+puntoVenta.getDireccionnumero()+". Cidade: "+puntoVenta.getCidade());
		vo.setCnpjEmpresa(empresa.getCnpj());
		vo.setIndVendeNaoBpe(dispositivo.getIndVendeNaoBpe());
		vo.setVersaoUltimaSinc(dispositivo.getVersaoUltimaSinc());
		vo.setDataUltimaSinc( DateUtil.getStringDate( dispositivo.getDataUltimaSinc(), DateUtil.formatJson) );
		
		Map<Estado, EmpresaImposto> impostos = getImpostos(empresa);
		
		for (PtovtaEmpresa e : puntoVenta.getLsPtovtaEmpresa()){
			EmpresaVO emp = new EmpresaVO();
			emp.setEmpresaId(e.getEmpresa().getEmpresaId().longValue());
			emp.setNombempresa(e.getEmpresa().getNombempresa());
			emp.setCnpj(e.getEmpresa().getCnpj());
			emp.setIndImprimeRelFechamentoViagemDetalhadoEmarcada(e.getEmpresa().getIndImprimeRelFechamentoViagemDetalhadoEmarcada() != null ? e.getEmpresa().getIndImprimeRelFechamentoViagemDetalhadoEmarcada() : Boolean.FALSE);
			emp.setIndImprimeLogoBilheteVendaEmbarcada(e.getEmpresa().getIndImprimeLogoBilheteVendaEmbarcada() != null ? e.getEmpresa().getIndImprimeLogoBilheteVendaEmbarcada() : Boolean.FALSE);
			emp.setIndImpressaoCanhotoEmbarcada(e.getEmpresa().getIndImpressaoCanhotoEmbarcada() != null ? e.getEmpresa().getIndImpressaoCanhotoEmbarcada() : Boolean.FALSE);
			emp.setIndSegundaViaFechamentoCaixa(e.getEmpresa().getIndSegundaViaFechamentoCaixa() != null ? e.getEmpresa().getIndSegundaViaFechamentoCaixa() : Boolean.FALSE);
			
			vo.getEmpresasVenda().add(emp);
			for (InscricaoEstadual insc : e.getEmpresa().getInscricoesEstaduais()){
				EmpresaImposto imposto = impostos.get(insc.getEstado());
				InscricaoEstadualVO ie;
				if (insc.getActivo()){
					ie = new InscricaoEstadualVO(insc);
					if (imposto != null) {
						ie.setPorctributo(imposto.getPorctributo());
						ie.setTributacaoImportacao(imposto.getTributacaoImportacao());
						ie.setTributacaoImportacaoIM(imposto.getTributacaoImportacaoIM());
					}
					emp.getInscricoesEstaduais().add(ie);
				}
			}
			
		}
		vo.setEnderecoEmpresa(empresa.getLogradouro()+", nº: "+empresa.getNumero()+". Cidade: "+empresa.getBairro());
		Constante estacionEmbarcadaConst = constanteDAO.buscarPorNomeConstante(Constantes.ESTACAO_EMBARCADA);
		
		if (estacionEmbarcadaConst == null || (estacionEmbarcadaConst != null && estacionEmbarcadaConst.getValorconstante() == null) || 
				(estacionEmbarcadaConst != null && estacionEmbarcadaConst.getValorconstante().isEmpty())){
			throw new ServiceEmbarcadaException("Error: Constante ESTACAO_EMBARCADA não cadastrada!");
		}
		
		String estacionIdEmbarcada = estacionEmbarcadaConst.getValorconstante();
		vo.setEstacionId(estacionIdEmbarcada != null && !estacionIdEmbarcada.isEmpty() ? Integer.parseInt(estacionIdEmbarcada) : null);
				
		for (CtrlSerieEmbarcada serie : dispositivo.getSeries()){			
			EstadoDispositivoEmbarcadaVO estado = new EstadoDispositivoEmbarcadaVO();
			estado.setDescUf(serie.getEstado().getCveestado());
			estado.setIdUf(serie.getEstado().getEstadoId().longValue());
			estado.setNumBpe(serie.getNumeroCorrente());
			estado.setSerie(serie.getSerie());
			estado.setEmpresaId(serie.getEmpresa().getEmpresaId().longValue());
			vo.add(estado);
		}
	
		return vo;
	}
	
	public DispositivoEmbarcadaVO getDispositivoEmbarcadaResumido(ParamsSincronizarDispositivo params) throws ServiceEmbarcadaException {
		DispositivoEmbarcadaDAO dispositivoEmbarcadaDAO = (DispositivoEmbarcadaDAO)AppContext.getApplicationContext().getBean("dispositivoEmbarcadaDAO");
		PuntoVentaDAO puntoVentaDAO = (PuntoVentaDAO)AppContext.getApplicationContext().getBean("puntoVentaDAO");
		DispositivoEmbarcada dispositivo = dispositivoEmbarcadaDAO.buscarImei(params.getImei());
		
		DispositivoEmbarcadaVO vo = getDispositivoEmbarcada(params);
		PuntoVenta puntoVenta = puntoVentaDAO.obtenerID(dispositivo.getPuntoVenta().getPuntoventaId().intValue());
		
		vo.setLsFormasPagamento(new ArrayList<FormaPagamentoVO>());
		vo.setLsSeguroTaxaEmbarque(new ArrayList<SeguroTaxaEmbarqueVO>());
		vo.setLsTiposPassagensBloqueadas(new ArrayList<TiposPassagensBloqueadasVO>());
		
		for (PtovtaEmpresa e : puntoVenta.getLsPtovtaEmpresa()){
			List<FormaPagoDet> listFP = dispositivoEmbarcadaDAO.getListaFormaPago(e.getPuntoVenta().getPuntoventaId());
			
			for (FormaPagoDet dp : listFP) {
				vo.getLsFormasPagamento().add(
						new FormaPagamentoVO(
								dp.getEmpresa().getEmpresaId(),
								dp.getEmpresa().getNombempresa(), 
								dp.getFormaPago().getFormapagoId().intValue(), 
								dp.getFormaPago().getDescpago(), 
								dp.getFormaPago()!=null && dp.getFormaPago().getTipoFormapago()!=null ? dp.getFormaPago().getTipoFormapago().getDescricao() : null));
			}
			
			List<PtoVtaSeguro> listSTx = dispositivoEmbarcadaDAO.getListaSeguroTaxaEmbarque(e.getPuntoVenta().getPuntoventaId());
			
			for (PtoVtaSeguro st : listSTx) {
				vo.getLsSeguroTaxaEmbarque().add(
						new SeguroTaxaEmbarqueVO(
								st.getEmpresa().getEmpresaId(),
								st.getIndVendeSeguroOpcEmbarcada(),
								st.getIndVendeSeguroTabelaEmbarcada(),
								st.getIndTaxaEmbarqueEmbarcada()));
			}
			
			List<PtovtaCatInd> listTPB = dispositivoEmbarcadaDAO.getListaTiposPassagensBloqueadas(e.getPuntoVenta().getPuntoventaId());
			
			for (PtovtaCatInd tpb : listTPB) {
				vo.getLsTiposPassagensBloqueadas().add(
						new TiposPassagensBloqueadasVO(
								tpb.getCategoria().getCategoriaId(),
								tpb.getUsuarioBloqueado().getUsuarioId(),
								tpb.getEmpresa().getEmpresaId()));
			}
		}
	
		return vo;		
	}
	
	private Map<Estado, EmpresaImposto> getImpostos(Empresa e){
		Map<Estado, EmpresaImposto> result = new HashMap<Estado, EmpresaImposto>();
		
		for (EmpresaImposto ei : e.getEmpresaImpostoList()) {
			if (ei.getActivo()) {
				result.put(ei.getEstado(), ei);
			}
		}
		return result;
	}
}
