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

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;

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.zul.Messagebox;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zkplus.databind.BindingListModelList;
import org.zkoss.zul.Button;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Row;
import org.zkoss.zul.Textbox;

import com.rjconsultores.ventaboletos.entidad.AbastoBoleto;
import com.rjconsultores.ventaboletos.entidad.Aidf;
import com.rjconsultores.ventaboletos.entidad.AidfEspecie;
import com.rjconsultores.ventaboletos.entidad.AidfTipo;
import com.rjconsultores.ventaboletos.entidad.Articulo;
import com.rjconsultores.ventaboletos.entidad.Clasificacion;
import com.rjconsultores.ventaboletos.entidad.DetAbastoBoleto;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.entidad.InscricaoEstadual;
import com.rjconsultores.ventaboletos.entidad.PerfilFuncion;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.entidad.Usuario;
import com.rjconsultores.ventaboletos.entidad.UsuarioPerfil;
import com.rjconsultores.ventaboletos.service.AbastoBoletoService;
import com.rjconsultores.ventaboletos.service.AbastoCentralService;
import com.rjconsultores.ventaboletos.service.AbastoHistoService;
import com.rjconsultores.ventaboletos.service.AidfService;
import com.rjconsultores.ventaboletos.service.DetAbastoBoletoService;
import com.rjconsultores.ventaboletos.service.EmpresaService;
import com.rjconsultores.ventaboletos.service.EstadoService;
import com.rjconsultores.ventaboletos.service.UsuarioService;
import com.rjconsultores.ventaboletos.utilerias.ApplicationProperties;
import com.rjconsultores.ventaboletos.utilerias.CustomEnum;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.web.utilerias.MyComboboxPuntoVenta;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;

@Controller("editarAidfController")
@Scope("prototype")
public class EditarAidfController extends MyGenericForwardComposer {

	private static final String TITULO = "editarAidfController.window.title";

	private static final long serialVersionUID = 1L;

	@Autowired
	private AidfService aidfService;

	@Autowired
	private AbastoBoletoService abastoBoletoService;
	
	@Autowired
	private AbastoHistoService abastoHistoService;

	@Autowired
	private AbastoCentralService abastoCentralService;

	@Autowired
	private DetAbastoBoletoService detAbastoBoletoService;

	@Autowired
	private EstadoService estadoService;

	@Autowired
	private EmpresaService empresaService;
	
	@Autowired
	private UsuarioService usuarioService;
	
	private Aidf aidf;
	private MyListbox aidfList;

	private List<AidfEspecie> lsAidfEspecie;
	private Combobox cmbAidfEspecie;

	private List<Estado> lsEstado;
	private Combobox cmbEstado;

	private List<AidfTipo> lsAidfTipo;
	private Combobox cmbAidfTipo;

	private Combobox cmbEmpresa;
	private List<Empresa> lsEmpresas;

	private Combobox cmbInscestadual;
	private List<InscricaoEstadual> lsInscestadual;

	private Textbox txtDocFiscal;
	private Textbox txtAcFiscal;
	private Textbox txtSerie;
	private Textbox txtSubSerie;
	private Textbox txtForminicial;
	private Textbox txtFormfinal;
	private Textbox txtFecAquisicao;
	private Textbox txtFecVencimento;

	private Button btnApagar;
	private Button btnSalvar;

	private Datebox dtbFecadquisicion;
	private Datebox dtbFecvencimiento;
	private Combobox cmbTipoValidaVenta;
	private MyComboboxPuntoVenta cmbPuntoVenta;
	private Row rowPuntoVenta;
	private static Logger log = LogManager.getLogger(EditarAidfController.class);

	@Autowired
	private DataSource dataSourceRead;
	private PuntoVenta puntoVenta;
	
	private boolean isEstoqueSimplificado;

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

		super.doAfterCompose(comp);

		txtDocFiscal.setConstraint(new OnlyNumber());

		aidf = (Aidf) Executions.getCurrent().getArg().get("aidf");
		aidfList = (MyListbox) Executions.getCurrent().getArg().get("aidfList");

