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

import java.util.ArrayList;
import java.util.Arrays;
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 org.zkoss.zul.Combobox;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Row;
import org.zkoss.zul.Spinner;
import org.zkoss.zul.Textbox;

import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.dao.ConstanteDAO;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.Corrida;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.entidad.Usuario;
import com.rjconsultores.ventaboletos.enums.StatusFlexBus;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.IndStatusCorrida;
import com.rjconsultores.ventaboletos.service.ClaseServicioService;
import com.rjconsultores.ventaboletos.service.CorridaService;
import com.rjconsultores.ventaboletos.service.RutaService;
import com.rjconsultores.ventaboletos.service.UsuarioService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;

/**
 * @author Valdir Cordeiro
 *
 */
@Controller("editarCorridaFlexBusController")
@Scope("prototype")
public class EditarCorridaFlexBusController  extends MyGenericForwardComposer {

	private static final long serialVersionUID = 1L;
	
	private static Logger log = LogManager.getLogger(EditarCorridaFlexBusController.class);
	
	@Autowired
	private BuqueCorridaFlexBusController busqueCorridaFlexBusController;
	
	@Autowired
	private ClaseServicioService claseService;
	
	@Autowired
	private RutaService rutaService;
	
	@Autowired
	private CorridaService corridaService;
	
	@Autowired
	private UsuarioService usuarioService;
	
	private Corrida corrida;
	private MyListbox corridaList;
	
	private Spinner txtHorasParaConfirmacao;
	private Spinner txtMinutosParaConfirmacao;
	private Intbox txtOcupacaoMinima;
	private Intbox txtOcupacaoAtual;

	private List<StatusFlexBus> lsStatus;
	private List<IndStatusCorrida> lsStatusCorrida;
	private List<ClaseServicio> lsClase;
	private List<Ruta> lsRuta;
	private List<Empresa> lsEmpresa;
	
	private Combobox cmbMarca;
	private Combobox cmbRuta;
	private Combobox cmbEmpresaCorrida;
	private Combobox cmbStatus;
	private Combobox cmbStatusCorrida;
	private Combobox cmbClase;
	private Intbox txtNumCorrida;
	private Textbox txtInfoCorrida;
	
	private StatusFlexBus statusAtual;
	private IndStatusCorrida statusCorrida;
	
	private Row rowUsuario;
	private Textbox txtUsuarioAlteracao;
	@Autowired
	private ConstanteDAO constanteDAO;
	
	private String titulo = Labels.getLabel("editarConfiguracionCorridaController.window.title");
	
	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		txtNumCorrida.setMaxlength(Boolean.valueOf(constanteDAO.buscarPorNomeConstante(Constantes.NUM_VIAJE_9_DIGITOS).getValorconstante()) ? 9 : 7);
		
		corrida = (Corrida) Executions.getCurrent().getArg().get("corrida");
		corridaList = (MyListbox) Executions.getCurrent().getArg().get("corridaList");
		busqueCorridaFlexBusController = (BuqueCorridaFlexBusController) Executions.getCurrent().getArg().get("busqueCorridaFlexBusController");

		lsStatus = Arrays.asList(StatusFlexBus.values());
		lsStatusCorrida = Arrays.asList(IndStatusCorrida.values());
		lsClase = new ArrayList<ClaseServicio>();
		lsClase.add(corrida.getClaseServicio());
		lsRuta = new ArrayList<Ruta>();
		lsRuta.add(corrida.getRuta());
		lsEmpresa = new ArrayList<Empresa>();
		lsEmpresa.addAll(UsuarioLogado.getUsuarioLogado().getEmpresa());
		
		txtHorasParaConfirmacao.setValue(corrida.getHorasParaConfirmacao());
		txtMinutosParaConfirmacao.setValue(corrida.getMinutosParaConfirmacao());
		txtOcupacaoMinima.setValue(corrida.getOcupacaoMinima());
		
		statusAtual = StatusFlexBus.buscarPorStatus(corrida.getStatusFlexBus());
		statusCorrida = IndStatusCorrida.buscarPorStatus(corrida.getIndstatuscorrida());
		
		cmbStatus.setValue(statusAtual.getDescricao());
		cmbStatusCorrida.setValue(statusCorrida.toString());
		
		//Não e possível editar se o status for diferente de EM RESERVA
		if(!statusAtual.equals(StatusFlexBus.EM_RESERVA)) {
			txtHorasParaConfirmacao.setDisabled(false);
			txtMinutosParaConfirmacao.setDisabled(false);
			txtOcupacaoMinima.setDisabled(false);
		}
		
		txtOcupacaoAtual.setValue(corridaService.buscarOcupacaoCorrida(corrida));
		
