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

import java.io.ByteArrayOutputStream;
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.apache.commons.lang.BooleanUtils;
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.zhtml.Messagebox;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zul.Button;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Radio;
import org.zkoss.zul.Row;
import org.zkoss.zul.Textbox;

import com.rjconsultores.ventaboletos.entidad.Categoria;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.EmpresaEmailConfig;
import com.rjconsultores.ventaboletos.entidad.UsuarioUbicacion;
import com.rjconsultores.ventaboletos.enums.MimeType;
import com.rjconsultores.ventaboletos.relatorios.impl.RelatorioMensalDAER;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.SaidaRelatorio;
import com.rjconsultores.ventaboletos.service.CategoriaService;
import com.rjconsultores.ventaboletos.service.EmpresaEmailConfigService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.SendMail;
import com.rjconsultores.ventaboletos.utilerias.SendMail.AuthType;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.comissao.EmailConfigVO;
import com.rjconsultores.ventaboletos.web.utilerias.MyComboboxEstandar;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;
import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;

@Controller("relatorioMensalDAERController")
@Scope("prototype")
public class RelatorioMensalDAERController extends MyGenericForwardComposer {
	private static final long serialVersionUID = 1L;
	private static Logger log = LogManager.getLogger(RelatorioMensalDAERController.class);
	
	@Autowired
	private DataSource dataSourceRead;
	
	@Autowired 
	private CategoriaService tipoVentaService;
	
	@Autowired
	private EmpresaEmailConfigService empresaEmailConfigService;
	
	private Textbox txtCompetencia;
	private Textbox txtEmail;
	private List<Empresa> lsEmpresas;
	private Combobox cmbEmpresa;
	private List<UsuarioUbicacion> lsAgencias;
	private String agenciasUsuario;
	private Boolean isPDF = true;
	private List<Categoria> lsTipoVenta;
	private MyListbox selectedTipoVentaList;
	private List<Categoria> listSelectedTipoVenta;
	private MyComboboxEstandar cmbTipoVenta;
	private Radio rdTipoAnexoPDF; 
	private Radio rdTipoAnexoXLS;
	private Radio rdEmailSim;
	private Radio rdEmailNao;
	private Row rowTipoAnexo;
	private Row rowSendTo;
	private Button btnEnviarEmailMensalDAER;
	

	private void executarRelatorio(boolean isEnviarEmail) throws Exception {
		try {
			Map<String, Object> parametros = new HashMap<String, Object>();
			String competencia = txtCompetencia.getValue().toString();
			// Filtro Data Inicial	
			if(competencia.isEmpty()) {
				Messagebox.show(Labels.getLabel("relatorioMensalDAERController.data.obrigatoria"),
	                    Labels.getLabel("relatorioMensalDAERController.window.title"),
	                    Messagebox.OK, Messagebox.INFORMATION);
				 return;
			} else {
				
				Date periodo = DateUtil.getDateFromString("01/"+competencia, "dd/MM/yyyy");
				Date dateInicio = DateUtil.inicioFecha(periodo);
				parametros.put("DATA_INICIO", dateInicio);
				
				// Filtro Data Final
				competencia = txtCompetencia.getValue().toString();
				parametros.put("MES", competencia.substring(0,2));
				parametros.put("ANO", competencia.substring(3)); 

				Date dateFim =  DateUtil.getDataFinalCompetencia(competencia);
				parametros.put("DATA_FINAL", dateFim);
			}

			// Filtro Empresa
			Empresa empresa = null;
			if (cmbEmpresa.getSelectedItem() != null) {
				empresa = (Empresa) cmbEmpresa.getSelectedItem().getValue();
			} else {
				Messagebox.show(Labels.getLabel("relatorioMensalDAERController.empresa.obrigatoria"),
	                    Labels.getLabel("relatorioMensalDAERController.window.title"),
	                    Messagebox.OK, Messagebox.INFORMATION);
				 return;
			}
			
			parametros.put("EMPRESA", empresa);
			parametros.put("NOMBEMPRESA", empresa != null ? empresa.getNombempresa() : "TODOS");

			// Filtro usuário Id
			parametros.put("USUARIO_ID", UsuarioLogado.getUsuarioLogado().getUsuarioId().toString());
			
			// Filtro nome usuário
			parametros.put("NOME_USUARIO", UsuarioLogado.getUsuarioLogado().getNombusuario().toString());
			parametros.put("AGENCIA", agenciasUsuario);
			parametros.put("RODOVIARIA", UsuarioLogado.getUsuarioLogado().getUsuarioUbicacionPadrao().getPuntoVenta().getNombpuntoventa().toString());
			parametros.put("ESTACION", "");
			
			StringBuilder tipVenta = new StringBuilder();
			StringBuilder tipVentaIds = new StringBuilder();
			List<Integer> listCategoria = new ArrayList<Integer>();
			String todos = "-1";
			
			if (!listSelectedTipoVenta.isEmpty()) {
				for (Categoria venta : listSelectedTipoVenta) {
					tipVenta.append(venta.getDesccategoria()).append(",");
					if (todos.equals(venta.getCategoriaId().toString())) {
						tipVentaIds = new StringBuilder();
						tipVentaIds.append("");
						break;  
					}
					listCategoria.add(venta.getCategoriaId());
				}
				
			}

			Relatorio relatorio = new RelatorioMensalDAER(parametros, dataSourceRead.getConnection(), listCategoria);
			
			if (isEnviarEmail) {

				Boolean enviado = enviarEmailDAER(relatorio.getConteudo(isPDF ? SaidaRelatorio.PDF : SaidaRelatorio.XLS), empresa.getEmpresaId(), txtEmail.getValue().toString());
				if (!enviado) {
					Messagebox.show(
							Labels.getLabel("relatorioMensalDAERController.recibo.email.naoEnvio"),
							Labels.getLabel("relatorioMensalDAERController.window.title"),
							Messagebox.OK, Messagebox.EXCLAMATION);
				} else {
					Messagebox.show(
							Labels.getLabel("relatorioMensalDAERController.recibo.email.msg"),
							Labels.getLabel("relatorioMensalDAERController.window.title"),
							Messagebox.OK, Messagebox.INFORMATION);
				}

			} else {
				Map<String, Object> args = new HashMap<String, Object>();
				args.put("relatorio", relatorio);

				// Abre a janela do relatório
				openWindow("/component/reportView.zul",
						Labels.getLabel("relatorioMensalDAERController.window.title"), args, MODAL);
			}

		} catch (Exception e) {
			log.error("Erro ao executar relatório", e);
		}

	}
	
