package com.rjconsultores.ventaboletos.web.gui.controladores.esquemaoperacional;

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

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.zkoss.util.resource.Labels;
import org.zkoss.zhtml.Messagebox;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;

import com.rjconsultores.ventaboletos.entidad.CasetaPeaje;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.ParadaSecuencia;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.entidad.RutaCaseta;
import com.rjconsultores.ventaboletos.entidad.RutaSecuencia;
import com.rjconsultores.ventaboletos.entidad.Tramo;
import com.rjconsultores.ventaboletos.entidad.TramoServicio;
import com.rjconsultores.ventaboletos.entidad.Via;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.CasetaPeajeService;
import com.rjconsultores.ventaboletos.service.RutaCasetaService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.MyComboboxEstandar;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderCasetaPeaje;

@Controller("editarSecuenciaController")
@Scope("prototype")
public class EditarSecuenciaController extends MyGenericForwardComposer{
	
	private static final long serialVersionUID = 1L;
	private ParadaSecuencia paradaSeqOrigen;
	private ParadaSecuencia paradaSeqDestino;
	private String localidadeOrigen;
	private String localidadeDestino;
	private MyListbox casetaPeajeList;
	private List<CasetaPeaje> lsCasetaPeaje;
	private List<CasetaPeaje> lsSequenciasRemovidas;
	private List<CasetaPeaje> lsSequenciasIncluidas;
	
	private List<RutaSecuencia> lsRutaSecuencia;
	
	@Autowired
	private CasetaPeajeService casetaPeajeService;
	@Autowired
	private RutaCasetaService rutaCasetaService; 
	
	private MyComboboxEstandar cmbTodasCasetasPeaje;
	private List<CasetaPeaje> lsTodasCasetasPeaje;
	
	private List<ParadaSecuencia> lsParadasSequencia;
	private MyListbox rutaSecuenciaList;
	private static Logger log = LogManager.getLogger(EditarSecuenciaController.class);
	
	
	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		paradaSeqOrigen = (ParadaSecuencia) Executions.getCurrent().getArg().get("paradaSecuenciaOrigen");
		paradaSeqDestino = (ParadaSecuencia) Executions.getCurrent().getArg().get("paradaSecuenciaDestino");
		lsRutaSecuencia = (List<RutaSecuencia>)Executions.getCurrent().getArg().get("lsRutaSecuencia");
		
		lsParadasSequencia = (List<ParadaSecuencia>)Executions.getCurrent().getArg().get("lsParadasSequencia");
		rutaSecuenciaList = (MyListbox)Executions.getCurrent().getArg().get("rutaSecuenciaList");
		lsCasetaPeaje  = (List<CasetaPeaje>)Executions.getCurrent().getArg().get("casetasList");
		casetaPeajeList.setData(lsCasetaPeaje);
		
		getLocalidadeDestino();
		getLocalidadeOrigen();
		casetaPeajeList.setItemRenderer(new RenderCasetaPeaje());
//		lsCasetaPeaje = new ArrayList<CasetaPeaje>();
		
