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

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

import javax.sql.DataSource;

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.event.Event;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Paging;

import com.rjconsultores.ventaboletos.entidad.Cliente;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.relatorios.impl.RelatorioHistoricoCompras;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.PagedListCliente;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.PagedListGenerico;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.PagedListPuntoVenta;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.ValidarDatas;
import com.rjconsultores.ventaboletos.service.RutaService;
import com.rjconsultores.ventaboletos.vo.ruta.RutaVO;
import com.rjconsultores.ventaboletos.web.utilerias.MensagensUtils;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;
import com.rjconsultores.ventaboletos.web.utilerias.MyTextbox;
import com.rjconsultores.ventaboletos.web.utilerias.paginacion.PagedListWrapper;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderPersonalizado;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRelatorioVendasBilheteiro;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRelatorioVendasBilheteiroSelecionados;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRutaPersonalizado;

@Controller("relatorioHistoricoComprasController")
@Scope("prototype")
public class RelatorioHistoricoComprasController extends MyGenericForwardComposer {
	
	private static final String MSG_DATA_INICIAL_EMBARQUE_MAIOR_FINAL = "relatorioHistoricoComprasController.MSG.dataInicialEmbarqueMaiorFinal";
	private static final String MSG_DATA_INICIAL_VENDA_MAIOR_FINAL = "relatorioHistoricoComprasController.MSG.dataInicialVendaMaiorFinal";
	private static final String MSG_PERIODO_VENDA_INCOMPLETO = "relatorioHistoricoComprasController.MSG.informarDataVenda";
	private static final String MSG_PERIODO_EMBARQUE_INCOMPLETO = "relatorioHistoricoComprasController.MSG.informarDataEmbarque";
	private static final String TITULO_RELATORIO = "relatorioHistoricoComprasController.window.title";
	private static final String MSG_FILTRO_SEM_PERIODO = "relatorioHistoricoComprasController.MSG.informarFiltroData";

	private static final long serialVersionUID = 1L;
	
	private Datebox dtVendaInicial;
	private Datebox dtVendaFinal;
	private Datebox dtEmbarqueInicial;
	private Datebox dtEmbarqueFinal;
	
	private MyTextbox txtNombrePuntoVenta;
	private MyListbox puntoVentaList;
	private MyListbox puntoVentaSelList;
	private Paging pagingPuntoVenta;
	
	private MyListbox linhaList;
	private MyListbox linhaSelList;
	private MyTextbox txtPalavraPesquisaLinha;
	
	private MyListbox cpfList;
	private MyListbox cpfSelList;
	private MyTextbox txtCpfPesquisa;
	private Paging pagingCpfCliente;
	
