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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
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.event.Event;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModelArray;
import org.zkoss.zul.Longbox;
import org.zkoss.zul.Textbox;

import com.rjconsultores.ventaboletos.entidad.AbastoBoleto;
import com.rjconsultores.ventaboletos.entidad.Aidf;
import com.rjconsultores.ventaboletos.entidad.DetAbastoBoleto;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.entidad.TipoMovimentacion;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.relatorios.impl.ReciboEntregaMovimentacao;
import com.rjconsultores.ventaboletos.service.AbastoBoletoService;
import com.rjconsultores.ventaboletos.service.AidfService;
import com.rjconsultores.ventaboletos.service.DetAbastoBoletoService;
import com.rjconsultores.ventaboletos.service.EstadoService;
import com.rjconsultores.ventaboletos.service.MovimentacionBilhetesService;
import com.rjconsultores.ventaboletos.utilerias.ApplicationProperties;
import com.rjconsultores.ventaboletos.utilerias.CustomEnum;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.MyComboboxPuntoVenta;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;

@Controller("movimentacionBilhetesController")
@Scope("prototype")
public class MovimentacionBilhetesController extends MyGenericForwardComposer {
	private static final String TITULO = "movimentacionBilhetesController.window.title";

	private static final long serialVersionUID = -5047032264890781980L;

	@Autowired
	private MovimentacionBilhetesService movimentacionBilhetesService;
	
	@Autowired
	private AidfService aidfService;
	
	@Autowired
	private AbastoBoletoService abastoBoletoService;
	
	@Autowired
	private DetAbastoBoletoService detAbastoService;
	
	@Autowired
	private DataSource dataSourceRead;
	
	@Autowired
	private EstadoService estadoService;
	
	private Combobox cmbAidf;
	private Combobox cmbEmpresa;
	private List<Aidf> lsAidf;
	
	private Combobox cmbTipoMovimentacion;
	private List<TipoMovimentacion> lsTipoMovimentacion;
	
	private Textbox txtForminicial;
	private Textbox txtFormfinal;	
	
	private Longbox txtCantidad;
	private List<PuntoVenta> lsPuntoVenta;
	private MyComboboxPuntoVenta cmbPuntoVentaOrigem;
	private MyComboboxPuntoVenta cmbPuntoVentaDestino;
	
	private Date fecmovimentacion;
	private Datebox dtbFecMovimentacion;
	
	private Label aidfEstado, aidfSerie, aidfSubserie;
	
	private List<Empresa> lsEmpresas;
	
	private boolean isEstoqueSimplificado;
	
	@Override
	public void doAfterCompose(Component comp) throws Exception {
		lsEmpresas = UsuarioLogado.getUsuarioLogado().getEmpresa();
		lsEmpresas.add(new Empresa(-1, "TODAS"));
		
		lsTipoMovimentacion = movimentacionBilhetesService.obtenerTiposMovimetacion();		
		isEstoqueSimplificado = ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.VALIDA_ESTOQUE_SIMPLIFICADO.getDescricao(), true) ;
		setLsPuntoVenta(new ArrayList<PuntoVenta>());
		fecmovimentacion = new Date();
		
