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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.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.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Radio;

import com.rjconsultores.ventaboletos.entidad.Pricing;
import com.rjconsultores.ventaboletos.entidad.PricingOcupaAntecipa;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.PricingOcupaAntecipaService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.ConstraintPorcentagem;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;
import com.rjconsultores.ventaboletos.web.utilerias.MyTextboxDecimal;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderPricingOcupaAntecipa;

@Controller("editarPricingOcupaAntecipaAutomaticoController")
@Scope("prototype")
public class EditarPricingOcupaAntecipaAutomaticoController extends MyGenericForwardComposer {

	private static final long serialVersionUID = 1L;

	private final int CANTDIASMAXDEFAULT = 365;

	@Autowired
	private PricingOcupaAntecipaService pricingOcupaAntecipaService;
	private PricingOcupaAntecipa pricingOcupaAntecipa;
	private MyListbox pricingOcupaAntecipaList;
	private MyListbox parentPricingOcupaAntecipaList;
	private Intbox ocupacioninicial;
	private Intbox ocupacionfinal;
	private Intbox cantdiasmin;

	private MyTextboxDecimal porcentaje;

	private List<PricingOcupaAntecipa> lsPricingOcupaAntecipa;

	private Radio rdOcupacao;
	private Boolean hasNoElements;

	private List<PricingOcupaAntecipa> argList;
	private Pricing pricing;

	private ConstraintPorcentagem ct;
	private static Logger log = Logger.getLogger(EditarPricingOcupaAntecipaController.class);

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		/*
		 * Transformar a tabela (valores de exemplo) :
		 * 
		 * Qtd. Dias 	Qtd. Dias 	Ocup. Min.	Ocup. Máx.	Porcentagem
		 *  Minimo		Máximo
		 *  
		 *  	12     		* 			 0%			20%			-30%
		 * 		12     		* 			21%			80%			-15%
		 * 		12     		* 			81%			90%			-10%
		 *		8		   11			 0%			80%			-15%
		 *		8		   11			81%			90%			-10%
		 *		4			7			 0%			90%			-10%
		 *
		 * Na forma:
		 * 
		 * 12 dias ----> 30% (ocupação de 0% -> 20%)
		 * 08 dias ----> 15% (ocupação de 21% -> 80%)
		 * 04 dias ----> 10% (ocupação de 81% -> 90%)
		 *
		 */
			
		argList = (List<PricingOcupaAntecipa>) Executions.getCurrent().getArg().get("clasePricingOcupaAntecipaList");
		parentPricingOcupaAntecipaList = (MyListbox) Executions.getCurrent().getArg().get("pricingOcupaAntecipaList");
		pricing = (Pricing) Executions.getCurrent().getArg().get("pricing");
		pricingOcupaAntecipaList.setItemRenderer(new RenderPricingOcupaAntecipa());
		lsPricingOcupaAntecipa = new ArrayList<PricingOcupaAntecipa>();

