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

import java.math.BigDecimal;
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.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.zkoss.util.resource.Labels;
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.Datebox;
import org.zkoss.zul.Decimalbox;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Paging;
import org.zkoss.zul.Textbox;

import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.ExcecaoGrupoContrato;
import com.rjconsultores.ventaboletos.entidad.GrupoContrato;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.TarifaGrupoContrato;
import com.rjconsultores.ventaboletos.service.ClaseServicioService;
import com.rjconsultores.ventaboletos.service.GrupoContratoService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;
import com.rjconsultores.ventaboletos.web.utilerias.paginacion.PagedListWrapper;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderExcecaoGrupoContrato;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderTarifaGrupoContrato;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Controller("editarGrupoContratoController")
@Scope("prototype")
public class EditarGrupoContratoController extends MyGenericForwardComposer {

	private static final String TITULO = "editarGrupoContratoController.window.title";
	private static final long serialVersionUID = 1L;
	@Autowired
	private transient PagedListWrapper<TarifaGrupoContrato> plwpagingTarifaGrupo;
	@Autowired
	private GrupoContratoService grupoContratoService;
	@Autowired
	private ClaseServicioService claseServicioService;
	
	private Paging pagingTarifaGrupo;
	
	private GrupoContrato grupoContrato;
	private MyListbox grupoContratoList;
	
	private MyListbox tarifaGrupoList;	
	private List<TarifaGrupoContrato> lsTarifaGrupo;
	private List<TarifaGrupoContrato> lsTarifaGrupoBanco = new ArrayList<>();
	
	private MyListbox tarifaNaoCobertaList;	
	private List<TarifaGrupoContrato> lsTarifaNaoCoberta;
	
	private MyListbox excecaoGrupoList;	
	private List<ExcecaoGrupoContrato> lsExcecaoGrupo;
	private List<ExcecaoGrupoContrato> lsExcecaoGrupoBanco = new ArrayList<>();
	
	private List<ClaseServicio> lsClasse;
	
	//Grupo
	private Textbox txtDescricao;
	
	//Tarifas
	private Combobox cmbOrigem;
	private Combobox cmbClasse;
	private Combobox cmbDestino;
	private Decimalbox txtTarifa;
	
	//Tarifas Nao Coberta
	private Combobox cmbOrigemNaoCoberta;
	private Combobox cmbClasseNaoCoberta;
	private Combobox cmbDestinoNaoCoberta;
	private Decimalbox txtTarifaNaoCoberta;
	
	//Excecoes
	private Datebox datInicial;
	private Datebox datFinal;
	private Combobox cmbOrigemExcecao;
	private Combobox cmbClasseExcecao;
	private Combobox cmbDestinoExcecao;
	private Decimalbox txtTarifaExcecao;

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		
		setLsClasse(claseServicioService.buscarTodosExceto(0));
		
		super.doAfterCompose(comp);
		
		grupoContrato = (GrupoContrato) Executions.getCurrent().getArg().get("grupoContrato");
		grupoContratoList = (MyListbox) Executions.getCurrent().getArg().get("grupoContratoList");
		
		tarifaGrupoList.setItemRenderer(new RenderTarifaGrupoContrato());
		tarifaNaoCobertaList.setItemRenderer(new RenderTarifaGrupoContrato());
		excecaoGrupoList.setItemRenderer(new RenderExcecaoGrupoContrato());
		
		lsTarifaGrupo = new ArrayList<TarifaGrupoContrato>();
		lsTarifaNaoCoberta = new ArrayList<TarifaGrupoContrato>();
		lsExcecaoGrupo = new ArrayList<ExcecaoGrupoContrato>();
				
