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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

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.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Messagebox;

import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.constantes.ConstantesFuncionSistema;
import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.exception.ComissaoException;
import com.rjconsultores.ventaboletos.service.CalculoComissaoService;
import com.rjconsultores.ventaboletos.service.ComissaoService;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.MyComboboxPuntoVenta;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;

@Scope("prototype")
@Controller("busquedaRetencaoDiariaComissaoController")
public class BusquedaRetencaoDiariaComissaoController extends MyGenericForwardComposer {

	private static final long serialVersionUID = 1L;
	private static Logger log = LogManager.getLogger(BusquedaRetencaoDiariaComissaoController.class);

	@Autowired
	private CalculoComissaoService calculoComissaoService;

	@Autowired
	private ConstanteService constanteService;
	
	@Autowired
	private ComissaoService comissaoService;
	
	private Combobox cmbEmpresa;
	private List<Empresa> lsEmpresas;
	private List<PuntoVenta> lsPuntoVenta;
	private MyComboboxPuntoVenta cmbPuntoVenta;
	private Datebox dataInicial;
	private Datebox dataFinal;

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

		lsEmpresas = UsuarioLogado.getUsuarioLogado().getEmpresa();
		lsPuntoVenta = new ArrayList<PuntoVenta>();
	}

	private boolean verificarCampos() throws Exception {
		PuntoVenta puntoVenta = (PuntoVenta) (cmbPuntoVenta.getSelectedItem() != null ? cmbPuntoVenta.getSelectedItem().getValue() : null);
		Empresa empresa = (Empresa) (cmbEmpresa.getSelectedItem() != null ? cmbEmpresa.getSelectedItem().getValue() : null);
		
		if((puntoVenta == null || puntoVenta.getPuntoventaId() == -1) && !isPermissaoCalculoDiarioComissaoTodasAsAgencias()) {
			Messagebox.show(Labels.getLabel("busquedaRetencaoDiariaComissaoController.error.puntoventa"),
					Labels.getLabel("busquedaRetencaoDiariaComissaoController.window.title"),
					Messagebox.OK, Messagebox.ERROR);
			return false;
			
		}
		
		if(empresa == null || empresa.getEmpresaId() == -1) {
			Messagebox.show(Labels.getLabel("busquedaRetencaoDiariaComissaoController.error.empresa"),
					Labels.getLabel("busquedaRetencaoDiariaComissaoController.window.title"),
					Messagebox.OK, Messagebox.ERROR);
			return false;
			
		}
		
		if(dataInicial.getValue().after(dataFinal.getValue())){
			Messagebox.show(Labels.getLabel("MSG.Error.invalida.dataInicialDepoisDataFinal"),
					Labels.getLabel("busquedaRetencaoDiariaComissaoController.window.title"),
					Messagebox.OK, Messagebox.ERROR);
			return false;
		}
		
		Calendar cal = Calendar.getInstance();
		cal.setTime(dataInicial.getValue());
		int monthInicial = cal.get(Calendar.MONTH);
		int yearInicial = cal.get(Calendar.YEAR);
		
		cal.setTime(dataFinal.getValue());
		int monthFinal = cal.get(Calendar.MONTH);
		int yearFinal = cal.get(Calendar.YEAR);
		
		if(monthInicial != monthFinal
				|| yearFinal != yearInicial){
			Messagebox.show(Labels.getLabel("MSG.Error.invalida.dataInicialFinalMesDiferente"),
					Labels.getLabel("busquedaRetencaoDiariaComissaoController.window.title"),
					Messagebox.OK, Messagebox.ERROR);
			return false;
		}
		
		Integer qtdeMaxDias = 1;
		Constante constante = constanteService.buscarPorNomeConstante(Constantes.QTDE_MAX_DIAS_RETENCAO_DIARIA_COMISSAO);
		if(constante != null && StringUtils.isNotBlank(constante.getValorconstante())) {
			qtdeMaxDias = Integer.valueOf(constante.getValorconstante());
		}
		
		if(DateUtil.getElapsedDias(dataInicial.getValue(), dataFinal.getValue()) > qtdeMaxDias) {
			Messagebox.show(Labels.getLabel("busquedaRetencaoDiariaComissaoController.info.qtdeMaxDias", new Object[] {qtdeMaxDias}),
					Labels.getLabel("busquedaRetencaoDiariaComissaoController.window.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
			return false;
		}
		
		return true;
	}

	public void onClick$btnCalcular(Event ev) throws InterruptedException {

		try {
			if(verificarCampos()) {
				processarRecalculoComissao();
				
				Messagebox.show(
						Labels.getLabel("busquedaRetencaoDiariaComissaoController.info.comissao"),
						Labels.getLabel("busquedaRetencaoDiariaComissaoController.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);
			}
		} catch (ComissaoException ce) {
			log.error(ce.getMessage(), ce);
			Messagebox.show(ce.getMessage(), Labels.getLabel("busquedaRetencaoDiariaComissaoController.window.title"),
					Messagebox.OK, Messagebox.ERROR);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			Messagebox.show(e.getMessage(), Labels.getLabel("busquedaRetencaoDiariaComissaoController.window.title"),
					Messagebox.OK, Messagebox.ERROR);
		}

	}
	
	private void processarRecalculoComissao() throws WrongValueException, ComissaoException, BusinessException {
		PuntoVenta puntoVenta = (PuntoVenta) (cmbPuntoVenta.getSelectedItem() != null ? cmbPuntoVenta.getSelectedItem().getValue() : null);
		Empresa empresa = (Empresa) (cmbEmpresa.getSelectedItem() != null ? cmbEmpresa.getSelectedItem().getValue() : null);
		
		List<PuntoVenta> puntoventas = null;
		if(puntoVenta == null || puntoVenta.getPuntoventaId() == -1) {
			puntoventas = comissaoService.buscaPuntoVentasEmpresaComComissaoParametrizada(empresa.getEmpresaId());
		} else {
			puntoventas = Arrays.asList(new PuntoVenta[] {puntoVenta});
		}
		
		Calendar cDataAtual = Calendar.getInstance();
		cDataAtual.setTime(dataInicial.getValue());
		Date dataInicioCalculo = new Date();
		log.info("Inicio Recalculo");
		while(DateUtil.compareOnlyDate(cDataAtual.getTime(), dataFinal.getValue()) <= 0) {
			int qtde = 0;
			Date dataInicioDia = new Date();
			for (PuntoVenta pv : puntoventas) {
				log.info("Inicio Recalculo Comissao Agencia: " + pv.getNombpuntoventa());
				log.info("Empresa: " + empresa.getNombempresa());
				log.info("Data: " + DateUtil.getStringDate(cDataAtual.getTime()) + " - Agencia: " + (++qtde) + "/" + puntoventas.size());
				Date dataInicioCalculoAgencia = new Date();
				calculoComissaoService.registrarCalculoComissao(pv, empresa, cDataAtual.getTime(), cDataAtual.getTime(), UsuarioLogado.getUsuarioLogado().getUsuarioId());
				log.info("Data/Hora Inicio: " + DateUtil.getStringDate(dataInicioCalculoAgencia, "dd/MM/yyyy HH:mm:ss") + " - Data/Hora Fim: " + DateUtil.getStringDate(new Date(), "dd/MM/yyyy HH:mm:ss"));
				log.info("Fim Recalculo Comissao Agencia: " + pv.getNombpuntoventa());
				log.info("-----------------------------");
			}
			log.info("Tempo processamento data: " + DateUtil.getStringDate(cDataAtual.getTime()) + " - Hora Inicio recalculo: " + DateUtil.getStringDate(dataInicioDia, "dd/MM/yyyy HH:mm:ss") + " - Fim recalculo: " + DateUtil.getStringDate(new Date(), "dd/MM/yyyy HH:mm:ss"));
			cDataAtual.add(Calendar.DAY_OF_MONTH, 1);
		}
		log.info("Recalculo total Data/Hora Inicio: " + DateUtil.getStringDate(dataInicioCalculo, "dd/MM/yyyy HH:mm:ss") + " - Data/Hora Fim: " + DateUtil.getStringDate(new Date(), "dd/MM/yyyy HH:mm:ss"));
		log.info("Fim Recalculo");
		
	}

	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 List<PuntoVenta> getLsPuntoVenta() {
		return lsPuntoVenta;
	}

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

	public MyComboboxPuntoVenta getCmbPuntoVenta() {
		return cmbPuntoVenta;
	}

	public void setCmbPuntoVenta(MyComboboxPuntoVenta cmbPuntoVenta) {
		this.cmbPuntoVenta = cmbPuntoVenta;
	}
	
	public Boolean isPermissaoCalculoDiarioComissaoTodasAsAgencias() {
		return UsuarioLogado.getUsuarioLogado().isPermisoClave(ConstantesFuncionSistema.CLAVE_CALCULODIARIOCOMISSAO_AUTORIZACAOCALCULOTODASAGENCIAS);
	}

}