		try {
			Collections.sort(argList, Collections.reverseOrder(new PricingOcupaAntecipaComparator()));
		} catch (Exception e) {
			Messagebox.show(Labels.getLabel("editarPricingOcupaAntecipaAutomaticoController.MSG.FormatoDados"),
					Labels.getLabel("editarPricingController.windowOcupacion.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);

			return;
		}

		int diaMin = -1;

		for (PricingOcupaAntecipa p : argList) {
			if (diaMin != p.getCantdiasmin()) {
				lsPricingOcupaAntecipa.add(p);
				diaMin = p.getCantdiasmin();
			}
		}

		// se TabelaMaior.size mod TabelaMenor.size = 0, então há possibilidade de transformar a maior na menor.
		if ((lsPricingOcupaAntecipa.size() > 0) && (argList.size() % lsPricingOcupaAntecipa.size() == 0)) {

			for (int j = 0; j < lsPricingOcupaAntecipa.size(); j++) {
				lsPricingOcupaAntecipa.get(j).setOcupacionfinal(argList.get(j).getOcupacionfinal());
				lsPricingOcupaAntecipa.get(j).setOcupacioninicial(argList.get(j).getOcupacioninicial());
				lsPricingOcupaAntecipa.get(j).setCantasientosmax(argList.get(j).getCantasientosmax());
				lsPricingOcupaAntecipa.get(j).setCantasientosmin(argList.get(j).getCantasientosmin());
			}

			pricingOcupaAntecipaList.setData(lsPricingOcupaAntecipa);
		} else if (lsPricingOcupaAntecipa.size() > 0) {
			Messagebox.show(Labels.getLabel("editarPricingOcupaAntecipaAutomaticoController.MSG.FormatoDados"),
					Labels.getLabel("editarPricingController.windowOcupacion.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
			return;
		}
	}

	private void apagarRegistros() throws BusinessException {
		for (PricingOcupaAntecipa poa : argList) {
			if ((poa.getOcupacioninicial() != null && poa.getOcupacioninicial().doubleValue() > 0) || (poa.getCantasientosmin() != null && poa.getCantasientosmin().intValue() > 0)) {
				pricingOcupaAntecipaService.borrar(poa);
			}
		}
	}

	public void onClick$btnAdicionarOcupaAntecipa(Event ev) throws Exception {
		List<PricingOcupaAntecipa> parentList = new ArrayList<PricingOcupaAntecipa>();
		calculaCantDiasMax();
		try {
			apagarRegistros();
			for (int i = 0; i < lsPricingOcupaAntecipa.size(); i++) {
				lsPricingOcupaAntecipa.get(i).setOcupacioninicial(new BigDecimal(0));
				if (lsPricingOcupaAntecipa.get(i).getPricingocupaantecipaId() == null) {
					pricingOcupaAntecipaService.suscribir(lsPricingOcupaAntecipa.get(i));
				} else {
					pricingOcupaAntecipaService.actualizacion(lsPricingOcupaAntecipa.get(i));
				}

				parentList.add(lsPricingOcupaAntecipa.get(i));

				for (int j = i + 1; j < lsPricingOcupaAntecipa.size(); j++) {
					PricingOcupaAntecipa p = new PricingOcupaAntecipa();
					p.setPricingocupaantecipaId(lsPricingOcupaAntecipa.get(j).getPricingocupaantecipaId());
					p.setCantasientosmax(lsPricingOcupaAntecipa.get(j).getCantasientosmax());
					p.setCantasientosmin(lsPricingOcupaAntecipa.get(j).getCantasientosmin());
					p.setCantdiasmax(lsPricingOcupaAntecipa.get(i).getCantdiasmax());
					p.setCantdiasmin(lsPricingOcupaAntecipa.get(i).getCantdiasmin());
					p.setOcupacionfinal(lsPricingOcupaAntecipa.get(j).getOcupacionfinal());
					p.setOcupacioninicial(lsPricingOcupaAntecipa.get(j).getOcupacioninicial());
					p.setPorcentaje(lsPricingOcupaAntecipa.get(j).getPorcentaje());
					p.setPricing(pricing);
					pricingOcupaAntecipaService.suscribir(p);
					parentList.add(p);
				}
			}

			parentPricingOcupaAntecipaList.setData(parentList);
			closeWindow();
		} catch (Exception e) {
			Messagebox.show(e.getLocalizedMessage(),
					Labels.getLabel("editarPricingController.windowOcupacion.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
		}
	}

	private class PricingOcupaAntecipaComparator implements Comparator<PricingOcupaAntecipa> {
		public int compare(PricingOcupaAntecipa pricing, PricingOcupaAntecipa outroPricing) {
			return pricing.getCantdiasmin().
					compareTo(outroPricing.getCantdiasmin());
		}
	}

	private void calculaCantDiasMax() {
		Collections.sort(lsPricingOcupaAntecipa, Collections.reverseOrder(new PricingOcupaAntecipaComparator()));
		PricingOcupaAntecipa poa;
		int cantDiasMinAnterior = lsPricingOcupaAntecipa.get(0).getCantdiasmin();
		for (int i = 0; i < lsPricingOcupaAntecipa.size(); i++) {
			poa = lsPricingOcupaAntecipa.get(i);
			if (i == 0) {
				poa.setCantdiasmax(CANTDIASMAXDEFAULT);
			} else {
				poa.setCantdiasmax(cantDiasMinAnterior - 1);
				cantDiasMinAnterior = poa.getCantdiasmin();
			}
		}
	}

	public void onClick$btnlancar(Event ev) throws Exception {

		for (PricingOcupaAntecipa poa : lsPricingOcupaAntecipa) {
			if (poa.getCantdiasmin().equals(cantdiasmin.getValue())) {
				Messagebox.show(Labels.getLabel("editarPricingAutomaticoController.msg.cantDias.erro"),
						Labels.getLabel("editarPricingController.windowOcupacion.title"),
						Messagebox.OK, Messagebox.EXCLAMATION);
				return;
			}
		}

		PricingOcupaAntecipa poa = new PricingOcupaAntecipa();
		poa.setPricing(pricing);
		poa.setCantdiasmin(cantdiasmin.getValue());
		poa.setPorcentaje(porcentaje.getValueDecimal());
		if (rdOcupacao.isChecked()) {
			poa.setOcupacioninicial(new BigDecimal(ocupacioninicial.getValue()));
			poa.setOcupacionfinal(new BigDecimal(ocupacionfinal.getValue()));
		} else {
			poa.setCantasientosmin(ocupacioninicial.getValue());
			poa.setCantasientosmax(ocupacionfinal.getValue());
		}

		lsPricingOcupaAntecipa.add(poa);
		pricingOcupaAntecipaList.setData(lsPricingOcupaAntecipa);
	}

	public void onClick$btnRemoverOcupaAntecipa(Event ev) {

		try {
			PricingOcupaAntecipa pOcupacion = (PricingOcupaAntecipa) pricingOcupaAntecipaList.getSelected();
			if (pOcupacion != null) {
				int resp = Messagebox.show(Labels.getLabel("editarPricingController.MSG.borrarPerguntaOcupacion"),
						Labels.getLabel("editarPricingController.windowOcupacion.title"),
						Messagebox.YES | Messagebox.NO,
						Messagebox.QUESTION);

				if (resp == Messagebox.YES) {
					pricingOcupaAntecipa.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
					pricingOcupaAntecipa.setFecmodif(Calendar.getInstance().getTime());
					pricingOcupaAntecipa.setActivo(Pricing.INATIVO);

					pricingOcupaAntecipaList.removeItem(pricingOcupaAntecipa);
					pricingOcupaAntecipaService.borrar(pricingOcupaAntecipa);
					closeWindow();
				}
			} else {
				Messagebox.show(Labels.getLabel("editarPricingController.MSG.selectItem"),
						Labels.getLabel("editarPricingController.windowOcupacion.title"),
						Messagebox.OK, Messagebox.EXCLAMATION);
			}
		} catch (Exception ex) {
			log.error(ex);
		}

	}

	public PricingOcupaAntecipa getPricingOcupaAntecipa() {
		return pricingOcupaAntecipa;
	}

	public void setPricingOcupacion(PricingOcupaAntecipa pricingOcupaAntecipa) {
		this.pricingOcupaAntecipa = pricingOcupaAntecipa;
	}

	public MyListbox getPricingOcupacionList() {
		return pricingOcupaAntecipaList;
	}

	public void setPricingOcupacionList(MyListbox pricingOcupacionList) {
		this.pricingOcupaAntecipaList = pricingOcupacionList;
	}

	public ConstraintPorcentagem getCt() {
		return ct;
	}

	public void setCt(ConstraintPorcentagem ct) {
		this.ct = ct;
	}

	public Boolean getHasNoElements() {
		return hasNoElements;
	}

	public void setHasNoElements(Boolean hasNoElements) {
		this.hasNoElements = hasNoElements;
	}

}