		super.doAfterCompose(comp);
	}
	
	public void onClick$btnSalvar(Event ev) throws InterruptedException {
		
		cmbAidf.getValue();
		cmbPuntoVentaDestino.getValue();
		cmbPuntoVentaOrigem.getValue();
		
		try{
			
			Comboitem aidfSeleccionada = cmbAidf.getSelectedItem();			
			Aidf aidf = (Aidf)aidfSeleccionada.getValue();
			
			Comboitem origemSeleccionada = cmbPuntoVentaOrigem.getSelectedItem();
			PuntoVenta origem = origemSeleccionada != null ? (PuntoVenta)origemSeleccionada.getValue() : null;
			
			Comboitem destinoSeleccionado = cmbPuntoVentaDestino.getSelectedItem();
			PuntoVenta destino = (PuntoVenta)destinoSeleccionado.getValue();
			
			Comboitem tipoMovSeleccionado = cmbTipoMovimentacion.getSelectedItem();
			TipoMovimentacion tipoMovimentacion = (TipoMovimentacion)tipoMovSeleccionado.getValue();
			
			String folioInicial = txtForminicial.getValue();
			String folioFinal = txtFormfinal.getValue();
			
			Long cantidad = txtCantidad.getValue();
			
			String usado = validarEstoqueUtilizado(aidf, folioInicial, folioFinal);
			if( !usado.equals("0") ) {
				Messagebox.show(
						Labels.getLabel("movimentacionBilhetesController.MSG.usado")+usado,
						Labels.getLabel(TITULO),
						Messagebox.OK, Messagebox.ERROR);
				return ;
			}
			
			if(isEstoqueSimplificado && tipoMovimentacion.getTipomovimentacionId().equals(TipoMovimentacion.TIPO_TRANSFERENCIA)) {
				DetAbastoBoleto detAbasto = detAbastoService.buscarPorAidf(aidf.getAidfId(), origem.getPuntoventaId(), folioInicial, folioFinal);
				
				if(detAbasto == null) {
					throw new BusinessException("movimentacionBilhetesController.MSG.origemNaoEncontrada");
				}
				
				AbastoBoleto abastoNovo = abastoBoletoService.movimentaAbasto(detAbasto.getAbastoBoleto(), destino );
				
				abastoNovo = abastoBoletoService.suscribir(abastoNovo);
				
				DetAbastoBoleto detAbastoNovo = detAbastoService.movimentaDetAbasto(detAbasto, abastoNovo, folioInicial, folioFinal );
				detAbastoService.suscribir(detAbastoNovo);
				
				if( detAbastoNovo.getFolioFinal() < detAbasto.getFolioFinal() ) {
					DetAbastoBoleto detAbastoQuebra = detAbastoService.movimentaDetAbasto(
																			detAbasto, 
																			detAbasto.getAbastoBoleto(), 
																			getInicioFolioNovo(), 
																			detAbasto.getNumfoliofinal() );
					detAbastoService.suscribir(detAbastoQuebra);	
				}
				
				detAbasto.setNumfoliofinal(getFimFolioAntigo());
				detAbastoService.actualizacion(detAbasto);
			}else {
				if(StringUtils.isNotBlank(folioInicial) && StringUtils.isNotBlank(folioFinal) && cantidad == null)
					movimentacionBilhetesService.realizaMovimentacionBilhetes(aidf, origem, destino, folioInicial, folioFinal, tipoMovimentacion);
				else if(cantidad != null)
					movimentacionBilhetesService.realizaMovimentacionBilhetes(aidf, origem, destino, cantidad, tipoMovimentacion);
				else
					movimentacionBilhetesService.realizaMovimentacionBilhetes(aidf, origem, destino, tipoMovimentacion);
			}
						
			Messagebox.show(
					Labels.getLabel("movimentacionBilhetesController.MSG.suscribirOK"),
					Labels.getLabel(TITULO),
					Messagebox.OK, Messagebox.INFORMATION);
			
			if( tipoMovimentacion.getTipomovimentacionId().equals( TipoMovimentacion.TIPO_TRANSFERENCIA)) {
				int retorno = Messagebox.show(
						Labels.getLabel("movimentacionBilhetesController.MSG.imprimir"),
						Labels.getLabel(TITULO),
						Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);
				
				if( retorno == Messagebox.YES) {					
					Map<String, Object> parametros = new HashMap<String, Object>();
					
					Empresa empresa = (Empresa)cmbEmpresa.getSelectedItem().getValue();
					parametros.put("nombempresa", empresa.getNombempresa());
					parametros.put("usuario", UsuarioLogado.getUsuarioLogado().getClaveUsuario());
					parametros.put("agenciaDe", origem.getNombpuntoventa());
					parametros.put("agenciaPara", destino.getNombpuntoventa());
					
					parametros.put("serie", aidf.getSerie());
					parametros.put("aidf", aidf.toString());
					parametros.put("subserie", aidf.getSubserie());
					parametros.put("bilheteinicial", folioInicial);
					parametros.put("bilhetefinal", folioFinal);
					
					ReciboEntregaMovimentacao recibo = new ReciboEntregaMovimentacao(parametros , dataSourceRead.getConnection());
					
					Map<String, Object> args = new HashMap<String, Object>();
					args.put("relatorio", recibo);

					openWindow("/component/reportView.zul",
							Labels.getLabel("indexController.mnRelatorioRDI.label"), args, MODAL);
				}
			}
		
		} catch (BusinessException be) {
			Messagebox.show(
					be.getMessage(),
					Labels.getLabel(TITULO),
					Messagebox.OK, Messagebox.ERROR);			
		} catch (Exception ex) {	
			Messagebox.show(
					Labels.getLabel("MSG.Error"),
					Labels.getLabel(TITULO),
					Messagebox.OK, Messagebox.ERROR);
		}
		
	}

	public void onChange$cmbAidf(Event evt) throws InterruptedException {
		
		Comboitem aidfSeleccionada = cmbAidf.getSelectedItem();		
		Aidf aidf = (Aidf)aidfSeleccionada.getValue();
		
		getAidfEstado().setValue(aidf.getEstado().getNombestado());
		getAidfSerie().setValue(aidf.getSerie());
		getAidfSubserie().setValue(aidf.getSubserie());
	}
	
	public void onChange$cmbEmpresa(Event evt) throws InterruptedException {
		Comboitem empresaSelecionada = cmbEmpresa.getSelectedItem();
		Empresa empresa = (Empresa) empresaSelecionada.getValue();

		try{
			Comboitem origemSelecionada = cmbPuntoVentaOrigem.getSelectedItem();
			PuntoVenta origem = (PuntoVenta)origemSelecionada.getValue();			
			lsAidf = detAbastoService.buscarAidfsPorEmpresaAgencia(empresa, origem);
		}catch (Exception e) {
			lsAidf = aidfService.buscaAidfsPorEmpresas(empresa.getEmpresaId().equals(-1) ?  UsuarioLogado.getUsuarioLogado().getEmpresa() : Arrays.asList(empresa));
		}
		cmbAidf.setModel(new ListModelArray(lsAidf));
		
	}
	
	private String validarEstoqueUtilizado(Aidf aidf, String folioInicial, String folioFinal) {		
		return movimentacionBilhetesService.validarEstoqueUtilizado(aidf, folioInicial, folioFinal);
	}

	private String getFimFolioAntigo() {
		String folioInicial = txtForminicial.getValue();
		return String.valueOf( Long.valueOf(folioInicial)-1 );
	}
	
	private String getInicioFolioNovo() {
		String folio = txtFormfinal.getValue();
		return String.valueOf( Long.valueOf(folio)+1 );
	}
	
	public List<TipoMovimentacion> getLsTipoMovimentacion() {
		return lsTipoMovimentacion;
	}

	public void setLsTipoMovimentacion(List<TipoMovimentacion> lsTipoMovimentacion) {
		this.lsTipoMovimentacion = lsTipoMovimentacion;
	}

	public Combobox getCmbTipoMovimentacion() {
		return cmbTipoMovimentacion;
	}

	public void setCmbTipoMovimentacion(Combobox cmbTipoMovimentacion) {
		this.cmbTipoMovimentacion = cmbTipoMovimentacion;
	}

	public Longbox getTxtCantidad() {
		return txtCantidad;
	}

	public void setTxtCantidad(Longbox txtCantidad) {
		this.txtCantidad = txtCantidad;
	}

	public Label getAidfEstado() {
		return aidfEstado;
	}

	public void setAidfEstado(Label aidfEstado) {
		this.aidfEstado = aidfEstado;
	}

	public Label getAidfSerie() {
		return aidfSerie;
	}

	public void setAidfSerie(Label aidfSerie) {
		this.aidfSerie = aidfSerie;
	}

	public Label getAidfSubserie() {
		return aidfSubserie;
	}

	public void setAidfSubserie(Label aidfSubserie) {
		this.aidfSubserie = aidfSubserie;
	}

	public MyComboboxPuntoVenta getCmbPuntoVentaOrigem() {
		return cmbPuntoVentaOrigem;
	}

	public void setCmbPuntoVentaOrigem(MyComboboxPuntoVenta cmbPuntoVentaOrigem) {
		this.cmbPuntoVentaOrigem = cmbPuntoVentaOrigem;
	}

	public MyComboboxPuntoVenta getCmbPuntoVentaDestino() {
		return cmbPuntoVentaDestino;
	}

	public void setCmbPuntoVentaDestino(MyComboboxPuntoVenta cmbPuntoVentaDestino) {
		this.cmbPuntoVentaDestino = cmbPuntoVentaDestino;
	}

	public List<PuntoVenta> getLsPuntoVenta() {
		return lsPuntoVenta;
	}

	public void setLsPuntoVenta(List<PuntoVenta> lsPuntoVenta) {
		this.lsPuntoVenta = lsPuntoVenta;
	}
	
	public Textbox getTxtForminicial() {
		return txtForminicial;
	}

	public void setTxtForminicial(Textbox txtForminicial) {
		this.txtForminicial = txtForminicial;
	}

	public Textbox getTxtFormfinal() {
		return txtFormfinal;
	}

	public void setTxtFormfinal(Textbox txtFormfinal) {
		this.txtFormfinal = txtFormfinal;
	}
	
	public EstadoService getEstadoService() {
		return estadoService;
	}

	public void setEstadoService(EstadoService estadoService) {
		this.estadoService = estadoService;
	}

	public Combobox getCmbAidf() {
		return cmbAidf;
	}

	public void setCmbAidf(Combobox cmbAidf) {
		this.cmbAidf = cmbAidf;
	}

	public Combobox getCmbEmpresa() {
		return cmbEmpresa;
	}

	public void setCmbEmpresa(Combobox cmbEmpresa) {
		this.cmbEmpresa = cmbEmpresa;
	}
	
	public List<Empresa> getLsEmpresas() {
		return lsEmpresas;
	}

	public void setLsEmpresas(List<Empresa> lsEmpresas) {
		this.lsEmpresas = lsEmpresas;
	}

	public Datebox getDtbFecMovimentacion() {
		return dtbFecMovimentacion;
	}

	public void setDtbFecMovimentacion(Datebox dtbFecMovimentacion) {
		this.dtbFecMovimentacion = dtbFecMovimentacion;
	}
	
	public Date getFecmovimentacion() {
		return fecmovimentacion;
	}

	public void setFecmovimentacion(Date fecmovimentacion) {
		this.fecmovimentacion = fecmovimentacion;
	}
	
	
}
