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

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
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.event.Event;
import org.zkoss.zul.Bandbox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Paging;
import org.zkoss.zul.Radio;
import org.zkoss.zul.Row;
import org.zkoss.zul.Textbox;

import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.entidad.Usuario;
import com.rjconsultores.ventaboletos.relatorios.impl.RelatorioVendaBilhetePorEmpresaAutorizadora;
import com.rjconsultores.ventaboletos.relatorios.impl.RelatorioVendaBilhetePorEmpresaAutorizadoraAnalitico;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.service.EmpresaService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
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.MyTextbox;
import com.rjconsultores.ventaboletos.web.utilerias.paginacion.HibernateSearchObject;
import com.rjconsultores.ventaboletos.web.utilerias.paginacion.PagedListWrapper;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRelatorioCheckinUsuario;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRelatorioCheckinUsuariosSelecionados;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRelatorioVendasBilheteiro;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRelatorioVendasBilheteiroSelecionados;

@Controller("relatorioVendaBilhetePorEmpresaAutorizadoraController")
@Scope("prototype")
public class RelatorioVendaBilhetePorEmpresaAutorizadoraController extends MyGenericForwardComposer {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static Logger log = LogManager.getLogger(RelatorioVendaBilhetePorEmpresaAutorizadoraController.class);

	@Autowired
	private EmpresaService empresaService;
	@Autowired
	private DataSource dataSourceRead;

	private Datebox datInicial;
	private Datebox datFinal;

	private MyComboboxEstandar cmbEmpresa;
	private MyComboboxEstandar cmbEmpresaAutorizadora;

	private List<Empresa> lsEmpresa;

	@Autowired
	private transient PagedListWrapper<PuntoVenta> plwPuntoVenta;
	@Autowired
	private transient PagedListWrapper<Usuario> plwUsuario;

	private MyTextbox txtNombrePuntoVenta;
	private Bandbox bbPesquisaPuntoVenta;
	private MyListbox puntoVentaList;
	private MyListbox puntoVentaSelList;
	private Paging pagingPuntoVenta;

	private MyListbox usuarioList;
	private MyListbox usuarioSelList;
	private Paging pagingUsuario;
	private Textbox txtPalavraPesquisa;
	private Bandbox bbPesquisaBilhetero;

	private List<Empresa> lsEmpresaAutorizadora;
	private MyTextbox txtBilheteiro;

	private Radio radioSintetico;
	private Radio radioAnalitico;
	
	private Row rowTipoReletario;



