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

import java.util.ArrayList;
import java.util.Date;
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.zhtml.Messagebox;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zkplus.databind.BindingListModelList;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Radio;

import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.EsquemaCorrida;
import com.rjconsultores.ventaboletos.entidad.InscricaoEstadual;
import com.rjconsultores.ventaboletos.entidad.OrgaoConcedente;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.entidad.RutaEmpresa;
import com.rjconsultores.ventaboletos.relatorios.impl.RelatorioMovimentoPorOrgaoConcedente;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.service.EmpresaService;
import com.rjconsultores.ventaboletos.service.EsquemaCorridaService;
import com.rjconsultores.ventaboletos.service.OrgaoConcedenteService;
import com.rjconsultores.ventaboletos.service.RutaService;
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.render.RenderEsquemaCorrida;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderRuta;

@Controller("relatorioMovimentoPorOrgaoConcedenteController")
@Scope("prototype")
public class RelatorioMovimentoPorOrgaoConcedenteController  extends MyGenericForwardComposer {

	@Autowired
	private DataSource dataSourceRead;
	
	@Autowired
	private EmpresaService empresaService;
	private List<Empresa> lsEmpresas;
	private Combobox cmbEmpresa;
	private Empresa empresa;
	
	@Autowired
	private OrgaoConcedenteService orgaoConcedenteService;
	private List<OrgaoConcedente> lsOrgaoConcedente;
	private Combobox cmbOrgaoConcedente;
	private OrgaoConcedente orgaoConcedente;
	
	private Radio radTipoServicioTodos;
	private Radio radTipoServicioOrdinarios;
	private Radio radTipoServicioExtraOrdinarios;
	
	private Datebox fecInicio;
	private Datebox fecFinal;
	
	@Autowired
	private EsquemaCorridaService esquemaCorridaService;
	private List<EsquemaCorrida> lsEsquemaCorrida;
	private List<EsquemaCorrida> lsSelectedEsquemaCorrida;
	private MyComboboxEstandar cmbEsquemaCorrida;
	private MyListbox listboxSelectedEsquemaCorrida;
	
	@Autowired
	private RutaService rutaService;
	private List<Ruta> lsRuta;
	private List<Ruta> lsSelectedRuta;
	private Combobox cmbRuta;
	private MyListbox listboxSelectedRuta;
	
	public List<Ruta> getLsRuta() {
		return lsRuta;
	}

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

	@Override
    public void doAfterCompose(Component comp) throws Exception {
		
		this.lsEmpresas = this.empresaService.obtenerTodos();
		this.lsOrgaoConcedente = this.orgaoConcedenteService.obtenerTodos();
		this.lsRuta = this.rutaService.buscarRutasPorEmpresas(UsuarioLogado.getUsuarioLogado().getEmpresa());
		this.lsEsquemaCorrida = this.esquemaCorridaService.obtenerTodos();
		
		super.doAfterCompose(comp);
		
		listboxSelectedEsquemaCorrida.setItemRenderer(new RenderEsquemaCorrida());
		lsSelectedEsquemaCorrida = new ArrayList<EsquemaCorrida>();
		listboxSelectedRuta.setItemRenderer(new RenderRuta());
		lsSelectedRuta = new ArrayList<Ruta>();
		
		
	}

	public OrgaoConcedenteService getOrgaoConcedenteService() {
		return orgaoConcedenteService;
	}

	public void setOrgaoConcedenteService(OrgaoConcedenteService orgaoConcedenteService) {
		this.orgaoConcedenteService = orgaoConcedenteService;
	}

	public Combobox getCmbOrgaoConcedente() {
		return cmbOrgaoConcedente;
	}

	public void setCmbOrgaoConcedente(Combobox cmbOrgaoConcedente) {
		this.cmbOrgaoConcedente = cmbOrgaoConcedente;
	}

	public List<OrgaoConcedente> getLsOrgaoConcedente() {
		return lsOrgaoConcedente;
	}

	public void setLsOrgaoConcedente(List<OrgaoConcedente> lsOrgaoConcedente) {
		this.lsOrgaoConcedente = lsOrgaoConcedente;
	}

	public List<Empresa> getLsEmpresas() {
		return lsEmpresas;
	}

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

	public EmpresaService getEmpresaService() {
		return empresaService;
	}

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

	public Combobox getCmbEmpresa() {
		return cmbEmpresa;
	}

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

	public Empresa getEmpresa() {
		return empresa;
	}

	public void setEmpresa(Empresa empresa) {
		this.empresa = empresa;
	}

	public Datebox getFecInicio() {
		return fecInicio;
	}

