package com.rjconsultores.ventaboletos.service.impl;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rjconsultores.ventaboletos.dao.CtrlSerieBPeDAO;
import com.rjconsultores.ventaboletos.dao.CtrlSerieEmbarcadaDAO;
import com.rjconsultores.ventaboletos.entidad.CtrlSerieBPe;
import com.rjconsultores.ventaboletos.entidad.CtrlSerieEmbarcada;
import com.rjconsultores.ventaboletos.exception.SerieEmbarcadaNaoDisponivelException;
import com.rjconsultores.ventaboletos.service.ControleSerieEmbarcadaService;
import com.rjconsultores.ventaboletos.vo.embarcada.SerieEmbarcada;

@Service("controleSerieEmbarcadaService")
public class ControleSerieEmbarcadaServiceImpl implements ControleSerieEmbarcadaService {
	
	private static final Logger log = LogManager.getLogger(ControleSerieEmbarcadaServiceImpl.class);
	
	@Autowired
	private CtrlSerieEmbarcadaDAO ctrlSerieEmbarcadaDAO;

	@Autowired
	private CtrlSerieBPeDAO ctrlSerieBPeDAO;

	@Override
	@Transactional
	public SerieEmbarcada buscarSerieEmbarcada(CtrlSerieEmbarcada controleSerieEmbarcada) {
		SerieEmbarcada serieembarcada = null;
		
		log.info(String.format("BuscarSerieEmbarcada :: Empresa:%s Estado:%s" , controleSerieEmbarcada.getEmpresa().getEmpresaId(),controleSerieEmbarcada.getEstado()));
		
		// Verificando se há Serie Embarcada disponível para reaproveitamento
		int tentativas = 0;
		
		do {
			tentativas++;
			
			try {
				serieembarcada = ctrlSerieEmbarcadaDAO.buscarSerieEmbarcadaDisponivel(controleSerieEmbarcada.getEmpresa().getEmpresaId(), controleSerieEmbarcada.getEstado().getEstadoId());
			} catch (SerieEmbarcadaNaoDisponivelException e) {
				break;
			}
		
			if (tentativas >= 5) {
				break;
			}

		} while (serieembarcada == null);
		
		// Caso não haja reaproveitamento de série, devo buscar a próxima série disponível na sequncia padrão
		if (serieembarcada == null) {
			log.info("BuscarSerieEmbarcada :: Reaproveitamento nao disponivel");
			Integer serieVlmax, SerieEmbarcada, serieBpe, serie, serieBpeSeq; 
			CtrlSerieBPe ctrlSerieBpe = ctrlSerieBPeDAO.buscarPorEmpresaEstado(controleSerieEmbarcada.getEmpresa().getEmpresaId(), controleSerieEmbarcada.getEstado().getEstadoId());
			if( ctrlSerieBpe == null || ctrlSerieBpe.getSerie() == null ) {
				log.info(String.format("BuscarSerieEmbarcada :: Serie não encontrada para Empresa:%s Estado:%s" , controleSerieEmbarcada.getEmpresa().getEmpresaId(),controleSerieEmbarcada.getEstado()));
				throw new RuntimeException( String.format("Serie não encontrada para Empresa:%s Estado:%s" , controleSerieEmbarcada.getEmpresa().getEmpresaId(),controleSerieEmbarcada.getEstado()) );
			}
				
			serieBpe = Integer.valueOf(ctrlSerieBpe.getSerie());			
			SerieEmbarcada = ctrlSerieBPeDAO.buscarSerieEmb(controleSerieEmbarcada.getEmpresa().getEmpresaId(), controleSerieEmbarcada.getEstado().getEstadoId().toString());
			serieVlmax = (serieBpe < SerieEmbarcada ? SerieEmbarcada : serieBpe);
			serie = (serieVlmax == null ? 1 : serieVlmax + 1);

			log.info(String.format("BuscarSerieEmbarcada :: Serie em uso [%d]", serie));
			
			ctrlSerieBPeDAO.gerarSeqSerieBPe(controleSerieEmbarcada.getEmpresa().getEmpresaId(), controleSerieEmbarcada.getEstado().getCveestado(), serie);
			serieBpeSeq = ctrlSerieBPeDAO.buscarSequencia(controleSerieEmbarcada.getEmpresa().getEmpresaId(), controleSerieEmbarcada.getEstado().getCveestado());
			serie =  (serie <= serieBpeSeq ? serieBpeSeq : serie);
			
			log.info(String.format("BuscarSerieEmbarcada :: Serie selecionada [%d]", serie));
			
			serieembarcada = new SerieEmbarcada();
			serieembarcada.setSerie(serie.toString());
			serieembarcada.setNumero("0");
		}
		
		return serieembarcada;
	}
}
