package br.com.elotech.commom;

import br.com.elotech.controllers.MainController;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.httprpc.sql.Parameters;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

public abstract class Util {

  private static final Logger logger = Logger.getLogger(MainController.class);

  private static final Gson gson = new Gson();
  private static final ClassLoader loader = Util.class.getClassLoader();

  private static final String HOMO_PATH = "WebESO\\html\\WebSocialUtil\\";
  private static final DateFormat format = new SimpleDateFormat("ddMMyyyy");
  private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  private static final DateFormat dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  private static final DateFormat df_BR = new SimpleDateFormat("dd/MM/yyyy");
  private static final DateFormat dtf_BR = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
  private static final String EXTENSION = ".txt";

  //Funções de Arquivo
  public static String getPath(String folder) throws Exception{
    String jarpath = System.getProperty("user.dir");
    if(jarpath.contains(HOMO_PATH)){
      URL resource = loader.getResource(folder);
      logger.info("Ambiente de Homologacao");
      return resource.getPath();
    }else{
      logger.info("Ambiente de Producao");
      return jarpath;
    }
  }

  public static File getFile () throws Exception {
    File files[] = new File(getPath("file")).listFiles();
    for(File arquivo: files){
      if(arquivo.getName().toLowerCase().contains(".txt")){
        logger.info("Arquivo de importacao: ".concat(arquivo.getName().toLowerCase()));
        return arquivo;
      }
    }
    logger.warn("NENHUM ARQUIVO ENCONTRADO");
    return null;
  }

  public static void excluiArquivo(File file) {
    try{
      Files.deleteIfExists(Paths.get(file.toURI()));
      logger.info("Arquivo " + file.getName() + " deletado.");
    }catch (IOException e) {
      logger.error("Arquivo "  + file.getName() + " nao foi deletado!", e);
    }
  }

  //Funções de Propriedades
  public static Properties getProp(PROP_FILE prop_file){
    Properties prop = new Properties();
    String file = null;
    try {
      file = "prop/".concat(prop_file.name().toLowerCase()).concat(".properties");
      prop.load(loader.getResource(file).openStream());
    } catch (Exception e) {
      logger.error("Erro ao carregar arquivo de propriedade: ".concat(file) , e);
    }
    return prop;
  }

  public static String getStringOfProp(String line, String pos, String tam){
    int inicio = Integer.parseInt(pos) - 1;
    int fim = inicio + Integer.parseInt(tam);
    return StringUtils.substring(line, inicio, fim).trim();
  }

  public static Date getDateOfProp(String line, String pos, String tam) throws ParseException {
    int inicio = Integer.parseInt(pos) - 1;
    int fim = inicio + Integer.parseInt(tam);
    String value = StringUtils.substring(line, inicio, fim).trim();
    if(StringUtils.isNotBlank(value)){
      return format.parse(value);
    }
    return null;
  }

  public static Object decodeArgsToJson(String arg, Class classe) {
    byte[] decoded = Base64.getMimeDecoder().decode(arg);
    return fromJsom(new String(decoded), classe);
  }

  public static String convertBase64(String arg) {
    byte[] decoded = Base64.getMimeDecoder().decode(arg);
    return new String(decoded);
  }

  public static Object fromJsom(String obj, Class classe) {
    return gson.fromJson(obj, classe);
  }

  public static String removerCaracteresEspeciais(String valor){
    String v = "";
    if(StringUtils.isNotBlank(valor)){
      v = StringUtils.lowerCase(valor);
      v = StringUtils.replacePattern(v, "[áàâã]", "a");
      v = StringUtils.replacePattern(v, "[éèê]", "e");
      v = StringUtils.replacePattern(v, "[íï]", "i");
      v = StringUtils.replacePattern(v, "[óôõö]", "o");
      v = StringUtils.replacePattern(v, "[ú]", "u");
      v = StringUtils.replacePattern(v, "[ç]", "c");
      v = StringUtils.replacePattern(v, "[ñ]", "n");
      v = StringUtils.replacePattern(v, "[^a-z0-9]", "");
    }
    return v;
  }

  //Funções de Banco
  public static ResultSet subResultSet(String sql, Map<String, Object> params, Connection conn) throws SQLException {
    PreparedStatement ps = prepareStatement(sql, params, conn);
    return ps.executeQuery();
  }

  public static void insert(String sql, Map<String, Object> params) throws Exception {
    Connection conn = ConnectionUtil.getConnection();
    PreparedStatement ps = prepareStatement(sql, params, conn);
    if(ps.executeUpdate() > 0){
      conn.close();
    }
  }

  public static ResultSet resolveResultSet(String sql, Map<String, Object> params) throws Exception {
    Connection conn = ConnectionUtil.getConnection();
    PreparedStatement ps = prepareStatement(sql, params, conn);
    ResultSet rs = ps.executeQuery();
    conn.commit();
    conn.close();
    return rs;
  }

  private static PreparedStatement prepareStatement(String sql, Map<String, Object> params, Connection conn) throws SQLException {
    Parameters p = Parameters.parse(sql);
    if(!params.isEmpty()){
      for (Map.Entry<String, Object> entry : params.entrySet()) {
        p.put(entry.getKey(), entry.getValue());
      }
    }

    PreparedStatement ps = conn.prepareStatement(p.getSQL());
    p.apply(ps);
    return ps;
  }
  //Funções de Data
  public static String formatDateBD(Date dt) {
    return df.format(dt);
  }

  public static String formatDateTimeBD(Date dt) {
    return dtf.format(dt);
  }

  public static String formatDateBR(Date dt) {
    return df_BR.format(dt);
  }

  public static String formatDateTimeBR(Date dt) {
    return dtf_BR.format(dt);
  }

  public static Timestamp dateToTimeStamp(Date dt) {
    return new Timestamp(dt.getTime());
  }

  public static java.sql.Date dateToSqlDate(Date dt) {
    return new java.sql.Date(dt.getTime());
  }
}
