package br.com.elotech.util;

import br.com.elotech.Main;
import br.com.elotech.config.DadosBasicos;
import br.com.elotech.enuns.SistemaEnum;
import br.com.elotech.enuns.TipoRelEnum;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.sql.SQLException;
import java.util.*;

public class JasperCreator {
  private String filename;
  private String title;
  private String repo_jasper;
  private String export_path;
  private TipoRelEnum tipoRelEnum;
  private String temp = Util.getJarPath().concat("/report/");
  private JRDataSource dataSource;
  private Map<String, Object> params;

  public JasperCreator(SistemaEnum sistema, String filename, String title, List<?> dataSource, TipoRelEnum tipoRelEnum)
    throws Exception {
    if (dataSource.isEmpty()) {
      filename = "empty" .concat(sistema.name().toLowerCase());
    }
    this.filename = filename.toLowerCase();
    this.title = title;
    this.repo_jasper = "jasper/" .concat(sistema.toString().toLowerCase()).concat("/");
    this.tipoRelEnum = tipoRelEnum;
    this.dataSource = (dataSource.isEmpty() ? new JREmptyDataSource() : new JRBeanCollectionDataSource(dataSource));
    carregaDadosBasicos(sistema);
  }

  public void gerarPdf() throws Exception {
    export_path = temp + filename.concat("-").concat(new Date().getTime() + ".pdf");
    try {
      URL url = getClass().getClassLoader().getResource(repo_jasper.concat(filename).concat(".jrxml"));
      if (url != null) {
        JasperReport report = JasperCompileManager.compileReport(url.openStream());
        JasperPrint print = JasperFillManager.fillReport(report, params, dataSource);
        JRPdfExporter exporter = new JRPdfExporter();
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
        exporter.setParameter(JRExporterParameter.OUTPUT_FILE, new File(export_path));
        exporter.setParameter(JRPdfExporterParameter.METADATA_TITLE, title);
        //Produção
        exporter.exportReport();
        //Desenvolvimento
        //               JasperViewer viewer = new JasperViewer(print);
        //               viewer.setVisible(true);
        Path.print(export_path);
      } else {
        throw new Exception("Arquivo de relatório não encontrado. (" + filename + ".jrxml)");
      }
    } catch (Exception e) {
      e.printStackTrace();
      throw new Exception("Erro ao gerar arquivo pdf: " + e.getMessage());
    }

  }

  public void setFiltro(String filtro) {
    this.params.put("FILTRO", filtro);
  }

  public void addParameter(String key, Object value) {
    params.put(key, value);
  }

  private void carregaDadosBasicos(SistemaEnum sistema) throws IOException, URISyntaxException, SQLException {
    params = new HashMap<>();
    DadosBasicos db = new DadosBasicos();
    params.put("DADOS_BASICOS", db);

    File logo = Util.getLogo(sistema);
    InputStream is = (logo.exists()
      ? new FileInputStream(logo)
      : this.getClass().getClassLoader().getResource("img/logo_" + sistema.name().toLowerCase() + ".jpg").openStream());
    BufferedImage isLogo = ImageIO.read(is);
    params.put("LOGO", isLogo);
    params.put("TITULO", title.toUpperCase());

    Properties prop = readConfigProperties();
    params.put("VERSION",
      SistemaEnum.SAUDE.equals(sistema) ? prop.getProperty("versionSaude") : prop.getProperty("versionSocial"));

    if (tipoRelEnum != null) {
      params.put("TP_REL", tipoRelEnum.name());
    }
  }

  public Properties readConfigProperties() throws IOException {
    Properties prop = new Properties();
    prop.load(Main.class.getClassLoader().getResourceAsStream("config.properties"));
    return prop;
  }
}