		lsTodasCasetasPeaje =  casetaPeajeService.buscarTodosOrdenadoPorDescricao();
		lsSequenciasRemovidas = new ArrayList<CasetaPeaje>();
		lsSequenciasIncluidas = new ArrayList<CasetaPeaje>();
	}


	public ParadaSecuencia getParadaSeqOrigen() {
		return paradaSeqOrigen;
	}


	public void setParadaSeqOrigen(ParadaSecuencia paradaSeq) {
		this.paradaSeqOrigen = paradaSeq;
	}

	public String getLocalidadeOrigen() {
		localidadeOrigen = paradaSeqOrigen.getParada().getCveparada()+" - "+paradaSeqOrigen.getParada().getDescparada();
		return localidadeOrigen;
	}


	public void setLocalidadeOrigen(String localidade) {
		this.localidadeOrigen = localidade;
	}


	public MyListbox getCasetaPeajeList() {
		return casetaPeajeList;
	}


	public void setCasetaPeajeList(MyListbox casetaPeajeList) {
		this.casetaPeajeList = casetaPeajeList;
	}


	public List<CasetaPeaje> getLsCasetaPeaje() {
		return lsCasetaPeaje;
	}


	public void setLsCasetaPeaje(List<CasetaPeaje> lsCasetaPeaje) {
		this.lsCasetaPeaje = lsCasetaPeaje;
	}
	
	
	
	public ParadaSecuencia getParadaSeqDestino() {
		return paradaSeqDestino;
	}


	public void setParadaSeqDestino(ParadaSecuencia paradaSeqDestino) {
		this.paradaSeqDestino = paradaSeqDestino;
	}


	public MyComboboxEstandar getCmbTodasCasetasPeaje() {
		return cmbTodasCasetasPeaje;
	}


	public void setCmbTodasCasetasPeaje(MyComboboxEstandar cmbTodasCasetasPeaje) {
		this.cmbTodasCasetasPeaje = cmbTodasCasetasPeaje;
	}


	public List<CasetaPeaje> getLsTodasCasetasPeaje() {
		return lsTodasCasetasPeaje;
	}


	public void setLsTodasCasetasPeaje(List<CasetaPeaje> lsTodasCasetasPeaje) {
		this.lsTodasCasetasPeaje = lsTodasCasetasPeaje;
	}


	public String getLocalidadeDestino() {
		localidadeDestino = paradaSeqDestino.getParada().getCveparada()+" - "+paradaSeqDestino.getParada().getDescparada();
		return localidadeDestino;
	}


	public void setLocalidadeDestino(String localidadeDestino) {
		this.localidadeDestino = localidadeDestino;
	}


	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void onClick$btnAdicionarCasetaPeaje(Event ev) throws InterruptedException {
		
		if (cmbTodasCasetasPeaje.getSelectedItem() == null){
			return;
		}
		
		CasetaPeaje cas = (CasetaPeaje) cmbTodasCasetasPeaje.getSelectedItem().getValue();
		
		if (casetaPeajeList.getListData().contains(cas)){
			 Messagebox.show(					 
					 Labels.getLabel("editarSecuenciaController.MSG.pracaCadastrada"),
	                 Labels.getLabel("editarSecuenciaController.window.title"),
	                 Messagebox.OK, Messagebox.INFORMATION);
			 
			 return;
		}
		
		lsSequenciasIncluidas.add(cas);
		casetaPeajeList.addItemNovo(cas);			
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void onClick$btnRemoverCasetaPeaje(Event ev) throws InterruptedException {
		CasetaPeaje cas = (CasetaPeaje)casetaPeajeList.getSelected();
		lsSequenciasRemovidas.add(cas);
		lsSequenciasIncluidas.remove(cas);
		
		casetaPeajeList.removeSelectedItem();				
	}
	
	public void onClick$btnSalvar(Event ev) throws InterruptedException {
		
		List<RutaCaseta> lsrc = new ArrayList<RutaCaseta>() ;
		
		for(int i = 0 ; i < lsSequenciasIncluidas.size() ; i ++){
			RutaCaseta rc = new RutaCaseta();
			RutaSecuencia rutaSecue = lsRutaSecuencia.get(paradaSeqOrigen.getSecuencia()-1);
			rc.setRutaSecuencia(rutaSecue);
			rc.setCasetaPeaje(lsSequenciasIncluidas.get(i));
			lsrc.add(rc);
		}
		
		for (CasetaPeaje casetaPeaje: lsSequenciasRemovidas){
			try {
				for (RutaSecuencia rutaSecuencia: casetaPeaje.getLsRutaSecuencia()){
					if (rutaSecuencia.getNumsecuencia() == (paradaSeqOrigen.getSecuencia()-1)){
						rutaCasetaService.deletarRutaCasetasFromRutaSecuenciaId(rutaSecuencia.getRutasecuenciaId());
						break;
					}
				}
			} catch (BusinessException e1) {
				log.error("Error ao salvar Caseta Peaje", e1);	
				return;
			}			
		}
				
		RutaSecuencia rutaSecue = lsRutaSecuencia.get(paradaSeqOrigen.getSecuencia()-1);
		
		for(RutaCaseta rc : lsrc){
			try {
				rutaCasetaService.suscribir(rc);		
				rutaSecue.getLsRutaCase().add(rc);
			} catch (BusinessException e) {
				log.error("Error ao salvar ruta secuencia", e);	
	            Messagebox.show(
	                    Labels.getLabel("MSG.Error"),
	                    Labels.getLabel("editarSecuenciaController.window.title"),
	                    Messagebox.OK, Messagebox.ERROR);
			}
		}
		 Messagebox.show(
                 Labels.getLabel("editarSecuenciaController.MSG.suscribirOK"),
                 Labels.getLabel("editarSecuenciaController.window.title"),
                 Messagebox.OK, Messagebox.INFORMATION);

		 lsParadasSequencia.clear();
			
			short numSecuencia = 0;
			for (int i = 0; i < lsRutaSecuencia.size(); i++) {
				RutaSecuencia rs = lsRutaSecuencia.get(i);
				Tramo tramo = rs.getTramo();
				List<RutaCaseta> lcas = rs.getLsRutaCase();
				Short numsecuencia = ++numSecuencia;			
				
				Via via = tramo.getVia();
				Parada paradaOrigem = tramo.getOrigem();
				
				if (paradaSeqOrigen.getSecuencia() == numsecuencia && !lsSequenciasRemovidas.isEmpty()){
					removerRutaCaseta(lcas);
				}
				
				addTramoPardaSecuencia(paradaOrigem, via, numsecuencia, lcas, getTempo(tramo.getTramoServicioList(), rs.getRuta()),tramo.getKmReal().toPlainString());					
				
				if (i == lsRutaSecuencia.size() - 1) {
					
					Parada paradaDestino = tramo.getDestino();
					Integer ultSecuencia = numsecuencia.intValue() + 1;
					addTramoPardaSecuencia(paradaDestino, via, ultSecuencia.shortValue());
				}
			}

			rutaSecuenciaList.setData(lsParadasSequencia);
		 
		 
		 closeWindow();
	}


	public List<RutaSecuencia> getLsRutaSecuencia() {
		return lsRutaSecuencia;
	}


	public void setLsRutaSecuencia(List<RutaSecuencia> lsRutaSecuencia) {
		this.lsRutaSecuencia = lsRutaSecuencia;
	}


	public RutaCasetaService getRutaCasetaService() {
		return rutaCasetaService;
	}


	public void setRutaCasetaService(RutaCasetaService rutaCasetaService) {
		this.rutaCasetaService = rutaCasetaService;
	}


	public List<ParadaSecuencia> getLsParadasSequencia() {
		return lsParadasSequencia;
	}


	public void setLsParadasSequencia(List<ParadaSecuencia> lsParadasSequencia) {
		this.lsParadasSequencia = lsParadasSequencia;
	}


	public MyListbox getRutaSecuenciaList() {
		return rutaSecuenciaList;
	}


	public void setRutaSecuenciaList(MyListbox rutaSecuenciaList) {
		this.rutaSecuenciaList = rutaSecuenciaList;
	}
	private void addTramoPardaSecuencia(Parada parada, Via via, Short numsecuencia) {
		ParadaSecuencia paradaSecuencia = new ParadaSecuencia();
		paradaSecuencia.setParada(parada);
		paradaSecuencia.setSecuencia(numsecuencia);
		paradaSecuencia.setVia(via);
		lsParadasSequencia.add(paradaSecuencia);
	}
		
	private void addTramoPardaSecuencia(Parada parada, Via via, Short numsecuencia, List<RutaCaseta> lCas, String tempo, String km) {
			ParadaSecuencia paradaSecuencia = new ParadaSecuencia();
			paradaSecuencia.setParada(parada);
			paradaSecuencia.setSecuencia(numsecuencia);
			paradaSecuencia.setVia(via);
			if (!lCas.isEmpty()){
				paradaSecuencia.setCasetas(lCas);				
			}
			paradaSecuencia.setKmReal(km);
			paradaSecuencia.setTempoReal(tempo);
			lsParadasSequencia.add(paradaSecuencia);		
	}
	
	private String getTempo(List<TramoServicio> lsTramoServicio, Ruta rutaTempo) {

		for (TramoServicio tramoServicio : lsTramoServicio) {

			if (tramoServicio.getClaseServicio().equals(rutaTempo.getClaseServicio())) {
				Calendar c = Calendar.getInstance();
				c.setTime(tramoServicio.getTiemporecorrido());

				Long tempo = DateUtil.getElapsedMinutos(DateUtil.getFecInicio().getTime(), c.getTime());
				long minutos = (tempo % 60);
				int horas = (tempo.intValue() / 60);

				String sMinutos = String.valueOf(minutos);
				return horas + ":" + ((sMinutos.length() < 2) ? "0" + sMinutos : sMinutos);
			}
		}

		return "";
	}
	
	private void removerRutaCaseta(List<RutaCaseta> lsRutaCaseta){
		List<RutaCaseta> rutaCasetasRemovidas = new ArrayList<RutaCaseta>();
		
		for (CasetaPeaje casetaPaje: lsSequenciasRemovidas){
			for (RutaCaseta rutaCaseta: lsRutaCaseta){
				if (rutaCaseta.getCasetaPeaje().getCasetaPeajeId() == casetaPaje.getCasetaPeajeId()){
					rutaCasetasRemovidas.add(rutaCaseta);
					break;
				}
			}
		}
		
		lsRutaCaseta.removeAll(rutaCasetasRemovidas);
	}
}
