package com.rjconsultores.ventaboletos.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rjconsultores.ventaboletos.dao.AbastoCentralDAO;
import com.rjconsultores.ventaboletos.dao.AbastoHistoDAO;
import com.rjconsultores.ventaboletos.dao.CajaDAO;
import com.rjconsultores.ventaboletos.dao.PtovtaTipoEstoqueDAO;
import com.rjconsultores.ventaboletos.dao.PuntoVentaDAO;
import com.rjconsultores.ventaboletos.dao.TipoMovimentacionDAO;
import com.rjconsultores.ventaboletos.entidad.AbastoCentral;
import com.rjconsultores.ventaboletos.entidad.AbastoHisto;
import com.rjconsultores.ventaboletos.entidad.Aidf;
import com.rjconsultores.ventaboletos.entidad.Estacion;
import com.rjconsultores.ventaboletos.entidad.PtovtaTipoEstoque;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.entidad.TipoMovimentacion;
import com.rjconsultores.ventaboletos.service.AutorizaFolioService;
import com.rjconsultores.ventaboletos.service.MovimentacionBilhetesService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;

@Service("movimentacioBilhetesService")
public class MovimentacionBilhetesServiceImpl implements MovimentacionBilhetesService {

	@Autowired
	private AbastoCentralDAO abastoCentralDAO;
	
	@Autowired
	private AbastoHistoDAO abastoHistoDAO;
	
	@Autowired
	private TipoMovimentacionDAO tipoMovimentacionDAO;
	
	@Autowired
	private PuntoVentaDAO puntoVentaDAO;
	
	@Autowired
	private PtovtaTipoEstoqueDAO ptovtaTipoEstoqueDAO;
	
	@Autowired
	private CajaDAO cajaDAO;
	
	@Autowired
	private AutorizaFolioService autorizaFolioService;
	
	
	@Override
	public List<AbastoHisto> obtenerHistoricoMovimetacion(String numBilhete) {
		
		return null;
	}

	@Override
	public List<AbastoHisto> obtenerHistoricoMovimetacion(Aidf aidf) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<AbastoHisto> obtenerHistoricoMovimetacion(Aidf aidf, Date fecInicial, Date fecFinal) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Transactional
	public void realizaAdquisicionBilhetes(Aidf aidf){
		
		PuntoVenta suprimento = buscarAgSuprimento();
		
		long formInicial = Long.valueOf(aidf.getForminicial());
		long formFinal = Long.valueOf(aidf.getFormfinal());
		
		List<AbastoCentral> bilhetes = new ArrayList<AbastoCentral>();
		
		for(long formCorrente = formInicial; formCorrente <= formFinal; formCorrente++){		
			AbastoCentral nuevoBilhete = new AbastoCentral();
			nuevoBilhete.setAidf(aidf);
			nuevoBilhete.setNumfoliopreimpreso(formCorrente+"");
			nuevoBilhete.setNumseriepreimpresa(aidf.getSerie());
			nuevoBilhete.setNumsubseriepreimpreso(aidf.getSubserie());
			nuevoBilhete.setPuntoventa(suprimento);
			nuevoBilhete.setFecmodif(Calendar.getInstance().getTime());
			nuevoBilhete.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
			nuevoBilhete.setActivo(true);
			
			bilhetes.add(nuevoBilhete);
		}
		
		abastoCentralDAO.suscribirBilhetes(bilhetes);
		
		TipoMovimentacion adquisicion = tipoMovimentacionDAO.buscarTipoMovimentacio(TipoMovimentacion.TIPO_ADQUISICION);
		abastoHistoDAO.grabaHistoricoBilhetes(bilhetes, adquisicion);
		
	}
	
	@Transactional
	public void realizaMovimentacionBilhetes(Aidf aidf, PuntoVenta origem, PuntoVenta destino, TipoMovimentacion tipoMovimentacion) {
		
		if(validaTipoMovimentacao(tipoMovimentacion)){		
			List<AbastoCentral> bilhetes = abastoCentralDAO.obtenerBilhetes(aidf, origem);
			atualizaBilhetesEGrabaHistorico(bilhetes, destino, tipoMovimentacion);
		}
	}

	@Transactional
	public void realizaMovimentacionBilhetes(Aidf aidf, PuntoVenta origem, PuntoVenta destino, Long cantidad, TipoMovimentacion tipoMovimentacion) {

		if(validaTipoMovimentacao(tipoMovimentacion)){
			Long formInicial = Long.valueOf(aidf.getForminicial());
			Long formFinal = formInicial + cantidad.longValue(); 
			
			realizaMovimentacionBilhetes(aidf, origem, destino, formInicial.toString(), formFinal.toString(), tipoMovimentacion);
		
		}
	}
	