	public void onClick$btnEnviarEmailMensalDAER(Event ev) throws Exception {
		executarRelatorio(true);
	}
	
	public void onClick$btnExecutarRelatorio(Event ev) throws Exception {
		executarRelatorio(false);
	}
	
	public void onClick$btnRemoveTipoVenta(Event ev) throws InterruptedException {
		Categoria tVenta = (Categoria) selectedTipoVentaList.getSelectedItem().getValue();
		listSelectedTipoVenta.remove(tVenta);
		selectedTipoVentaList.setData(listSelectedTipoVenta);
	}

	public void onClick$btnAddTipoVenta(Event ev) throws InterruptedException {
		if (cmbTipoVenta.getSelectedItem() != null) {
			listSelectedTipoVenta.add((Categoria) cmbTipoVenta.getSelectedItem().getValue());
			selectedTipoVentaList.setData(listSelectedTipoVenta);
			selectedTipoVentaList.setSelectedItem(null);
		}
	}
	
	public boolean enviarEmailDAER(byte[] anexo, Integer empresaId, String email) {
		try {
			EmailConfigVO emailConfig = carregarConfiguracoesEmail(empresaId);
			if (emailConfig != null) {
				SendMail mail = new SendMail();
				mail.setEmailTo(email);
				mail.setEmailFrom(emailConfig.getSmtpEmail());
				mail.setSmtpHost(emailConfig.getSmtp());
				mail.setSmtpPassword(emailConfig.getSenha());
				mail.setSmtpPort(emailConfig.getSmtpPorta());
				mail.setSmtpUser(emailConfig.getSmtpEmail());
				mail.setAuth(emailConfig.isAutenticacao());
				
				if (StringUtils.isNotEmpty(emailConfig.getTipoAutorizacao())) {
					mail.setAuthType(AuthType.valueOf(emailConfig.getTipoAutorizacao()));
				}

				String assunto = null;
				String texto = null;
				String nomeArquivo = null;
				String competencia = txtCompetencia.getValue().toString();
				String formato = isPDF ? ".PDF" : ".XLS";

				assunto = Labels.getLabel("relatorioMensalDAERController.recibo.email.assunto", new String[] { Labels.getLabel("relatorioMensalDAERController.lbCompetencia.label"), competencia });
				texto = Labels.getLabel("relatorioMensalDAERController.recibo.email.texto", new String[] { Labels.getLabel("relatorioMensalDAERController.lbCompetencia.label"), competencia });
				nomeArquivo = "Relatorio_DAER_" + competencia;

				mail.setSubject(assunto);
				mail.setText(texto);

				ByteArrayOutputStream baos = new ByteArrayOutputStream(anexo.length);
				baos.write(anexo, 0, anexo.length);

				mail.addAnexo(Labels.getLabel("relatorioMensalDAERController.recibo.email.nomeAnexo", new String[] { nomeArquivo }).concat(formato), baos, isPDF ? MimeType.PDF : MimeType.XLS );
				mail.send();

				return true;
			}

		} catch (

		Exception e) {
			log.error(e.getMessage(), e);
		}
		return false;
	}
	
