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

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

import com.rjconsultores.ventaboletos.entidad.GP_Pricing;
import com.rjconsultores.ventaboletos.entidad.GP_PricingOcupaAntecipa;
import com.rjconsultores.ventaboletos.exception.BusinessException;
import com.rjconsultores.ventaboletos.service.GP_PricingOcupaAntecipaService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.pricing.GP_PricingOcupaAntecipaLegendaVO;
import com.rjconsultores.ventaboletos.vo.pricing.GP_PricingOcupaAntecipaPoltronasVO;
import com.rjconsultores.ventaboletos.vo.pricing.GP_PricingOcupaAntecipaVO;
import com.rjconsultores.ventaboletos.web.utilerias.ConstraintPorcentagem;
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.MyTextboxDecimal;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderPricingOcupaAntecipaLegenda;
import com.rjconsultores.ventaboletos.web.utilerias.render.RenderPricingOcupacao;

import ch.stfo.zk.component.Colorbox;

@Controller("editarGP_PricingOcupaAntecipaAutomaticoController")
@Scope("prototype")
public class EditarGP_PricingOcupaAntecipaAutomaticoController extends MyGenericForwardComposer {

	private static final long serialVersionUID = 1L;

	private final int CANTDIASMAXDEFAULT = 365;

	@Autowired
	private GP_PricingOcupaAntecipaService pricingOcupaAntecipaService;
	private GP_PricingOcupaAntecipa pricingOcupaAntecipa;
	private MyListbox pricingOcupaAntecipaList;
	private MyListbox parentPricingOcupaAntecipaList;
	private MyListbox parentPricingOcupaAntecipaLegendaList;
	
	private Colorbox colorChoose;
	private MyListbox pricingOcupaAntecipaLegendaList;	
	
	private Intbox ocupacioninicial;
	private Intbox ocupacionfinal;
	private Intbox cantdiasmin;

	private MyTextboxDecimal porcentaje;

	private List<GP_PricingOcupaAntecipa> lsPricingOcupaAntecipa;

	private Radio rdOcupacao;
	private Boolean hasNoElements;

	private List<GP_PricingOcupaAntecipa> argList;
	private GP_Pricing pricing;

	private ConstraintPorcentagem ct;
	private static Logger log = LogManager.getLogger(EditarGP_PricingOcupaAntecipaAutomaticoController.class);
	
	private List<String> columns;
	private List<GP_PricingOcupaAntecipaVO> lsPricingOcupacaoAntecipaVO;
	private List<GP_PricingOcupaAntecipaLegendaVO> lsPricingOcupaAntecipaLegendas;	

