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

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

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.Filedownload;
import org.zkoss.zk.ui.Component;
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.entidad.Empresa;
import com.rjconsultores.ventaboletos.service.EmpresaService;
import com.rjconsultores.ventaboletos.service.SisdapService;
import com.rjconsultores.ventaboletos.web.utilerias.MyGenericForwardComposer;

@Controller("relatorioSisdapController")
@Scope("prototype")
public class RelatorioSisdapController extends MyGenericForwardComposer {

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

	private Integer MAX_BUFFER_ZIP = Integer.valueOf(18024);

	private Datebox datInicio;
	private Datebox datFinal;
	private Empresa empresa;
	private Combobox cmbEmpresa;

	@Autowired
	private EmpresaService empresaService;

	@Autowired
	private SisdapService sisdapService;

	private List<Empresa> lsEmpresa;

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		lsEmpresa = empresaService.obtenerTodos();

		super.doAfterCompose(comp);
	}

	public void onClick$btnExecutarRelatorio(Event ev) throws Exception {
		if (cmbEmpresa.getSelectedIndex() < 0) {
			Messagebox.show(Labels.getLabel("relatorioSisdapController.MSG.empresaErro"),
					Labels.getLabel("filtroRelatorioSisdap.window.title"),
					Messagebox.OK, Messagebox.INFORMATION);
			return;
		}
		processarRelatorioSisdap(datInicio.getValue(), datFinal.getValue());
		closeWindow();
	}

	private void zipFiles(String[] filesToZip, String fileOutputName) {
		byte[] buffer = new byte[MAX_BUFFER_ZIP];

		try {
			ZipOutputStream out = new ZipOutputStream(new FileOutputStream(fileOutputName));

			// Ajusta modo de compressão
			out.setLevel(Deflater.DEFAULT_COMPRESSION);

			// faz a iteração sobre os arquivos, adicionando-os ao arquivo ZIP
			for (int i = 0; i < filesToZip.length; i++) {

				FileInputStream in = new FileInputStream(filesToZip[i]);

				// Add ZIP entry to output stream.
				out.putNextEntry(new ZipEntry(filesToZip[i]));

				// Transfer bytes from the current file to the ZIP file
				int len;
				while ((len = in.read(buffer)) > 0) {
					out.write(buffer, 0, len);
				}

				// Close the current entry
				out.closeEntry();

				// Close the current file input stream
				in.close();
			}

			// Close the ZipOutPutStream
			out.close();

		} catch (IllegalArgumentException iae) {
			log.error("", iae);
		} catch (FileNotFoundException fnfe) {
			log.error("", fnfe);
		} catch (IOException ioe) {
			log.error("", ioe);
		}
	}

	private void processarRelatorioSisdap(Date fecInicio, Date fecFinal) {

		List<String> movimentoLinhas = sisdapService.getMovimentoLinhas(fecInicio, fecFinal, empresa.getEmpresaId());
		List<String> movimentoSecoes = sisdapService.getMovimentoSecoes(fecInicio, fecFinal, empresa.getEmpresaId());

		if (movimentoLinhas.size() <= 1 && movimentoSecoes.size() <= 1) {
			// Não retornou dados
			try {
				Messagebox.show(Labels.getLabel("relatorioSisdapController.MSG.nenhumRegistro"),
						Labels.getLabel("filtroRelatorioSisdap.window.title"),
						Messagebox.OK, Messagebox.INFORMATION);
			} catch (InterruptedException e) {
				log.error("", e);
			}
			return;
		}

		exportarZip(movimentoLinhas, movimentoSecoes);

	}

	private void exportarZip(List<String> movimentoLinhas, List<String> movimentoSecoes) {
		try {
			FileWriter writer = new FileWriter("movimentoLinhas.txt");
			for (String str : movimentoLinhas) {
				writer.write(str + "\r\n");
			}
			writer.close();

			writer = new FileWriter("movimentoSecoes.txt");
			for (String str : movimentoSecoes) {
				writer.write(str + "\r\n");
			}
			writer.close();

			String[] files = new String[] { "movimentoLinhas.txt", "movimentoSecoes.txt" };
			zipFiles(files, "sisdap.zip");

			FileInputStream is = new FileInputStream("sisdap.zip");
			Filedownload.save(is, "application/zip", "sisdap.zip");
		} catch (Exception e) {
			log.error("", e);
		}
	}

	public Empresa getEmpresa() {
		return empresa;
	}

	public void setEmpresa(Empresa empresa) {
		this.empresa = empresa;
	}

	public List<Empresa> getLsEmpresa() {
		return lsEmpresa;
	}

	public void setLsEmpresa(List<Empresa> lsEmpresa) {
		this.lsEmpresa = lsEmpresa;
	}
}