	public void setFecInicio(Datebox fecInicio) {
		this.fecInicio = fecInicio;
	}

	public Datebox getFecFinal() {
		return fecFinal;
	}

	public void setFecFinal(Datebox fecFinal) {
		this.fecFinal = fecFinal;
	}
	
	public OrgaoConcedente getOrgaoConcedente() {
		return orgaoConcedente;
	}

	public void setOrgaoConcedente(OrgaoConcedente orgaoConcedente) {
		this.orgaoConcedente = orgaoConcedente;
	}

	public List<EsquemaCorrida> getLsEsquemaCorrida() {
		return lsEsquemaCorrida;
	}

	public void setLsEsquemaCorrida(List<EsquemaCorrida> lsEsquemaCorrida) {
		this.lsEsquemaCorrida = lsEsquemaCorrida;
	}

	public List<EsquemaCorrida> getLsSelectedEsquemaCorrida() {
		return lsSelectedEsquemaCorrida;
	}

	public void setLsSelectedEsquemaCorrida(List<EsquemaCorrida> lsSelectedEsquemaCorrida) {
		this.lsSelectedEsquemaCorrida = lsSelectedEsquemaCorrida;
	}

	public EsquemaCorridaService getEsquemaCorridaService() {
		return esquemaCorridaService;
	}

	public void setEsquemaCorridaService(EsquemaCorridaService esquemaCorridaService) {
		this.esquemaCorridaService = esquemaCorridaService;
	}

	public MyComboboxEstandar getCmbEsquemaCorrida() {
		return cmbEsquemaCorrida;
	}

	public void setCmbEsquemaCorrida(MyComboboxEstandar cmbEsquemaCorrida) {
		this.cmbEsquemaCorrida = cmbEsquemaCorrida;
	}
	
	public void onChange$cmbOrgaoConcedente(Event ev) {
		Comboitem cbiOrgao = cmbOrgaoConcedente.getSelectedItem();
		if (cbiOrgao != null) {
			OrgaoConcedente orgao = (OrgaoConcedente) cbiOrgao.getValue();

			List<EsquemaCorrida> lsEsqCorrSecundaria = new ArrayList<EsquemaCorrida>();
			for(EsquemaCorrida ec : lsEsquemaCorrida){
				if(ec.getRuta() != null && ec.getRuta().getOrgaoConcedente() != null 
						&& ec.getRuta().getOrgaoConcedente().getOrgaoConcedenteId().equals(orgao.getOrgaoConcedenteId()) ){
					lsEsqCorrSecundaria.add(ec);
				}
			}
				cmbEsquemaCorrida.setModel(new BindingListModelList(lsEsqCorrSecundaria, true));

			List<Ruta> lsRutaSecundaria = new ArrayList<Ruta>();
			for(Ruta r : lsRuta){
				if(r.getOrgaoConcedente() != null && r.getOrgaoConcedente().getOrgaoConcedenteId().equals(orgao.getOrgaoConcedenteId())   ){
					lsRutaSecundaria.add(r);
				}
			}
				cmbRuta.setModel(new BindingListModelList(lsRutaSecundaria, true));
		}
	}
	
	public void onChange$cmbEmpresa(Event ev) {
		Comboitem cbiEmpresa = cmbEmpresa.getSelectedItem();
		if (cbiEmpresa != null) {
			Empresa empresa = (Empresa) cbiEmpresa.getValue();

			List<EsquemaCorrida> lsEsqCorrSecundaria = new ArrayList<EsquemaCorrida>();
			for(EsquemaCorrida ec : lsEsquemaCorrida){
				if((ec.getEmpresa()!= null && ec.getEmpresa().getEmpresaId() !=null &&  ec.getEmpresa().getEmpresaId().equals(empresa.getEmpresaId()))){
					lsEsqCorrSecundaria.add(ec);
				}
			}
			if(!lsEsqCorrSecundaria.isEmpty())
			cmbEsquemaCorrida.setModel(new BindingListModelList(lsEsqCorrSecundaria, true));

			List<Ruta> lsRutaSecundaria = new ArrayList<Ruta>();
			for(Ruta r : lsRuta){
				if(r.getLsRutaEmpresa() != null && r.getLsRutaEmpresa().size()>0   ){
					for(RutaEmpresa  re : r.getLsRutaEmpresa()){
						if(re.getEmpresa().getEmpresaId().equals(empresa.getEmpresaId())){
							lsRutaSecundaria.add(re.getRuta());
						}
					}
				}
			}
			if(!lsRutaSecundaria.isEmpty())
				cmbRuta.setModel(new BindingListModelList(lsRutaSecundaria, true));
		}
	}
	