		if (!isRegistroNovo(grupoContrato.getGrupoContratoId())) {
			grupoContrato = grupoContratoService.obtenerID(grupoContrato.getGrupoContratoId());
			lsExcecaoGrupo = grupoContrato.getExcecoesGrupoContrato();
			processaTarifas();
			
			tarifaGrupoList.setData(lsTarifaGrupo);
			tarifaNaoCobertaList.setData(lsTarifaNaoCoberta);
			excecaoGrupoList.setData(lsExcecaoGrupo);
		}
	}

	private void processaTarifas() {
		for (TarifaGrupoContrato item: grupoContrato.getTarifasGrupoContrato()) {
			if( item.isIndCobertura()) {
				lsTarifaGrupo.add(item);
			}else{
				lsTarifaNaoCoberta.add(item);
			}
		}
	}

	public void onClick$btnSalvar(Event ev) throws InterruptedException {
		try {
            if (isRegistroNovo(grupoContrato.getGrupoContratoId())) {
            	List<GrupoContrato> lsGrupoContratos = grupoContratoService.buscar(grupoContrato.getNomeGrupoContrato());

                if (!lsGrupoContratos.isEmpty()) {
                    Messagebox.show(
                            Labels.getLabel("MSG.Registro.Existe"),
                            Labels.getLabel(TITULO),
                            Messagebox.OK, Messagebox.EXCLAMATION);
                    return;
                }
                grupoContratoService.suscribir(grupoContrato);
                grupoContratoList.addItemNovo(grupoContrato);
            } else {
                grupoContratoService.actualizacion(grupoContrato);
                grupoContratoList.updateItem(grupoContrato);
            }
            
            gravarTarifasGrupoContrato();
            gravarExcecoesGrupoContrato();

            Messagebox.show(
                    Labels.getLabel("MSG.suscribirOK"),
                    Labels.getLabel(TITULO),
                    Messagebox.OK, Messagebox.INFORMATION);

            closeWindow();            
				
		} catch (Exception ex) {
			Messagebox.show(
						Labels.getLabel("MSG.Error"),
						Labels.getLabel(TITULO),
						Messagebox.OK, Messagebox.ERROR);
		}
	}

	public void onClick$btnApagar(Event ev) throws InterruptedException {
		Integer resp = Messagebox.show(
					Labels.getLabel("MSG.borrarPergunta"),
					Labels.getLabel(TITULO),
					Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

		if (resp == Messagebox.YES) {

			grupoContratoService.borrar(grupoContrato);

			Messagebox.show(
						Labels.getLabel("MSG.borrarOK"),
						Labels.getLabel(TITULO),
						Messagebox.OK, Messagebox.INFORMATION);

			grupoContratoList.removeItem(grupoContrato);

			closeWindow();
		}
	}
	
	public void onClick$btnAdicionarTarifa(Event ev) throws InterruptedException {
		ClaseServicio classe = (ClaseServicio) cmbClasse.getSelectedItem().getValue(); 
		Parada origem = (Parada) cmbOrigem.getSelectedItem().getValue();
		Parada destino = (Parada) cmbDestino.getSelectedItem().getValue();
		BigDecimal valorTarifa = txtTarifa.getValue();
		addTarifaGrupoContrato(classe, origem, destino, valorTarifa, true);
	}
	
	public void onClick$btnAdicionarTarifaNaoCoberta(Event ev) throws InterruptedException {
		ClaseServicio classe = (ClaseServicio) cmbClasseNaoCoberta.getSelectedItem().getValue(); 
		Parada origem = (Parada) cmbOrigemNaoCoberta.getSelectedItem().getValue();
		Parada destino = (Parada) cmbDestinoNaoCoberta.getSelectedItem().getValue();
		BigDecimal valorTarifa = txtTarifaNaoCoberta.getValue();
		addTarifaGrupoContrato(classe, origem, destino, valorTarifa, false);
	}
	
	private void addTarifaGrupoContrato(ClaseServicio classe, Parada origem, Parada destino, BigDecimal valorTarifa, boolean cobertura) throws InterruptedException {				
		TarifaGrupoContrato tarifa = new TarifaGrupoContrato();
		tarifa.setClaseServicio(classe);
		tarifa.setOrigem(origem);
		tarifa.setDestino(destino);
		tarifa.setGrupoContrato(grupoContrato);
		tarifa.setIndCobertura(cobertura);
		tarifa.setTarifa(valorTarifa);
		tarifa.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		tarifa.setFecModif(Calendar.getInstance().getTime());
		tarifa.setActivo(true);
		
		if( validaExisteTarifa(tarifa)) {		
			Messagebox.show(
	                Labels.getLabel("editarGrupoContratoController.MSG.tarifaExiste"),
	                Labels.getLabel(TITULO),
	                Messagebox.OK, Messagebox.INFORMATION);
			return;
		}
		
		lsTarifaGrupoBanco.add(tarifa);
		
		if (cobertura) {
			lsTarifaGrupo.add(tarifa);
			tarifaGrupoList.setData(lsTarifaGrupo);
		}else {
			lsTarifaNaoCoberta.add(tarifa);			
			tarifaNaoCobertaList.setData(lsTarifaNaoCoberta);
		}
	}
	
	public void onClick$btnRemoverTarifa(Event ev) {
		TarifaGrupoContrato tarifa = (TarifaGrupoContrato) tarifaGrupoList.getSelected();
		if(tarifa != null) {
			lsTarifaGrupo.remove(tarifa);
			tarifaGrupoList.setData(lsTarifaGrupo);
			
			if( tarifa.getTarifaGrupoContratoId() != null ) {
				tarifa.setActivo(false);
				tarifa.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				tarifa.setFecModif(Calendar.getInstance().getTime());
				lsTarifaGrupoBanco.add(tarifa);
			}else {				
				lsTarifaGrupoBanco.remove(lsTarifaGrupoBanco.indexOf(tarifa));
			}
		}
	}
	
	public void onClick$btnRemoverTarifaNaoCoberta(Event ev) {
		TarifaGrupoContrato tarifa = (TarifaGrupoContrato) tarifaNaoCobertaList.getSelected();
		if(tarifa != null) {
			lsTarifaNaoCoberta.remove(tarifa);
			tarifaNaoCobertaList.setData(lsTarifaNaoCoberta);
			
			if( tarifa.getTarifaGrupoContratoId() != null ) {
				tarifa.setActivo(false);
				tarifa.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				tarifa.setFecModif(Calendar.getInstance().getTime());
				lsTarifaGrupoBanco.add(tarifa);
			}else {				
				lsTarifaGrupoBanco.remove(lsTarifaGrupoBanco.indexOf(tarifa));
			}
		}
	}
	
	private void gravarTarifasGrupoContrato() {
		grupoContratoService.gravarTarifasGrupoContrato(lsTarifaGrupoBanco);
		grupoContrato.setTarifasGrupoContrato(lsTarifaGrupo);
	}
	
	public void onClick$btnAdicionarExcecao(Event ev) throws InterruptedException {
		Date dataInicial = datInicial.getValue();
		Date dataFinal = datFinal.getValue();
		ClaseServicio classe = (ClaseServicio) cmbClasseExcecao.getSelectedItem().getValue();
		Parada origem = (Parada) cmbOrigemExcecao.getSelectedItem().getValue();
		Parada destino = (Parada) cmbDestinoExcecao.getSelectedItem().getValue();
		BigDecimal valorTarifa = txtTarifaExcecao.getValue();
		addExcecaoGrupoContrato(dataInicial, dataFinal, classe, origem, destino, valorTarifa);
	}	
	
	private void addExcecaoGrupoContrato(
			Date dataInicial, 
			Date dataFinal, 
			ClaseServicio classe, 
			Parada origem, 
			Parada destino, 
			BigDecimal valorTarifa) throws InterruptedException {
		
		ExcecaoGrupoContrato excecao = new ExcecaoGrupoContrato();
		excecao.setDataInicial(dataInicial);
		excecao.setDataFinal(dataFinal);
		excecao.setClaseServicio(classe);
		excecao.setOrigem(origem);
		excecao.setDestino(destino);
		excecao.setGrupoContrato(grupoContrato);
		excecao.setTarifa(valorTarifa);
		excecao.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		excecao.setFecModif(Calendar.getInstance().getTime());
		excecao.setActivo(true);
		
		if( validaExisteExcecao(excecao)) {		
			Messagebox.show(
	                Labels.getLabel("editarGrupoContratoController.MSG.excecaoExiste"),
	                Labels.getLabel(TITULO),
	                Messagebox.OK, Messagebox.INFORMATION);
			return;
		}
		
		lsExcecaoGrupo.add(excecao);
		lsExcecaoGrupoBanco.add(excecao);
		excecaoGrupoList.setData(lsExcecaoGrupo);
	}

	public void onClick$btnRemoverExcecao(Event ev) {
		ExcecaoGrupoContrato excecao = (ExcecaoGrupoContrato) excecaoGrupoList.getSelected();
		if(excecao != null) {
			lsExcecaoGrupo.remove(excecao);
			excecaoGrupoList.setData(lsExcecaoGrupo);
			
			if( excecao.getExcecaoGrupoContratoId() != null ) {
				excecao.setActivo(false);
				excecao.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				excecao.setFecModif(Calendar.getInstance().getTime());
				lsExcecaoGrupoBanco.add(excecao);
			}else {				
				lsExcecaoGrupoBanco.remove(lsExcecaoGrupoBanco.indexOf(excecao));
			}
		}
	}
	
	private void gravarExcecoesGrupoContrato() {
		grupoContratoService.gravarExcecoesGrupoContrato(lsExcecaoGrupoBanco);
		grupoContrato.setExcecoesGrupoContrato(lsExcecaoGrupo);
	}
	
	private boolean validaExisteTarifa(TarifaGrupoContrato tarifa) {
		for (TarifaGrupoContrato item : lsTarifaGrupo) {
			if( item.getClaseServicio().equals(tarifa.getClaseServicio()) 
					&& item.getOrigem().equals(tarifa.getOrigem()) 
					&& item.getDestino().equals(tarifa.getDestino()) ) {
				return true;
			}
		}
		return false;
	}
	
	private boolean validaExisteExcecao(ExcecaoGrupoContrato excecao) {
		for (ExcecaoGrupoContrato item : lsExcecaoGrupo) {
			if( item.getDataInicial().equals(excecao.getDataInicial())
					&& item.getDataFinal().equals(excecao.getDataFinal()) 
					&& item.getClaseServicio().equals(excecao.getClaseServicio()) 
					&& item.getOrigem().equals(excecao.getOrigem()) 
					&& item.getDestino().equals(excecao.getDestino()) ) {
				return true;
			}
		}
		return false;
	}
	
}