		if((statusAtual.equals(StatusFlexBus.CANCELADO_MANUALMENTE) || statusAtual.equals(StatusFlexBus.CONFIRMADO_MANUALMENTE) ) && corrida.getUsuarioFlexBusId() != null) {
			rowUsuario.setVisible(true);
			Usuario usuario = usuarioService.obtenerID(corrida.getUsuarioFlexBusId());
			
			txtUsuarioAlteracao.setValue(usuario.getUsuarioId() + " - " + usuario.getNombusuario());
		} else {
			rowUsuario.setVisible(false);
		}
	}
	
	public void onClick$btnSalvar(Event ev) throws InterruptedException {
		try {
			if(!statusAtual.equals(StatusFlexBus.EM_RESERVA)) {
				Messagebox.show(Labels.getLabel("MSG.Error.soReservaFlexBus"), titulo, Messagebox.OK, Messagebox.ERROR);
				return;
			}
			
			if(Calendar.getInstance().getTime().after(corrida.getFechorsalida())) {
				Messagebox.show(Labels.getLabel("MSG.Error.dataSaidaFlexBus"), titulo, Messagebox.OK, Messagebox.ERROR);
				return;
			}
			
			if((txtHorasParaConfirmacao.getValue() == null || txtMinutosParaConfirmacao.getValue() == null || txtOcupacaoMinima.getValue() == null)) {
				Messagebox.show(Labels.getLabel("editarConfiguracionCorridaController.inserirInformacoesFlexBus"), titulo, Messagebox.OK, Messagebox.EXCLAMATION);
				return;
			}
			
			corrida.setHorasParaConfirmacao(txtHorasParaConfirmacao.getValue());
			corrida.setMinutosParaConfirmacao(txtMinutosParaConfirmacao.getValue());
			corrida.setOcupacaoMinima(txtOcupacaoMinima.getValue());
			
			corridaService.actualizacion(corrida);
			corridaList.updateItem(corrida);

			Messagebox.show(Labels.getLabel("editarConfiguracionCorridaController.corridaAlteradaSucesso.value"), titulo, Messagebox.OK, Messagebox.INFORMATION);
			closeWindow();
		} catch (Exception e) {
			log.error("Erro ao salvar informacoes da corrida: ", e);
			Messagebox.show(Labels.getLabel("MSG.Error"), titulo, Messagebox.OK, Messagebox.ERROR);
		}
	}
	
	public void onClick$btnCancelarServico(Event ev) throws InterruptedException {
		try {
			int resp = Messagebox.show(Labels.getLabel("editarConfiguracionCorridaController.MSG.desejaCancelarCorrida"), titulo, Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

			if (resp == Messagebox.NO) {
				return;
			}
			
			if(!validarAlteracao()) {
				return;
			}
			
			corrida.setStatusFlexBus(StatusFlexBus.CANCELADO_MANUALMENTE.getStatus());
			corrida.setIndstatuscorrida(IndStatusCorrida.CANCELADO.getValue());
			corrida.setUsuarioFlexBusId(UsuarioLogado.getUsuarioLogado().getUsuarioId());

			corridaService.actualizacion(corrida);
			corridaList.updateItem(corrida);

			Messagebox.show(Labels.getLabel("editarConfiguracionCorridaController.corridaAlteradaSucesso.value"), titulo, Messagebox.OK, Messagebox.INFORMATION);
			closeWindow();
		} catch (Exception e) {
			log.error("Erro ao Cancelar corrida: ", e);
			Messagebox.show(Labels.getLabel("MSG.Error"), titulo, Messagebox.OK, Messagebox.ERROR);
		}
	}
	
	public void onClick$btnConfirmarServico(Event ev) throws InterruptedException {
		try {
			int resp = Messagebox.show(Labels.getLabel("editarConfiguracionCorridaController.MSG.desejaConfirmarCorrida"), titulo, Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

			if (resp == Messagebox.NO) {
				return;
			}
			
			if(!validarAlteracao()) {
				return;
			}
			
			corrida.setStatusFlexBus(StatusFlexBus.CONFIRMADO_MANUALMENTE.getStatus());
			corrida.setUsuarioFlexBusId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
			
			corridaService.actualizacion(corrida);
			corridaList.updateItem(corrida);
			

			Messagebox.show(Labels.getLabel("editarConfiguracionCorridaController.corridaAlteradaSucesso.value"), titulo, Messagebox.OK, Messagebox.INFORMATION);
			closeWindow();
		} catch (Exception e) {
			log.error("Erro ao Confirmar corrida: ", e);
			Messagebox.show(Labels.getLabel("MSG.Error"), titulo, Messagebox.OK, Messagebox.ERROR);
		}
	}
	
	private Boolean validarAlteracao() throws InterruptedException {
		if(StatusFlexBus.CONFIRMADO_AUTOMATICAMENTE.equals(statusAtual) || StatusFlexBus.CONFIRMADO_MANUALMENTE.equals(statusAtual)) {
			Messagebox.show(Labels.getLabel("MSG.Error.corridaConfirmada"), titulo, Messagebox.OK, Messagebox.ERROR);
			return false;
		}
		
		if(StatusFlexBus.CANCELADO_AUTOMATICAMENTE.equals(statusAtual) || StatusFlexBus.CANCELADO_MANUALMENTE.equals(statusAtual)) {
			Messagebox.show(Labels.getLabel("MSG.Error.corridaCancelada"), titulo, Messagebox.OK, Messagebox.ERROR);
			return false;
		}
		
		if(Calendar.getInstance().getTime().after(corrida.getFechorsalida())) {
			Messagebox.show(Labels.getLabel("MSG.Error.dataSaidaFlexBus"), titulo, Messagebox.OK, Messagebox.ERROR);
			return false;
		}
		
		return true;
	}

	public List<Empresa> getLsEmpresa() {
		return lsEmpresa;
	}

	public void setLsEmpresa(List<Empresa> lsEmpresa) {
		this.lsEmpresa = lsEmpresa;
	}

	public BuqueCorridaFlexBusController getBusqueCorridaFlexBusController() {
		return busqueCorridaFlexBusController;
	}

	public void setBusqueCorridaFlexBusController(BuqueCorridaFlexBusController busqueCorridaFlexBusController) {
		this.busqueCorridaFlexBusController = busqueCorridaFlexBusController;
	}

	public ClaseServicioService getClaseService() {
		return claseService;
	}

	public void setClaseService(ClaseServicioService claseService) {
		this.claseService = claseService;
	}

	public RutaService getRutaService() {
		return rutaService;
	}

	public void setRutaService(RutaService rutaService) {
		this.rutaService = rutaService;
	}

	public Corrida getCorrida() {
		return corrida;
	}

	public void setCorrida(Corrida corrida) {
		this.corrida = corrida;
	}

	public MyListbox getCorridaList() {
		return corridaList;
	}

	public void setCorridaList(MyListbox corridaList) {
		this.corridaList = corridaList;
	}

	public Spinner getTxtHorasParaConfirmacao() {
		return txtHorasParaConfirmacao;
	}

	public void setTxtHorasParaConfirmacao(Spinner txtHorasParaConfirmacao) {
		this.txtHorasParaConfirmacao = txtHorasParaConfirmacao;
	}

	public Spinner getTxtMinutosParaConfirmacao() {
		return txtMinutosParaConfirmacao;
	}

	public void setTxtMinutosParaConfirmacao(Spinner txtMinutosParaConfirmacao) {
		this.txtMinutosParaConfirmacao = txtMinutosParaConfirmacao;
	}

	public Intbox getTxtOcupacaoMinima() {
		return txtOcupacaoMinima;
	}

	public void setTxtOcupacaoMinima(Intbox txtOcupacaoMinima) {
		this.txtOcupacaoMinima = txtOcupacaoMinima;
	}

	public List<StatusFlexBus> getLsStatus() {
		return lsStatus;
	}

	public void setLsStatus(List<StatusFlexBus> lsStatus) {
		this.lsStatus = lsStatus;
	}

	public List<ClaseServicio> getLsClase() {
		return lsClase;
	}

	public void setLsClase(List<ClaseServicio> lsClase) {
		this.lsClase = lsClase;
	}

	public List<Ruta> getLsRuta() {
		return lsRuta;
	}

	public void setLsRuta(List<Ruta> lsRuta) {
		this.lsRuta = lsRuta;
	}

	public Combobox getCmbMarca() {
		return cmbMarca;
	}

	public void setCmbMarca(Combobox cmbMarca) {
		this.cmbMarca = cmbMarca;
	}

	public Combobox getCmbRuta() {
		return cmbRuta;
	}

	public void setCmbRuta(Combobox cmbRuta) {
		this.cmbRuta = cmbRuta;
	}

	public Combobox getCmbEmpresaCorrida() {
		return cmbEmpresaCorrida;
	}

	public void setCmbEmpresaCorrida(Combobox cmbEmpresaCorrida) {
		this.cmbEmpresaCorrida = cmbEmpresaCorrida;
	}

	public Combobox getCmbStatus() {
		return cmbStatus;
	}

	public void setCmbStatus(Combobox cmbStatus) {
		this.cmbStatus = cmbStatus;
	}

	public Combobox getCmbClase() {
		return cmbClase;
	}

	public void setCmbClase(Combobox cmbClase) {
		this.cmbClase = cmbClase;
	}

	public Intbox getTxtNumCorrida() {
		return txtNumCorrida;
	}

	public void setTxtNumCorrida(Intbox txtNumCorrida) {
		this.txtNumCorrida = txtNumCorrida;
	}

	public Textbox getTxtInfoCorrida() {
		return txtInfoCorrida;
	}

	public void setTxtInfoCorrida(Textbox txtInfoCorrida) {
		this.txtInfoCorrida = txtInfoCorrida;
	}

	public List<IndStatusCorrida> getLsStatusCorrida() {
		return lsStatusCorrida;
	}

	public void setLsStatusCorrida(List<IndStatusCorrida> lsStatusCorrida) {
		this.lsStatusCorrida = lsStatusCorrida;
	}

	public IndStatusCorrida getStatusCorrida() {
		return statusCorrida;
	}

	public void setStatusCorrida(IndStatusCorrida statusCorrida) {
		this.statusCorrida = statusCorrida;
	}

	public StatusFlexBus getStatusAtual() {
		return statusAtual;
	}

	public void setStatusAtual(StatusFlexBus statusAtual) {
		this.statusAtual = statusAtual;
	}
}