	public void onClick$btnAddEsquemaCorrida(Event ev) throws InterruptedException {
		if (cmbEsquemaCorrida.getSelectedItem() != null) {
			lsSelectedEsquemaCorrida.add((EsquemaCorrida) cmbEsquemaCorrida.getSelectedItem().getValue());
			listboxSelectedEsquemaCorrida.setData(lsSelectedEsquemaCorrida);
			cmbEsquemaCorrida.setSelectedItem(null);
		}
	}
	
	public void onClick$btnRemoveEsquemaCorrida(Event ev) throws InterruptedException {
		if (listboxSelectedEsquemaCorrida.getSelectedItem() != null) {
			EsquemaCorrida ec = (EsquemaCorrida)listboxSelectedEsquemaCorrida.getSelected();
			lsSelectedEsquemaCorrida.remove(ec);
			listboxSelectedEsquemaCorrida.setData(lsSelectedEsquemaCorrida);
		}
	}
	
	public void onClick$btnAddRuta(Event ev) throws InterruptedException {
		if (cmbRuta.getSelectedItem() != null) {
			lsSelectedRuta.add((Ruta) cmbRuta.getSelectedItem().getValue());
			listboxSelectedRuta.setData(lsSelectedRuta);
			cmbRuta.setSelectedItem(null);
		}
	}
	
	public void onClick$btnRemoveRuta(Event ev) throws InterruptedException {
		if (listboxSelectedRuta.getSelectedItem() != null) {
			Ruta ec = (Ruta)listboxSelectedRuta.getSelected();
			lsSelectedRuta.remove(ec);
			listboxSelectedRuta.setData(lsSelectedRuta);
		}
	}

	public MyListbox getListboxSelectedEsquemaCorrida() {
		return listboxSelectedEsquemaCorrida;
	}

	public void setListboxSelectedEsquemaCorrida(MyListbox listboxSelectedEsquemaCorrida) {
		this.listboxSelectedEsquemaCorrida = listboxSelectedEsquemaCorrida;
	}

	public RutaService getRutaService() {
		return rutaService;
	}

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

	public List<Ruta> getLsSelectedRuta() {
		return lsSelectedRuta;
	}

	public void setLsSelectedRuta(List<Ruta> lsSelectedRuta) {
		this.lsSelectedRuta = lsSelectedRuta;
	}

	public Combobox getCmbRuta() {
		return cmbRuta;
	}

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

	public MyListbox getListboxSelectedRuta() {
		return listboxSelectedRuta;
	}

	public void setListboxSelectedRuta(MyListbox listboxSelectedRuta) {
		this.listboxSelectedRuta = listboxSelectedRuta;
	}
	