	private EmailConfigVO carregarConfiguracoesEmail(Integer empresaId) {
		EmailConfigVO emailConfigVO = null;
		EmpresaEmailConfig empresaEmailConfig = empresaEmailConfigService.buscarPorEmpresa(new Empresa(empresaId));

		if (empresaEmailConfig != null) {
			emailConfigVO = new EmailConfigVO();
			emailConfigVO.setAutenticacao(BooleanUtils.toBoolean(empresaEmailConfig.getIndAutenticacao()));
			emailConfigVO.setSenha(empresaEmailConfig.getSenha());
			emailConfigVO.setSmtp(empresaEmailConfig.getSmtp());
			emailConfigVO.setSmtpEmail(empresaEmailConfig.getSmtpEmail());
			emailConfigVO.setSmtpUser(empresaEmailConfig.getSmtpEmail());
			emailConfigVO.setSmtpPorta(empresaEmailConfig.getSmtpPorta());
		}

		return emailConfigVO;
	}

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		lsEmpresas = UsuarioLogado.getUsuarioLogado().getEmpresa();
		lsAgencias = UsuarioLogado.getUsuarioLogado().getUsuarioUbicacionActivoList();
		lsTipoVenta = tipoVentaService.buscarCategoriaOrgaoConcedente("DAER");
		//lsTipoVenta = tipoVentaService.buscarCategoriaOrgaoConcedente("DAER");
		listSelectedTipoVenta = new ArrayList<Categoria>();
		StringBuilder agencias = new StringBuilder(); 
					
		for (int i =0; i< lsAgencias.size() ; i++) {
			agencias.append(lsAgencias.get(i).getPuntoVenta().getPuntoventaId().toString());
			if(lsAgencias.size() > 1 && i < lsAgencias.size() -1) {
				agencias.append(", ");
			}
		}
		this.agenciasUsuario = agencias.toString();
	}
	
	public void onCheck$rdTipoAnexoPDF() {
		if (rdTipoAnexoPDF.isChecked()) {
			tipoRelatorio(true);
		}
	}
	
	private void tipoRelatorio(boolean isPDFSelected) {
		isPDF = isPDFSelected;
	}

	public void onCheck$rdTipoAnexoXLS() {
		if (rdTipoAnexoXLS.isChecked()) {
			tipoRelatorio(false);
		}
	}
	
	public void onCheck$rdEmailSim() {
		if (rdEmailSim.isChecked()) {
			controlRowVisibility(true);
		}
	}

	public void onCheck$rdEmailNao() {
		if (rdEmailNao.isChecked()) {
			controlRowVisibility(false);
		}
	}
	
	private void controlRowVisibility(Boolean isvisivel) {
			rowTipoAnexo.setVisible(isvisivel);
			rowSendTo.setVisible(isvisivel);
			btnEnviarEmailMensalDAER.setDisabled(!isvisivel);
	}

	public MyListbox getSelectedTipoVentaidadeList() {
		return selectedTipoVentaList;
	}

	public void setSelectedTipoVentaList(MyListbox selectedTipoVentaList) {
		this.selectedTipoVentaList = selectedTipoVentaList;
	}

	public List<Categoria> getListSelectedTipoVenta() {
		return listSelectedTipoVenta;
	}

	public void setListSelectedTipoVenta(List<Categoria> listSelectedTipoVenta) {
		this.listSelectedTipoVenta = listSelectedTipoVenta;
	}

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

	public void setLsEmpresa(List<Empresa> lsEmpresas) {
		this.lsEmpresas = lsEmpresas;
	}
	
	public List<UsuarioUbicacion> getLsAgencias() {
		return lsAgencias;
	}

	public void setLsAgencia(List<UsuarioUbicacion> lsAgencias) {
		this.lsAgencias = lsAgencias;
	}
	
	public List<Categoria> getLsTipoVenta() {
		return lsTipoVenta;
	}

	public void setLsCategorias(List<Categoria> lsTipoVenta) {
		this.lsTipoVenta = lsTipoVenta;
	}

}