	@Autowired
	private transient PagedListWrapper<PuntoVenta> pagedListPuntoVenta;
	@Autowired
	private transient PagedListWrapper<Cliente> pagedListCliente;
	@Autowired
	private RutaService rutaService;
	@Autowired
	private DataSource dataSource;

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);

		configuraRenders();
	}

	private void configuraRenders() {
		puntoVentaList.setItemRenderer(new RenderRelatorioVendasBilheteiro());
		puntoVentaSelList.setItemRenderer(new RenderRelatorioVendasBilheteiroSelecionados());
		
		List<String> colunasLinhaRender = Arrays.asList("numRuta", "prefixo", "descruta");
		linhaList.setItemRenderer(new RenderRutaPersonalizado(colunasLinhaRender));
		linhaSelList.setItemRenderer(new RenderRutaPersonalizado(colunasLinhaRender).comBotaoExcluir());
		
		List<String> colunasClienteRender = Arrays.asList("numIdentificaUno", "nombcliente");
		cpfList.setItemRenderer(new RenderPersonalizado<Cliente>(colunasClienteRender));
		cpfSelList.setItemRenderer(new RenderPersonalizado<Cliente>(colunasClienteRender).comBotaoExcluir());
	}

	public void onClick$btnPesquisaPuntoVenta(Event ev) throws Exception {
		PagedListPuntoVenta pageList = new PagedListPuntoVenta(puntoVentaList, txtNombrePuntoVenta, pagingPuntoVenta);
		pageList.buscarDadosPagedList(pagedListPuntoVenta);
		
		pageList.validarPagedListSemRegistro(TITULO_RELATORIO);
	}
	
	public void onClick$btnLimpar(Event ev) {
		PagedListGenerico.limparPesquisaListBox(puntoVentaList, txtNombrePuntoVenta);
	}

	public void onDoubleClick$puntoVentaSelList(Event ev) {
		puntoVentaSelList.removeItem((PuntoVenta) puntoVentaSelList.getSelected());
	}

	public void onDoubleClick$puntoVentaList(Event ev) {
		PagedListGenerico.validarInclusaoLista((PuntoVenta) puntoVentaList.getSelected(), puntoVentaSelList);
	}
	
	public void onClick$btnPesquisaLinha(Event ev) {
		linhaList.setData(rutaService.buscaRutaPorNumeroSemDadoRepetido(txtPalavraPesquisaLinha.getText()));
		PagedListGenerico.validarPagedListSemRegistro(linhaList, TITULO_RELATORIO);
	}

	public void onClick$btnLimparLinha(Event ev) {
		PagedListGenerico.limparPesquisaListBox(linhaList, txtPalavraPesquisaLinha);
	}
	
	public void onDoubleClick$linhaSelList(Event ev) {
		linhaSelList.removeItem((RutaVO) linhaSelList.getSelected());
	}

	public void onDoubleClick$linhaList(Event ev) {
		PagedListGenerico.validarInclusaoLista((RutaVO) linhaList.getSelected(), linhaSelList);
	}
	
	public void onClick$btnPesquisaCpf(Event ev) {
		PagedListCliente pageListCliente = new PagedListCliente(cpfList, txtCpfPesquisa, pagingCpfCliente);
		pageListCliente.buscarDadosPagedList(pagedListCliente);
		pageListCliente.validarPagedListSemRegistro(TITULO_RELATORIO);
	}
	
	public void onClick$btnLimparCpf(Event ev) {
		PagedListCliente.limparPesquisaListBox(cpfList, txtCpfPesquisa);
	}
	
	public void onDoubleClick$cpfSelList(Event ev) {
		cpfSelList.removeItem((Cliente) cpfSelList.getSelected());
	}
	
	public void onDoubleClick$cpfList(Event ev) {
		PagedListGenerico.validarInclusaoLista((Cliente) cpfList.getSelected(), cpfSelList);
	}
	
	public void onClick$btnExecutarRelatorio(Event ev) throws Exception {
		if (isDatasValidas()) {
			Relatorio relatorio = new RelatorioHistoricoCompras(getParametros(), dataSource.getConnection());

			Map<Object, Object> args = new HashMap<Object, Object>();
			args.put("relatorio", relatorio);

			openWindow("/component/reportView.zul",
					Labels.getLabel(TITULO_RELATORIO), args, MODAL);
		}
	}

	private Map<String, Object> getParametros() {
		Map<String, Object> parametros = new HashMap<String, Object>();
		
		parametros.put("NOME_RELATORIO", Labels.getLabel(TITULO_RELATORIO));
		parametros.put("dtVendaInicial", dtVendaInicial.getValue());
		parametros.put("dtVendaFinal", dtVendaFinal.getValue());
		parametros.put("dtEmbarqueInicial", dtEmbarqueInicial.getValue());
		parametros.put("dtEmbarqueFinal", dtEmbarqueFinal.getValue());
		getParametroPuntoVenta(parametros);
		getParametroLinha(parametros);
		getParametroCliente(parametros);
		
		return parametros;
	}

	private void getParametroCliente(Map<String, Object> parametros) {
		EspecializaLista<Cliente> especializaLista = new EspecializaLista<Cliente>(Cliente.class, cpfSelList, "getClienteId");
		if (!especializaLista.getLista().isEmpty()) {
			parametros.put("clienteId", especializaLista.obtemIds());
		}
	}

	private void getParametroLinha(Map<String, Object> parametros) {
		EspecializaLista<RutaVO> especializaLista = new EspecializaLista<RutaVO>(RutaVO.class, linhaSelList, "getNumRuta");
		if (!especializaLista.getLista().isEmpty()) {
			parametros.put("numRuta", especializaLista.obtemIds());
		}
	}

	private void getParametroPuntoVenta(Map<String, Object> parametros) {
		EspecializaLista<PuntoVenta> especializaLista = new EspecializaLista<PuntoVenta>(PuntoVenta.class, puntoVentaSelList, "getPuntoventaId");
		if (!especializaLista.getLista().isEmpty()) {
			parametros.put("puntoVentaId", especializaLista.obtemIds());
		}
	}

	private boolean isDatasValidas() {
		ValidarDatas validarDtVenda = new ValidarDatas(dtVendaInicial, dtVendaFinal);
		ValidarDatas validarDtEmbarque = new ValidarDatas(dtEmbarqueInicial, dtEmbarqueFinal);
		
		if (isDatasPeriodosNaoInformados(validarDtVenda, validarDtEmbarque)) {
			MensagensUtils.showMessageInformation(MSG_FILTRO_SEM_PERIODO, TITULO_RELATORIO);
			return false;
		}

		if (validarDtVenda.isPeriodoParcialmenteInformado()) {
			MensagensUtils.showMessageInformation(MSG_PERIODO_VENDA_INCOMPLETO, TITULO_RELATORIO);
			return false;
		}
		
		if (validarDtEmbarque.isPeriodoParcialmenteInformado()) {
			MensagensUtils.showMessageInformation(MSG_PERIODO_EMBARQUE_INCOMPLETO, TITULO_RELATORIO);
			return false;
		}
		
		if (!validarDtVenda.isPeriodoInicialNaoInformado() 
				&& validarDtVenda.validarDataInicioMaiorQueTermino(MSG_DATA_INICIAL_VENDA_MAIOR_FINAL, TITULO_RELATORIO)) {
			return false;
		}
		
		if (!validarDtEmbarque.isPeriodoNaoInformado()) {
			return !validarDtEmbarque.validarDataInicioMaiorQueTermino(MSG_DATA_INICIAL_EMBARQUE_MAIOR_FINAL, TITULO_RELATORIO);
		}
		
		return true;
	}

	private boolean isDatasPeriodosNaoInformados(ValidarDatas validarDtVenda, ValidarDatas validarDtEmbarque) {
		return validarDtVenda.isPeriodoNaoInformado() && validarDtEmbarque.isPeriodoNaoInformado();
	}
}