	public void onClick$btnExecutarRelatorio(Event ev) throws Exception {
		executarRelatorio();
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void executarRelatorio() throws Exception {
		
		Relatorio relatorio;

		Map<String, Object> parametros = new HashMap<String, Object>();

		if (this.orgaoConcedente != null) {
			parametros.put("ORGAOCONCEDENTE_ID", this.orgaoConcedente.getOrgaoConcedenteId());
			parametros.put("ORGAO_CONCEDENTE", this.orgaoConcedente.getDescOrgao());
		}else{
			parametros.put("ORGAO_CONCEDENTE", "TODOS");
		}
		
		if(this.empresa != null){
			parametros.put("EMPRESA", this.empresa.getNombempresa());
			parametros.put("MUNICIPIO", this.empresa.getCidade().getNombciudad());
			parametros.put("EMPRESA_ID", this.empresa.getEmpresaId());
			parametros.put("ENDERECO", this.empresa.getLogradouro() +this.empresa.getNumero());// +this.empresa.getComplemento());
			parametros.put("CNPJ", this.empresa.getCnpj());
			String inscricaoEstadual = "";
			for (InscricaoEstadual a : this.empresa.getInscricoesEstaduais()) {
				if (inscricaoEstadual.length() != 0 && a.getActivo()) {
					inscricaoEstadual += ",";
				}
				inscricaoEstadual += a.getNumInscricaoEstadual();
			}
			parametros.put("INSCRICAO", inscricaoEstadual);
		}else{
			parametros.put("EMPRESA", "TODAS");
			parametros.put("MUNICIPIO", "");
			parametros.put("ENDERECO","");
			parametros.put("CNPJ", "");
			parametros.put("INSCRICAO", "");
		}
		Boolean isNull = fecInicio.getValue() == null || fecFinal.getValue() == null;
		if(isNull){
			try {
				Messagebox.show(Labels.getLabel("relatorioMovimentoPorOrgaoConcedente.MSG.informarPeriodoData"),
						Labels.getLabel("relatorioMovimentoPorOrgaoConcedente.window.title"),
						Messagebox.OK, Messagebox.EXCLAMATION);
				return;
			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}
		}
		
		if(this.lsSelectedRuta != null && !this.lsSelectedRuta.isEmpty()){
			parametros.put("LINHA_ID",  obterRutaIds(this.lsSelectedRuta)   );
			parametros.put("LINHA", retornarLinha(this.lsSelectedRuta));
		}else{
			parametros.put("LINHA", "TODAS");
		}
		
		if(this.lsSelectedEsquemaCorrida != null && ! this.lsSelectedEsquemaCorrida.isEmpty()){
			parametros.put("SERVICO_ID",  obterEsquemaCorrridaIds(this.lsSelectedEsquemaCorrida)   );
			parametros.put("SERVICO", this.lsSelectedEsquemaCorrida);
		}else{
			parametros.put("SERVICO", "TODOS");
		}
		
		
		
		String tipoServicioId = "";
		if (radTipoServicioTodos.isChecked()) {
			tipoServicioId = "-1";
		}else if (radTipoServicioOrdinarios.isChecked()) {
			tipoServicioId = "1";
		}else if(radTipoServicioExtraOrdinarios.isChecked()) {
			tipoServicioId = "2";
		}
		parametros.put("TIPOSERVICIO_ID", tipoServicioId);
		
		if(fecInicio.getValue() != null && fecFinal.getValue() != null ){
			Date dataInicial = fecInicio.getValue();
			Date dataFinal = fecFinal.getValue();
			if (dataInicial.after(dataFinal)) {
				Messagebox.show(Labels.getLabel("relatorioMovimentoPorOrgaoConcedente.MSG.dataInicialMaiorFinal"),
						Labels.getLabel("relatorioMovimentoPorOrgaoConcedente.window.title"),
						Messagebox.OK, Messagebox.EXCLAMATION);
				return;
			}
//			parametros.put("FECCORRIDA", new java.sql.Date(((java.util.Date) this.fecCorrida.getValue()).getTime()));
			parametros.put("DATA_DE", new java.sql.Date(((java.util.Date) fecInicio.getValue()).getTime()));
			parametros.put("DATA_ATE", new java.sql.Date(((java.util.Date) fecFinal.getValue()).getTime()));
		}
		
		parametros.put("ESQUEMACORRIDA_ID", obterEsquemaCorrridaIds(lsSelectedEsquemaCorrida) );
		
		relatorio = new RelatorioMovimentoPorOrgaoConcedente(parametros, dataSourceRead.getConnection());
		
		Map args = new HashMap();
		args.put("relatorio", relatorio);

		openWindow("/component/reportView.zul",
				Labels.getLabel("relatorioMovimentoPorOrgaoConcedente.window.title"), args, MODAL);

	}

	private String obterEsquemaCorrridaIds(List<EsquemaCorrida> esquemaCorridas){
		String ids = ""; 
		for(int i = 0 ; i < esquemaCorridas.size() ; i ++){
			if(i == 0 ){
				ids = ids+esquemaCorridas.get(i).getNumCorrida();
			}else{
				ids = ids+","+esquemaCorridas.get(i).getNumCorrida();
			}
		}
		return ids;
	}
	
	private String obterRutaIds(List<Ruta> rutas){
		String ids = ""; 
		for(int i = 0 ; i < rutas.size() ; i ++){
			if(i == 0 ){
				ids = ids+rutas.get(i).getRutaId();
			}else{
				ids = ids+","+rutas.get(i).getRutaId();
			}
		}
		return ids;
	}
	
	public Radio getRadTipoServicioTodos() {
		return radTipoServicioTodos;
	}

	public void setRadTipoServicioTodos(Radio radTipoServicioTodos) {
		this.radTipoServicioTodos = radTipoServicioTodos;
	}

	public Radio getRadTipoServicioOrdinarios() {
		return radTipoServicioOrdinarios;
	}

	public void setRadTipoServicioOrdinarios(Radio radTipoServicioOrdinarios) {
		this.radTipoServicioOrdinarios = radTipoServicioOrdinarios;
	}

	public Radio getRadTipoServicioExtraOrdinarios() {
		return radTipoServicioExtraOrdinarios;
	}

	public void setRadTipoServicioExtraOrdinarios(Radio radTipoServicioExtraOrdinarios) {
		this.radTipoServicioExtraOrdinarios = radTipoServicioExtraOrdinarios;
	}
	
	private String retornarLinha(List<Ruta>  ls){
		String x = "";
		
		for(Ruta r : ls){
			x = x + r.getPrefixo()+r.toString();
		}
		
		return x;
	}
}