	@Transactional
	public void realizaMovimentacionBilhetes(Aidf aidf, PuntoVenta origem, PuntoVenta destino, String formInicial, String formFinal, TipoMovimentacion tipoMovimentacion) {
		
		if(validaTipoMovimentacao(tipoMovimentacion)){
			List<AbastoCentral> bilhetes = abastoCentralDAO.obtenerBilhetes(aidf, formInicial, formFinal, origem);
			atualizaBilhetesEGrabaHistorico(bilhetes, destino, tipoMovimentacion);
		}
	}

	private boolean validaTipoMovimentacao(TipoMovimentacion tipoMovimentacion){
		TipoMovimentacion adquisicion = tipoMovimentacionDAO.buscarTipoMovimentacio(TipoMovimentacion.TIPO_ADQUISICION);
		return !tipoMovimentacion.equals(adquisicion);
	}
	
	public List<TipoMovimentacion> obtenerTiposMovimetacion() {
		List<TipoMovimentacion> tiposMovimentacion = tipoMovimentacionDAO.obtenerTodos();
		return tiposMovimentacion;
	}
	
	public PuntoVenta buscarAgSuprimento() {
		PtovtaTipoEstoque tipoSuprimento = ptovtaTipoEstoqueDAO.buscarTipoSuprimento();		
		PuntoVenta suprimento = puntoVentaDAO.buscarPuntoVentaPorTipoEstoque(tipoSuprimento).get(0);
		
		return suprimento;
	}

	
	public PuntoVenta buscarAgContabilidade() {
		PtovtaTipoEstoque tipoContabilidade = ptovtaTipoEstoqueDAO.buscarTipoContabilidade();		
		PuntoVenta contabilidade = puntoVentaDAO.buscarPuntoVentaPorTipoEstoque(tipoContabilidade).get(0);
		
		return contabilidade;
	}

	public List<TipoMovimentacion> obtenerTiposMovimetacionPuntoVenta() {
		List<TipoMovimentacion> tipos = tipoMovimentacionDAO.obtenerTiposMovimetacionPuntoVenta();
		return tipos;
	}

	@Transactional
	public void realizaMovimentacionBilhetes(PuntoVenta puntoVentaBilhetes, Estacion origem, Estacion destino, String numSerie, String formInicial, String formFinal, TipoMovimentacion tipoMovimentacion) {
		
		List<AbastoCentral> bilhetes = abastoCentralDAO.obtenerBilhetesPorPuntoVenta(numSerie, formInicial, formFinal, puntoVentaBilhetes, origem);
		atualizaBilhetesEGrabaHistorico(bilhetes, destino, tipoMovimentacion);
		trataRequisicionBilhetesEstacion(bilhetes, origem, destino, formInicial, formFinal, tipoMovimentacion);	
	}
	
	private void trataRequisicionBilhetesEstacion(List<AbastoCentral> bilhetes, Estacion origem, Estacion destino, String numfolioinicial, String numfoliofinal, TipoMovimentacion tipoMovimentacion){
		
		Aidf aidfCorrente = null;
		
		for(AbastoCentral bilhete : bilhetes){
				
			if(aidfCorrente == null || (aidfCorrente != null && !aidfCorrente.equals(bilhete.getAidf()))){
				aidfCorrente = bilhete.getAidf();
				String numseriepreimpresa = aidfCorrente.getSerie();
				autorizaFolioService.noChequeFolioPreimpresos(aidfCorrente, origem, destino, numfolioinicial, numfoliofinal, numseriepreimpresa, aidfCorrente.getEmpresa(), tipoMovimentacion);
			}	
		}
	}
	
	private void atualizaBilhetesEGrabaHistorico(List<AbastoCentral> bilhetes, Estacion destino, TipoMovimentacion tipoMovimentacion){
		
		abastoCentralDAO.actualizaBilhetes(bilhetes, destino);
		abastoHistoDAO.grabaHistoricoBilhetes(bilhetes, tipoMovimentacion);
	}

	private void atualizaBilhetesEGrabaHistorico(List<AbastoCentral> bilhetes, PuntoVenta destino, TipoMovimentacion tipoMovimentacion){
		
		abastoCentralDAO.actualizaBilhetes(bilhetes, destino);
		abastoHistoDAO.grabaHistoricoBilhetes(bilhetes, tipoMovimentacion);
	}

	@Override
	public List<String> buscarSeriesBilhetesPorEstacion(Estacion estacion) {
		List<String> seriesEstacion = abastoCentralDAO.buscarSeriesBilhetesPorEstacion(estacion);
		return seriesEstacion;
	}

	@Override
	public String validarEstoqueUtilizado(Aidf aidf, String folioInicial, String folioFinal) {
		return cajaDAO.validarEstoqueUtilizado(aidf, folioInicial, folioFinal);
	}
	
}