	@SuppressWarnings("unchecked")
	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		/*
		 * Transformar a tabela (valores de exemplo) :
		 * 
		 * Qtd. Dias 	Qtd. Dias 	Ocup. Min.	Ocup. Mxx.	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<GP_PricingOcupaAntecipa>) Executions.getCurrent().getArg().get("clasePricingOcupaAntecipaList");
		parentPricingOcupaAntecipaList = (MyListbox) Executions.getCurrent().getArg().get("pricingOcupaAntecipaList");
		parentPricingOcupaAntecipaLegendaList = (MyListbox) Executions.getCurrent().getArg().get("pricingOcupaAntecipaLegendasList");
		pricing = (GP_Pricing) Executions.getCurrent().getArg().get("pricing");
		
		lsPricingOcupaAntecipa = new ArrayList<GP_PricingOcupaAntecipa>();
		lsPricingOcupaAntecipaLegendas = new ArrayList<GP_PricingOcupaAntecipaLegendaVO>();
		lsPricingOcupacaoAntecipaVO = new ArrayList<GP_PricingOcupaAntecipaVO>();
		
		pricingOcupaAntecipaList.setItemRenderer(new RenderPricingOcupacao());
		pricingOcupaAntecipaLegendaList.setItemRenderer(new RenderPricingOcupaAntecipaLegenda());

		try {
			Collections.sort(argList, 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 (GP_PricingOcupaAntecipa p : argList) {
			if (p.getCantdiasmin() != null || 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());
			}

			carregarPricingOcupaAntecipaVO(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 (GP_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<GP_PricingOcupaAntecipa> parentList = new ArrayList<GP_PricingOcupaAntecipa>();
		Collections.sort(lsPricingOcupaAntecipa, new PricingOcupaAntecipaComparator());
		Integer cantDiasMin = lsPricingOcupaAntecipa.isEmpty() || lsPricingOcupaAntecipa.get(0).getCantdiasmin() == null ? 0 : lsPricingOcupaAntecipa.get(0).getCantdiasmin(); 
		if(cantDiasMin > 0){
			calculaCantDiasMax();
		}
		try {
			apagarRegistros();
			for (int i = 0; i < lsPricingOcupaAntecipa.size(); i++) {
				GP_PricingOcupaAntecipa pricingOcupaAntecipa = lsPricingOcupaAntecipa.get(i);
				if(!cantDiasMin.equals(pricingOcupaAntecipa.getCantdiasmin())){
					if(rdOcupacao.isChecked()){
						pricingOcupaAntecipa.setCantasientosmin(0);
					}else{
						pricingOcupaAntecipa.setOcupacioninicial(BigDecimal.ZERO);
					}
					
				}
				if(pricingOcupaAntecipa.getOcupacioninicial() == null){
					pricingOcupaAntecipa.setOcupacioninicial(BigDecimal.ZERO);
				}				
				if (pricingOcupaAntecipa.getPricingocupaantecipaId() == null) {
					pricingOcupaAntecipaService.suscribir(pricingOcupaAntecipa);
				} else {
					pricingOcupaAntecipaService.actualizacion(pricingOcupaAntecipa);
				}
				
				parentList.add(pricingOcupaAntecipa);

				cantDiasMin = pricingOcupaAntecipa.getCantdiasmin();
				if(validaPricingOcupa(i)){
					continue;
				}
				for (int j = i + 1; j < lsPricingOcupaAntecipa.size(); j++) {
					GP_PricingOcupaAntecipa p = new GP_PricingOcupaAntecipa();
					p.setPricingocupaantecipaId(lsPricingOcupaAntecipa.get(j).getPricingocupaantecipaId());
					p.setCantasientosmax(lsPricingOcupaAntecipa.get(j).getCantasientosmax());
					p.setCantasientosmin(lsPricingOcupaAntecipa.get(j).getCantasientosmin());
					p.setCantdiasmax(pricingOcupaAntecipa.getCantdiasmax());
					p.setCantdiasmin(pricingOcupaAntecipa.getCantdiasmin());
					p.setOcupacionfinal(lsPricingOcupaAntecipa.get(j).getOcupacionfinal());
					p.setOcupacioninicial(lsPricingOcupaAntecipa.get(j).getOcupacioninicial());
					p.setPorcentaje(lsPricingOcupaAntecipa.get(j).getPorcentaje());
					p.setPricing(pricing);
					p.setCor(lsPricingOcupaAntecipa.get(j).getCor());
					pricingOcupaAntecipaService.suscribir(p);
					parentList.add(p);
				}
			}
			
			//parentPricingOcupaAntecipaList.setData(parentList);
			carregarPricingOcupaAntecipaVO(parentList);
			parentPricingOcupaAntecipaList.setData(lsPricingOcupacaoAntecipaVO);
			parentPricingOcupaAntecipaLegendaList.setData(lsPricingOcupaAntecipaLegendas);
			closeWindow();
		} catch (Exception e) {
			log.error("", e);
			Messagebox.show(e.getLocalizedMessage(),
					Labels.getLabel("editarPricingController.windowOcupacion.title"),
					Messagebox.OK, Messagebox.EXCLAMATION);
		}
	}

	private boolean validaPricingOcupa(int i) {
		return (i+1) < lsPricingOcupaAntecipa.size() && lsPricingOcupaAntecipa.get(i).getCantdiasmin().equals(lsPricingOcupaAntecipa.get(i + 1).getCantdiasmin());
	}
	
	private class PricingOcupaAntecipaComparator implements Comparator<GP_PricingOcupaAntecipa> {
		public int compare(GP_PricingOcupaAntecipa pricing, GP_PricingOcupaAntecipa outroPricing) {
			Integer cantDiasMinComp = outroPricing.getCantdiasmin() != null ? outroPricing.getCantdiasmin().compareTo(pricing.getCantdiasmin()) : 0;
			Integer ocupaMinComp = outroPricing.getCantasientosmin() != null ? pricing.getCantasientosmin().compareTo(outroPricing.getCantasientosmin()) : 0;
			if (cantDiasMinComp != 0) {
				return cantDiasMinComp;
			}
			if(ocupaMinComp != 0){
			return pricing.getCantasientosmin().compareTo(outroPricing.getCantasientosmin());
			}else{
				return ocupaMinComp;
			}
		}
	}

	private void calculaCantDiasMax() {
		GP_PricingOcupaAntecipa poa;
		int cantDiasMinAnterior;
		if (lsPricingOcupaAntecipa.get(0).getCantdiasmin() == null){
			cantDiasMinAnterior = 0;
		}else{
			cantDiasMinAnterior = lsPricingOcupaAntecipa.get(0).getCantdiasmin();		
			int cantDiasMaxAnterior = CANTDIASMAXDEFAULT;
		for (int i = 0; i < lsPricingOcupaAntecipa.size(); i++) {
			poa = lsPricingOcupaAntecipa.get(i);
			if (i == 0) {
				poa.setCantdiasmax(CANTDIASMAXDEFAULT);
			} else {
				if(poa.getCantdiasmin().intValue() == cantDiasMinAnterior){
					poa.setCantdiasmax(cantDiasMaxAnterior);
				}else{
					poa.setCantdiasmax(cantDiasMinAnterior - 1);
					cantDiasMinAnterior = poa.getCantdiasmin();
					cantDiasMaxAnterior = poa.getCantdiasmax();
				}
			}
		}
		}
	}

	public void onClick$btnlancar(Event ev) throws Exception {
		try{
			colorChoose.getValue();
			
			GP_PricingOcupaAntecipa poa = new GP_PricingOcupaAntecipa();
			poa.setPricing(pricing);
			poa.setCantdiasmin(cantdiasmin.getValue());
			poa.setCor(colorChoose.getValue());
			if(!porcentaje.getValue().isEmpty()){
				poa.setPorcentaje(porcentaje.getValueDecimal());
				if( cantdiasmin.getValue() == null || (cantdiasmin.getValue() <= 365 && cantdiasmin.getValue() >= 0)){
					if ((ocupacionfinal.getValue() >= ocupacioninicial.getValue()) && ocupacionfinal.getValue() > 0  && ocupacioninicial.getValue() >= 0){
						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);
						
						carregarPricingOcupaAntecipaVO(lsPricingOcupaAntecipa);
					}else if(ocupacionfinal.getValue() == 0){	
						MensagensUtils.showMessageExclamation("editarPricingEspecificoOcupacionController.MSG.opucMaxAut","editarPricingController.windowOcupacion.title");
						ocupacionfinal.focus();
					}else if(ocupacioninicial.getValue() == null || ocupacionfinal.getValue() == null){
						MensagensUtils.showMessageExclamation("editarPricingEspecificoOcupacionController.MSG.ocupMinOpucMaxVazio","editarPricingController.windowOcupacion.title");
						ocupacioninicial.focus();
					}
					if(ocupacionfinal.getValue() < ocupacioninicial.getValue()) {
						MensagensUtils.showMessageExclamation("editarPricingEspecificoOcupacionController.MSG.ocupMinOpucMax","editarPricingController.windowOcupacion.title");
						ocupacioninicial.focus();						
					}
				}else{
					MensagensUtils.showMessageExclamation("editarPricingEspecificoOcupacionController.MSG.quantDiasOcup","editarPricingController.windowOcupacion.title");
				}
			}else{
				MensagensUtils.showMessageExclamation("editarPricingEspecificoOcupacionController.MSG.porcOcupaAutVazio", "editarPricingController.windowOcupacion.title");
				porcentaje.focus();
			}
		}catch(Exception ex) {
			log.error("ocupação mínimo ou máxima = null",ex);
		}		
	}

	private void carregarPricingOcupaAntecipaVO(List<GP_PricingOcupaAntecipa> lsPricingOcupaAntecipa) {
		lsPricingOcupacaoAntecipaVO = pricingOcupaAntecipaService.carregarPricingOcupaAntecipaVO(lsPricingOcupaAntecipa);
		lsPricingOcupaAntecipaLegendas = pricingOcupaAntecipaService.carregarPricingOcupaAntecipaLegenda(lsPricingOcupaAntecipa);
		
		pricingOcupaAntecipaList.setData(lsPricingOcupacaoAntecipaVO);
		pricingOcupaAntecipaLegendaList.setData(lsPricingOcupaAntecipaLegendas);
	}

	public void onClick$btnRemoverOcupaAntecipa(Event ev) {

		try {
			GP_PricingOcupaAntecipa pOcupacion = (GP_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(GP_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 GP_PricingOcupaAntecipa getPricingOcupaAntecipa() {
		return pricingOcupaAntecipa;
	}

	public void setPricingOcupacion(GP_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;
	}
	
	public List<String> getColumns() {
		if (columns == null) {
			carregarColunas();
		}
		return columns;
	}

	private void carregarColunas() {
		columns = new ArrayList<String>();
		for (int i = 1; i <= GP_PricingOcupaAntecipaPoltronasVO.MAXPOLTRONAS; i++) {
			columns.add(i+"");
		}
	}
	
	public void onChange$colorChoose(Event ev) throws InterruptedException {
		colorChoose.setStyle(" background: #FFFFFF; font-style: oblique;");
	}

}