	private static final Short EMPRESA_OPERADORA = 4;

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		lsEmpresaAutorizadora = buscarEmpresaDiferenteDeOperadora(true);
		lsEmpresa = buscarEmpresaOperadora();
		puntoVentaList.setItemRenderer(new RenderRelatorioVendasBilheteiro());
		puntoVentaSelList.setItemRenderer(new RenderRelatorioVendasBilheteiroSelecionados());
		usuarioList.setItemRenderer(new RenderRelatorioCheckinUsuario());
		usuarioSelList.setItemRenderer(new RenderRelatorioCheckinUsuariosSelecionados());
		rowTipoReletario.setVisible(false);
		setarValorInicialCmbEmpresa();
	}

	private void setarValorInicialCmbEmpresa() {
		if(lsEmpresa!=null && !lsEmpresa.isEmpty()) {
		cmbEmpresa.setValue(lsEmpresa.get(0).toString());
		}
	}

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

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

	public List<Empresa> getLsEmpresaAutorizadora() {
		return lsEmpresaAutorizadora;
	}

	public void setLsEmpresaAutorizadora(List<Empresa> lsEmpresaAutorizadora) {
		this.lsEmpresaAutorizadora = lsEmpresaAutorizadora;
	}

	public EmpresaService getEmpresaService() {
		return empresaService;
	}

	public void setEmpresaService(EmpresaService empresaService) {
		this.empresaService = empresaService;
	}

	public DataSource getDataSourceRead() {
		return dataSourceRead;
	}

	public void setDataSourceRead(DataSource dataSourceRead) {
		this.dataSourceRead = dataSourceRead;
	}

	public Datebox getDatInicial() {
		return datInicial;
	}

	public void setDatInicial(Datebox datInicial) {
		this.datInicial = datInicial;
	}

	public Datebox getDatFinal() {
		return datFinal;
	}

	public void setDatFinal(Datebox datFinal) {
		this.datFinal = datFinal;
	}

	public MyComboboxEstandar getCmbEmpresa() {
		return cmbEmpresa;
	}

	public void setCmbEmpresa(MyComboboxEstandar cmbEmpresa) {
		this.cmbEmpresa = cmbEmpresa;
	}

	public MyComboboxEstandar getCmbEmpresaAutorizadora() {
		return cmbEmpresaAutorizadora;
	}

	public void setCmbEmpresaAutorizadora(MyComboboxEstandar cmbEmpresaAutorizadora) {
		this.cmbEmpresaAutorizadora = cmbEmpresaAutorizadora;
	}

	public PagedListWrapper<PuntoVenta> getPlwPuntoVenta() {
		return plwPuntoVenta;
	}

	public void setPlwPuntoVenta(PagedListWrapper<PuntoVenta> plwPuntoVenta) {
		this.plwPuntoVenta = plwPuntoVenta;
	}

	public PagedListWrapper<Usuario> getPlwUsuario() {
		return plwUsuario;
	}

	public void setPlwUsuario(PagedListWrapper<Usuario> plwUsuario) {
		this.plwUsuario = plwUsuario;
	}

	public MyTextbox getTxtNombrePuntoVenta() {
		return txtNombrePuntoVenta;
	}

	public void setTxtNombrePuntoVenta(MyTextbox txtNombrePuntoVenta) {
		this.txtNombrePuntoVenta = txtNombrePuntoVenta;
	}

	public Bandbox getBbPesquisaPuntoVenta() {
		return bbPesquisaPuntoVenta;
	}

	public void setBbPesquisaPuntoVenta(Bandbox bbPesquisaPuntoVenta) {
		this.bbPesquisaPuntoVenta = bbPesquisaPuntoVenta;
	}

	public MyListbox getPuntoVentaList() {
		return puntoVentaList;
	}

	public void setPuntoVentaList(MyListbox puntoVentaList) {
		this.puntoVentaList = puntoVentaList;
	}

	public MyListbox getPuntoVentaSelList() {
		return puntoVentaSelList;
	}

	public void setPuntoVentaSelList(MyListbox puntoVentaSelList) {
		this.puntoVentaSelList = puntoVentaSelList;
	}

	public Paging getPagingPuntoVenta() {
		return pagingPuntoVenta;
	}

	public void setPagingPuntoVenta(Paging pagingPuntoVenta) {
		this.pagingPuntoVenta = pagingPuntoVenta;
	}

	public MyListbox getUsuarioList() {
		return usuarioList;
	}

	public void setUsuarioList(MyListbox usuarioList) {
		this.usuarioList = usuarioList;
	}

	public MyListbox getUsuarioSelList() {
		return usuarioSelList;
	}

	public void setUsuarioSelList(MyListbox usuarioSelList) {
		this.usuarioSelList = usuarioSelList;
	}

	public Paging getPagingUsuario() {
		return pagingUsuario;
	}

	public void setPagingUsuario(Paging pagingUsuario) {
		this.pagingUsuario = pagingUsuario;
	}

	public Textbox getTxtPalavraPesquisa() {
		return txtPalavraPesquisa;
	}

	public void setTxtPalavraPesquisa(Textbox txtPalavraPesquisa) {
		this.txtPalavraPesquisa = txtPalavraPesquisa;
	}

	public Bandbox getBbPesquisaBilhetero() {
		return bbPesquisaBilhetero;
	}

	public void setBbPesquisaBilhetero(Bandbox bbPesquisaBilhetero) {
		this.bbPesquisaBilhetero = bbPesquisaBilhetero;
	}

	public MyTextbox getTxtBilheteiro() {
		return txtBilheteiro;
	}

	public void setTxtBilheteiro(MyTextbox txtBilheteiro) {
		this.txtBilheteiro = txtBilheteiro;
	}

	public static Short getEmpresaOperadora() {
		return EMPRESA_OPERADORA;
	}

	public void onClick$btnPesquisa(Event ev) {
		executarPesquisa();
	}

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

	public void onDoubleClick$puntoVentaList(Event ev) {
		PuntoVenta puntoVenta = (PuntoVenta) puntoVentaList.getSelected();
		puntoVentaSelList.addItemNovo(puntoVenta);
	}

	public void onClick$btnLimpar(Event ev) {
		puntoVentaList.setData(new ArrayList<PuntoVenta>());

		bbPesquisaPuntoVenta.setText("");
	}

	private void executarPesquisa() {
		HibernateSearchObject<PuntoVenta> puntoVentaBusqueda = new HibernateSearchObject<PuntoVenta>(PuntoVenta.class,
				pagingPuntoVenta.getPageSize());
		puntoVentaBusqueda.addFilterILike("nombpuntoventa", "%" + txtNombrePuntoVenta.getValue() + "%");
		puntoVentaBusqueda.addFilterEqual("activo", Boolean.TRUE);
		puntoVentaBusqueda.addSortAsc("nombpuntoventa");
		puntoVentaBusqueda.addFilterEqual("activo", Boolean.TRUE);
		plwPuntoVenta.init(puntoVentaBusqueda, puntoVentaList, pagingPuntoVenta);

		if (puntoVentaList.getData().length == 0) {
			try {
				Messagebox.show(Labels.getLabel("MSG.ningunRegistro"),
						Labels.getLabel("relatorioVendasBilheteiroSinteticoController.window.title"), Messagebox.OK,
						Messagebox.INFORMATION);
			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}
		}
	}

	public void onClick$btnLimparUsu(Event ev) {
		usuarioList.setData(new ArrayList<Usuario>());
		bbPesquisaBilhetero.setText("");
	}

	public void onClick$btnPesquisaUsu(Event ev) {
		executarPesquisaUsu();
	}

	public void onDoubleClick$usuarioList(Event ev) {
		Usuario usuario = (Usuario) usuarioList.getSelected();
		usuarioSelList.addItemNovo(usuario);
	}

	private void executarPesquisaUsu() {
		HibernateSearchObject<Usuario> usuarioBusqueda = new HibernateSearchObject<Usuario>(Usuario.class,
				pagingUsuario.getPageSize());
		usuarioBusqueda.addFilterLike("nombusuario", "%" + txtPalavraPesquisa.getValue() + "%");
		usuarioBusqueda.addSortAsc("nombusuario");
		usuarioBusqueda.addFilterEqual("activo", Boolean.TRUE);
		plwUsuario.init(usuarioBusqueda, usuarioList, pagingUsuario);
		if (usuarioList.getData().length == 0) {
			try {
				Messagebox.show(Labels.getLabel("MSG.ningunRegistro"),
						Labels.getLabel("indexController.mniRelatorioCheckin.label"), Messagebox.OK,
						Messagebox.INFORMATION);
			} catch (InterruptedException ex) {
				log.error(ex);
			}
		}
	}

	private List<Empresa> buscarEmpresaDiferenteDeOperadora(boolean isTodas) {
		List<Empresa> todasAsEmpresas = empresaService.obtenerTodos();
		List<Empresa> emAutorizadora = new ArrayList<Empresa>();
		if(isTodas) {
		Empresa empresa = new Empresa();
		empresa.setEmpresaId(-1);
		empresa.setNombempresa("TODAS");
		emAutorizadora.add(empresa);
		}
		for (Empresa emp : todasAsEmpresas) {
			if (emp.getIndTipo() != EMPRESA_OPERADORA) {
				emAutorizadora.add(emp);
			}
		}
		return emAutorizadora;
	}

	private List<Empresa> buscarEmpresaOperadora() {
		List<Empresa> todasAsEmpresas = empresaService.obtenerTodos();
		List<Empresa> empOperadoras = new ArrayList<Empresa>();
		for (Empresa emp : todasAsEmpresas) {
			if (emp.getIndTipo() == EMPRESA_OPERADORA) {
				empOperadoras.add(emp);
			}
		}
		return empOperadoras;
	}

	public void onClick$btnExecutarRelatorio(Event ev) throws Exception {
		executarRelatorio();
	}

	private void executarRelatorio() throws Exception {
		
		if(lsEmpresaAutorizadora.size()<=1) {
			Messagebox.show(Labels.getLabel("relatorioVendaBilhetePorEmpresaAutorizadoraController.naoexisteempresaautorizadora"),
					Labels.getLabel("relatorioVendaBilhetePorEmpresaAutorizadoraController.window.title"), Messagebox.OK,
					Messagebox.ERROR);
			return;		
			
		}		
	
		Map<String, Object> parametros = new HashMap<String, Object>();
		StringBuilder filtro = new StringBuilder();
		
		carregaValoresEmpresaAutorizadora(parametros, filtro);
		carregaValoresEmpresa(parametros, filtro);
		carregaValoresAgencia(parametros, filtro);

		carregaValoresBilheteiro(parametros, filtro);

		carregaDataInicial(parametros);
		carregaDataFinal(parametros);
		carregarUsuarioLogado(parametros);
		carregarUsuarioLogado(parametros);
		carregarOFiltro(parametros, filtro);

		if (radioAnalitico.isChecked()) {
			excutarRelatorioAnalitico(parametros);
		} else {
			executarRelatorioSintetico(parametros);
		}
	}

	private void executarRelatorioSintetico(Map<String, Object> parametros) throws Exception, SQLException {
		Relatorio relatorio;
		parametros.put("NOME_RELATORIO",
				Labels.getLabel("relatorioVendaBilhetePorEmpresaAutorizadoraController.nomeRelatorioSintetico.value"));
		relatorio = new RelatorioVendaBilhetePorEmpresaAutorizadora(parametros, dataSourceRead.getConnection());
		Map args = new HashMap();
		args.put("relatorio", relatorio);
		openWindow("/component/reportView.zul",
				Labels.getLabel("relatorioVendaBilhetePorEmpresaAutorizadoraController.nomeRelatorioSintetico.value"), args, MODAL);
	}

	private void excutarRelatorioAnalitico(Map<String, Object> parametros) throws Exception, SQLException {
		Relatorio relatorio;
		parametros.put("NOME_RELATORIO",
				Labels.getLabel("relatorioVendaBilhetePorEmpresaAutorizadoraController.nomeRelatorioAnalitico.value"));
		relatorio = new RelatorioVendaBilhetePorEmpresaAutorizadoraAnalitico(parametros,
				dataSourceRead.getConnection());
		Map args = new HashMap();
		args.put("relatorio", relatorio);
		openWindow("/component/reportView.zul",
				Labels.getLabel("relatorioVendaBilhetePorEmpresaAutorizadoraController.nomeRelatorioAnalitico.value"), args, MODAL);
	}

	private void carregarOFiltro(Map<String, Object> parametros, StringBuilder filtro) {
		parametros.put("FILTROS", filtro.toString());
	}

	private void carregarUsuarioLogado(Map<String, Object> parametros) {
		parametros.put("USUARIO", UsuarioLogado.getUsuarioLogado().getUsuarioId().toString());
	}

	private void carregaDataFinal(Map<String, Object> parametros) {
		parametros.put("DATA_FINAL", (java.util.Date) this.datFinal.getValue());
	}

	private void carregaDataInicial(Map<String, Object> parametros) {
		parametros.put("DATA_INICIAL", (java.util.Date) this.datInicial.getValue());
	}

	private void carregaValoresBilheteiro(Map<String, Object> parametros, StringBuilder filtro) {
		filtro.append("Usuarios: ");
		String usuarioIds = "";
		String usuarios = "";
		List<Usuario> lsUsuarioSelecionados = new ArrayList(Arrays.asList(usuarioSelList.getData()));
		if (lsUsuarioSelecionados.isEmpty()) {
			usuarios = "Todos";
		} else {
			for (int i = 0; i < lsUsuarioSelecionados.size(); i++) {
				Usuario usuario = lsUsuarioSelecionados.get(i);
				usuarios = usuarios + usuario.getClaveUsuario() + ",";

				usuarioIds = usuarioIds + usuario.getUsuarioId() + ",";
			}

			// removendo ultima virgula
			usuarioIds = usuarioIds.substring(0, usuarioIds.length() - 1);
			usuarios = usuarios.substring(0, usuarios.length() - 1);
			parametros.put("USUARIOIDS", usuarioIds);
		}
		filtro.append(usuarios).append(";");
	}

	private void carregaValoresAgencia(Map<String, Object> parametros, StringBuilder filtro) {
		filtro.append(" Agência: ");
		String puntoVentaIds = "";
		String puntoVentas = "";
		List<PuntoVenta> lsPuntoVentaSelecionados = new ArrayList(Arrays.asList(puntoVentaSelList.getData()));
		if (lsPuntoVentaSelecionados.isEmpty()) {
			puntoVentas = "Todas";
		} else {
			for (int i = 0; i < lsPuntoVentaSelecionados.size(); i++) {
				PuntoVenta puntoVenta = lsPuntoVentaSelecionados.get(i);
				puntoVentas = puntoVentas + puntoVenta.getNombpuntoventa() + ",";

				puntoVentaIds = puntoVentaIds + puntoVenta.getPuntoventaId() + ",";
			}

			// removendo ultima virgula
			puntoVentaIds = puntoVentaIds.substring(0, puntoVentaIds.length() - 1);
			puntoVentas = puntoVentas.substring(0, puntoVentas.length() - 1);
			parametros.put("NUMPUNTOVENTA", puntoVentaIds);
		}

		filtro.append(puntoVentas).append(";");
		
	}

	private void carregaValoresEmpresa(Map<String, Object> parametros, StringBuilder filtro) {
		filtro.append(" Empresa: ");

		Comboitem itemEmpresa = cmbEmpresa.getSelectedItem();
		if (itemEmpresa != null && !isEmpresaTodas(itemEmpresa)) {
			Empresa empresa = (Empresa) itemEmpresa.getValue();
			parametros.put("EMPRESA_ID", empresa.getEmpresaId());
			parametros.put("EMPRESA", empresa.getNombempresa());
			filtro.append(empresa.getNombempresa() + ";");
		} else {
			filtro.append(" Todas;");
		}
	}
	
	private boolean isEmpresaTodas(Comboitem itemEmpresa ) {
		Empresa empresa = (Empresa) itemEmpresa.getValue();
		return empresa.getEmpresaId().equals(-1);
		
		
	}

	private void carregaValoresEmpresaAutorizadora(Map<String, Object> parametros, StringBuilder filtro) {
		filtro.append(" Empresa Autorizadora: ");
		Comboitem itemEmpresaAutorizadora = cmbEmpresaAutorizadora.getSelectedItem();
		if (!isEmpresaTodas(itemEmpresaAutorizadora)) {
			Empresa empresa = (Empresa) itemEmpresaAutorizadora.getValue();
		    parametros.put("EMPRESAAUTORIZADORA_ID", empresa.getEmpresaId());
			filtro.append(empresa.getNombempresa() + ";");
		} else {
			filtro.append("TODAS;");
			parametros.put("EMPRESAAUTORIZADORA_ID", carregarOsIdsDeTodasAsEmpresasAutorizadoras());
		}
	}
	
	private String carregarOsIdsDeTodasAsEmpresasAutorizadoras() {
		List <Empresa> listEmpresasAutorizadora = buscarEmpresaDiferenteDeOperadora(false);
		StringBuilder string = new StringBuilder();
		
		if(listEmpresasAutorizadora!=null && !listEmpresasAutorizadora.isEmpty()) {
			for(Empresa e : listEmpresasAutorizadora) {
				if(StringUtils.isNotBlank(string.toString())) {
					string.append(",");
				}
				string.append(e.getEmpresaId());				
			}
			return string.toString();
		}		
		return null;		
	}
	
	

}