		lsAidfTipo = aidfService.obtenerTodosAdifTipo();
		lsAidfEspecie = aidfService.obtenerTodosAdifEspecie();
		lsEstado = estadoService.obtenerTodos();
		lsEmpresas = UsuarioLogado.getUsuarioLogado().getEmpresa();
		isEstoqueSimplificado = ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.VALIDA_ESTOQUE_SIMPLIFICADO.getDescricao(), true) ;
		lsInscestadual = new ArrayList<InscricaoEstadual>();
		
		if (ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.EXIBIR_PUNTO_VENTA_CADASTRO_AIDF.getDescricao())
				|| isEstoqueSimplificado) {
			
			if (ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.IS_PUNTOVENTA_CADASTRO_AIDF_OBRIGATORIO.getDescricao())) {
				cmbPuntoVenta.setConstraint("no empty");
			}
			
			rowPuntoVenta.setVisible(true);
			PuntoVenta pv = aidf.getPuntoVenta();
			if (pv != null) {
				List<PuntoVenta> ls = new ArrayList<PuntoVenta>();
				ls.add(pv);
				cmbPuntoVenta.setModel(new BindingListModelList(ls, false));
				cmbPuntoVenta.setText(pv.getNombpuntoventa());
			}
		}

		if (aidf.getAidfId() == null) {
			btnApagar.setVisible(Boolean.FALSE);			
		}else{
			if (temPermissao("ADM.AIDF.EDITARJACRIADA")) {
				btnSalvar.setDisabled(Boolean.TRUE);
			} else {
				if (detAbastoBoletoService.buscabDetAbastoBoletoToVerifyIfAidfCanBeEditable(aidf).size() > 0) {
					Messagebox.show(
							Labels.getLabel("editarAidfController.MSG.noWrite"),
							Labels.getLabel(TITULO),
							Messagebox.OK, Messagebox.INFORMATION);

					btnApagar.setVisible(Boolean.FALSE);
					btnSalvar.setVisible(Boolean.FALSE);
				}
			}
		}
		
		if( aidf.getFecadquisicion() == null && isEstoqueSimplificado){
			aidf.setFecadquisicion(Calendar.getInstance().getTime());
		}
	}

	private boolean temPermissao(String permissao) {
		Usuario usuario = usuarioService.obtenerID(UsuarioLogado.getUsuarioLogado().getUsuarioId());

		for (UsuarioPerfil up : usuario.getUsuarioPerfilList()) {
			List<PerfilFuncion> listPerfilFuncion = up.getPerfil().getPerfilFuncionList();
			for (PerfilFuncion pf : listPerfilFuncion) {
				if (pf.getFuncionSistema().getDescruta().equals(permissao)) {
					return true;
				}
			}
		}
		return false;
	}

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

		try {

			int opcao = Messagebox.show(
					Labels.getLabel("editarAidfController.btnApagar.MSG.Deseja.Borrar"),
					Labels.getLabel(TITULO),
					Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);

			if (opcao == Messagebox.YES) {
				aidf.setFecmodif(Calendar.getInstance().getTime());
				aidf.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
				aidf.setActivo(Boolean.FALSE);

				abastoHistoService.borrarLosQueTienenAIDF(aidf);
				abastoCentralService.borrarLosQueTienenAIDF(aidf);

				aidfService.borrar(aidf);
				aidfList.removeItem(aidf);

				Messagebox.show(
						Labels.getLabel("editarAidfController.btnApagar.MSG.borrarOK"),
						Labels.getLabel(TITULO),
						Messagebox.OK, Messagebox.INFORMATION);
				closeWindow();
			}

		} catch (Exception ex) {
			log.error("", ex);

			Messagebox.show(
					Labels.getLabel("MSG.Error"),
					Labels.getLabel(TITULO),
					Messagebox.OK, Messagebox.EXCLAMATION);
		}

	}

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

		cmbAidfEspecie.getValue();
		cmbAidfTipo.getValue();
		cmbEmpresa.getValue();
		cmbEstado.getValue();
		cmbInscestadual.getValue();
		txtSerie.getValue();
		txtForminicial.getValue();
		txtFormfinal.getValue();
		txtDocFiscal.getValue();
		if (ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.EXIBIR_PUNTO_VENTA_CADASTRO_AIDF.getDescricao())) {
			if(ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.IS_PUNTOVENTA_CADASTRO_AIDF_OBRIGATORIO.getDescricao())){
				cmbPuntoVenta.getValue();
			}
		}
		cmbTipoValidaVenta.getValue();

		try {

			Comboitem inscEstadualSeleccionada = cmbInscestadual.getSelectedItem();
			aidf.setInscestadual(inscEstadualSeleccionada != null ? inscEstadualSeleccionada.getValue().toString() : "");

			Long idIdf = isEstoqueSimplificado ? 
						aidfService.validarSerieFormInicialFinal(aidf, dataSourceRead.getConnection()):
						aidfService.validarDocFiscalSerieFormInicialFinal(aidf, dataSourceRead.getConnection());

			if (idIdf != -1) {
				Messagebox.show(
						isEstoqueSimplificado ? 
						Labels.getLabel("editarAidfController.btnSalvar.MSG.existeDados", new Object[] { idIdf }):
						Labels.getLabel("editarAidfController.btnSalvar.MSG.conflitoFormIniFin", new Object[] { idIdf }) ,						
						Labels.getLabel(TITULO),
						Messagebox.OK, Messagebox.EXCLAMATION);
				return;
			}

			Integer especieId = null;

			if (aidf.getAidfEspecie() != null) {
				especieId = aidf.getAidfEspecie().getAidfespId();
			}
			
			if (ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.EXIBIR_PUNTO_VENTA_CADASTRO_AIDF.getDescricao())) {
				if(ApplicationProperties.getInstance().isCustomHabilitado(CustomEnum.IS_PUNTOVENTA_CADASTRO_AIDF_OBRIGATORIO.getDescricao())){	
					PuntoVenta puntoVenta = (PuntoVenta) cmbPuntoVenta.getSelectedItem().getValue();
					aidf.setPuntoVenta(puntoVenta);
					if (!validarDocFiscalPorEstadoAgencia(aidf.getAidfId(), especieId, txtDocFiscal.getValue(), aidf.getForminicial(), aidf.getFormfinal(), aidf.getEstado(), aidf.getPuntoVenta())) {
						Messagebox.show(
								Labels.getLabel("editarAidfController.btnSalvar.MSG.conflitoDocFiscalEstadoAgencia"),
								Labels.getLabel(TITULO),
								Messagebox.OK, Messagebox.EXCLAMATION);
						return;
					}
				}
			} else {
				if (!validarDocFiscalEstado(aidf.getAidfId(), especieId, txtDocFiscal.getValue(), aidf.getEstado())) {
					Messagebox.show(
							Labels.getLabel("editarAidfController.btnSalvar.MSG.conflitoDocFiscalEstado"),
							Labels.getLabel(TITULO),
							Messagebox.OK, Messagebox.EXCLAMATION);
					return;
				}
			}

			if (!validarTipoVenda(aidf.getTipoValidaVenta(), aidf.getSerie(), aidf.getAidfTipo().getAidftipoId())) {
				Messagebox.show(
						Labels.getLabel("editarAidfController.btnSalvar.MSG.serieUNICTipoFormularioContinuoVendaMotoristaNaoPermitido"),
						Labels.getLabel(TITULO),
						Messagebox.OK, Messagebox.EXCLAMATION);
				return;
			}

			if (!validarVendaManual(aidf.getAidfTipo().getAidftipoId(), aidf.getSerie())) {
				Messagebox.show(
						Labels.getLabel("editarAidfController.btnSalvar.MSG.serieUNICTipoVendaManualNaoPermitido"),
						Labels.getLabel(TITULO),
						Messagebox.OK, Messagebox.EXCLAMATION);
				return;
			}

			aidf.setActivo(true);
			aidf.setFecmodif(Calendar.getInstance().getTime());
			aidf.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());

			if (aidf.getAidfId() == null) {
				aidfService.suscribir(aidf);
				aidfList.addItemNovo(aidf);
				
				if(isEstoqueSimplificado) {
					gravarDetAbastoAutomatico();
				}	
			} else {
				aidfService.actualizacion(aidf);
				aidfList.updateItem(aidf);
			}

			Messagebox.show(
					Labels.getLabel("editarMensajeController.MSG.suscribirOK"),
					Labels.getLabel(TITULO),
					Messagebox.OK, Messagebox.INFORMATION);

			closeWindow();

		} catch (SQLException e) {

			Messagebox.show(
					Labels.getLabel("MSG.Error"),
					Labels.getLabel(TITULO),
					Messagebox.OK, Messagebox.EXCLAMATION);

			log.error("", e);

		} catch (Exception ex) {
			log.error("", ex);

			Messagebox.show(
					Labels.getLabel("MSG.Error"),
					Labels.getLabel(TITULO),
					Messagebox.OK, Messagebox.EXCLAMATION);
		}

	}

	private boolean validarDocFiscalEstado(Long idAidf, Integer especieId, String docFiscal, Estado estado) {
		return aidfService.validarDocFiscalPorEstado(idAidf, especieId, docFiscal, estado);
	}

	private boolean validarDocFiscalPorEstadoAgencia(Long idAidf, Integer especieId, String docFiscal, String formInicial, String formFinal, Estado estado, PuntoVenta puntoVenta) {
		return aidfService.validarDocFiscalPorEstadoAgencia(idAidf, especieId, docFiscal, formInicial, formFinal, estado, puntoVenta);
	}

	private boolean validarTipoVenda(String tipoVenda, String serie, Integer tipo) {
		return aidfService.validarTipoVenda(tipoVenda, serie, tipo);
	}

	private boolean validarVendaManual(Integer tipo, String serie) {
		return aidfService.validarVendaManual(tipo, serie);
	}

	public void onChange$cmbEmpresa(Event ev) {
		Comboitem cbiEmpresa = cmbEmpresa.getSelectedItem();
		if (cbiEmpresa != null) {
			Empresa empresa = (Empresa) cbiEmpresa.getValue();

			lsInscestadual = new ArrayList<InscricaoEstadual>();
			lsInscestadual.addAll(empresaService.buscaInscricoesEstaduais(empresa));
			cmbInscestadual.setModel(new BindingListModelList(lsInscestadual, true));
		}
	}

	public void onBlur$txtSerie(Event ev) {
		try {
			txtSerie.getValue();
		} catch (WrongValueException e) {
			aidf.setSerie("");
			txtSerie.setValue("");
		}
	}

	public class OnlyNumber implements Constraint {
		public void validate(Component comp, Object value) throws WrongValueException {
			if (!value.toString().matches("[0-9]+")) {
				aidf.setDocfiscal(value.toString());
				throw new WrongValueException(comp, Labels.getLabel("editarAidfController.btnSalvar.MSG.apenasValoresNumericosPermitidos"));
			}
		}
	}

	private AbastoBoleto gravarAbastoAutomatico() {
		Date now = Calendar.getInstance().getTime();
		
		Articulo articulo = new Articulo(Articulo.TIPO_OUTRO);
		
		if( aidf.getAidfEspecie().getAidfespId().equals(1)){
			articulo = new Articulo(Articulo.TIPO_VENDA_MANUAL);
		}

		AbastoBoleto abastoboleto = new AbastoBoleto();
		abastoboleto.setNumservidor(1);
		abastoboleto.setCantfajilla( 1L );
		
		abastoboleto.setArticulo( articulo );
		abastoboleto.setClasificacion(new Clasificacion(38));
		abastoboleto.setPuntoventa(aidf.getPuntoVenta());
		abastoboleto.setPuntoventacentral(aidf.getPuntoVenta());
		abastoboleto.setEmpresa(aidf.getEmpresa());
		abastoboleto.setStatusfirma(2);
		abastoboleto.setStatusEnvio(1);
		abastoboleto.setUsuarioreqId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
		abastoboleto.setFechorfirma(now);
		abastoboleto.setFechorgeneracion(now);
		abastoboleto.setUsuariogeneracionId(UsuarioLogado.getUsuarioLogado().getUsuarioId());

		return abastoBoletoService.suscribir(abastoboleto);		
	}
	
	private DetAbastoBoleto gravarDetAbastoAutomatico() {

		AbastoBoleto abastoBoleto = gravarAbastoAutomatico();
		Long nummovimiento = detAbastoBoletoService.getSecuencia();

		DetAbastoBoleto detAbastoBoleto = new DetAbastoBoleto();
		detAbastoBoleto.setAbastoBoleto(abastoBoleto);
		detAbastoBoleto.setAidf(aidf);
		detAbastoBoleto.setNummovimiento(nummovimiento);
		detAbastoBoleto.setNumseriepreimpresa(aidf.obterSerieSubserieFormatada());
		detAbastoBoleto.setNumfolioinicial(aidf.getForminicial());
		detAbastoBoleto.setNumfoliofinal(aidf.getFormfinal());
		detAbastoBoleto.setStatusfirma(Boolean.TRUE);
		detAbastoBoleto.setStatusoperacion(0);
		detAbastoBoleto.setStatusenvio(Boolean.TRUE);

		return detAbastoBoletoService.suscribir(detAbastoBoleto);
	}

	public Aidf getAidf() {
		return aidf;
	}

	public void setAidf(Aidf aidf) {
		this.aidf = aidf;
	}

	public MyListbox getAidfList() {
		return aidfList;
	}

	public void setAidfList(MyListbox aidfList) {
		this.aidfList = aidfList;
	}

	public List<AidfEspecie> getLsAidfEspecie() {
		return lsAidfEspecie;
	}

	public void setLsAidfEspecie(List<AidfEspecie> lsAidfEspecie) {
		this.lsAidfEspecie = lsAidfEspecie;
	}

	public Combobox getCmbAidfEspecie() {
		return cmbAidfEspecie;
	}

	public void setCmbAidfEspecie(Combobox cmbAidfEspecie) {
		this.cmbAidfEspecie = cmbAidfEspecie;
	}

	public List<Estado> getLsEstado() {
		return lsEstado;
	}

	public void setLsEstado(List<Estado> lsEstado) {
		this.lsEstado = lsEstado;
	}

	public Combobox getCmbEstado() {
		return cmbEstado;
	}

	public void setCmbEstado(Combobox cmbEstado) {
		this.cmbEstado = cmbEstado;
	}

	public List<AidfTipo> getLsAidfTipo() {
		return lsAidfTipo;
	}

	public void setLsAidfTipo(List<AidfTipo> lsAidfTipo) {
		this.lsAidfTipo = lsAidfTipo;
	}

	public Combobox getCmbAidfTipo() {
		return cmbAidfTipo;
	}

	public void setCmbAidfTipo(Combobox cmbAidfTipo) {
		this.cmbAidfTipo = cmbAidfTipo;
	}

	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 Combobox getCmbInscestadual() {
		return cmbInscestadual;
	}

	public void setCmbInscestadual(Combobox cmbInscestadual) {
		this.cmbInscestadual = cmbInscestadual;
	}

	public List<InscricaoEstadual> getLsInscestadual() {
		return lsInscestadual;
	}

	public void setLsInscestadual(List<InscricaoEstadual> lsInscestadual) {
		this.lsInscestadual = lsInscestadual;
	}

	public Textbox getTxtDocFiscal() {
		return txtDocFiscal;
	}

	public void setTxtDocFiscal(Textbox txtDocFiscal) {
		this.txtDocFiscal = txtDocFiscal;
	}

	public Textbox getTxtAcFiscal() {
		return txtAcFiscal;
	}

	public void setTxtAcFiscal(Textbox txtAcFiscal) {
		this.txtAcFiscal = txtAcFiscal;
	}

	public Textbox getTxtSerie() {
		return txtSerie;
	}

	public void setTxtSerie(Textbox txtSerie) {
		this.txtSerie = txtSerie;
	}

	public Textbox getTxtSubSerie() {
		return txtSubSerie;
	}

	public void setTxtSubSerie(Textbox txtSubSerie) {
		this.txtSubSerie = txtSubSerie;
	}

	public Textbox getTxtForminicial() {
		return txtForminicial;
	}

	public void setTxtForminicial(Textbox txtForminicial) {
		this.txtForminicial = txtForminicial;
	}

	public Textbox getTxtFormfinal() {
		return txtFormfinal;
	}

	public void setTxtFormfinal(Textbox txtFormfinal) {
		this.txtFormfinal = txtFormfinal;
	}

	public Textbox getTxtFecAquisicao() {
		return txtFecAquisicao;
	}

	public void setTxtFecAquisicao(Textbox txtFecAquisicao) {
		this.txtFecAquisicao = txtFecAquisicao;
	}

	public Textbox getTxtFecVencimento() {
		return txtFecVencimento;
	}

	public void setTxtFecVencimento(Textbox txtFecVencimento) {
		this.txtFecVencimento = txtFecVencimento;
	}

	public Button getBtnApagar() {
		return btnApagar;
	}

	public void setBtnApagar(Button btnApagar) {
		this.btnApagar = btnApagar;
	}

	public Button getBtnSalvar() {
		return btnSalvar;
	}

	public void setBtnSalvar(Button btnSalvar) {
		this.btnSalvar = btnSalvar;
	}

	public Datebox getDtbFecadquisicion() {
		return dtbFecadquisicion;
	}

	public void setDtbFecadquisicion(Datebox dtbFecadquisicion) {
		this.dtbFecadquisicion = dtbFecadquisicion;
	}

	public Datebox getDtbFecvencimiento() {
		return dtbFecvencimiento;
	}

	public void setDtbFecvencimiento(Datebox dtbFecvencimiento) {
		this.dtbFecvencimiento = dtbFecvencimiento;
	}

	public Combobox getCmbTipoValidaVenta() {
		return cmbTipoValidaVenta;
	}

	public void setCmbTipoValidaVenta(Combobox cmbTipoValidaVenta) {
		this.cmbTipoValidaVenta = cmbTipoValidaVenta;
	}

	public PuntoVenta getPuntoVenta() {
		return puntoVenta;
	}

	public void setPuntoVenta(PuntoVenta puntoVenta) {
		this.puntoVenta = puntoVenta;
	}

}