package br.com.elotech.util;

import br.com.elotech.Main;
import br.com.elotech.config.ConnectionUtil;
import br.com.elotech.enuns.SistemaEnum;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringEscapeUtils;
import org.htmlcleaner.HtmlCleaner;
import org.httprpc.sql.Parameters;

import java.io.File;
import java.net.URISyntaxException;
import java.sql.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

public abstract class Util {

  private static final Gson gson = new Gson();
  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 = ".png";

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

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

  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());
  }

  public static Date startDataInicial(Date dt) {
    if (dt != null) {
      return dt;
    }

    Calendar c = Calendar.getInstance();
    c.set(Calendar.YEAR, 1950);
    c.set(Calendar.MONTH, Calendar.JANUARY);
    c.set(Calendar.DAY_OF_MONTH, 1);
    return c.getTime();
  }

  public static String getJarPath() throws URISyntaxException {
    return new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent();
  }

  public static File getLogo(SistemaEnum sistema) throws URISyntaxException {
    return new File(new File(getJarPath()).getPath()
      .concat("/logos/".concat(sistema.name().toLowerCase()).concat(EXTENSION)));
  }

  public static String toCamelCase(String phrase) {
    while (phrase.contains("_")) {
      phrase = phrase
        .replaceFirst("_[a-z]", String.valueOf(Character.toUpperCase(phrase.charAt(phrase.indexOf("_") + 1))));
    }
    return phrase;
  }

  public static ResultSet resolveResultSet(String sql, Map<String, Object> params) throws SQLException {
    Parameters p = Parameters.parse(sql);
    if (!params.isEmpty()) {
      for (Map.Entry<String, Object> entry : params.entrySet()) {
        p.put(entry.getKey(), entry.getValue());
      }
    }
    Connection conn = ConnectionUtil.getConnection();
    PreparedStatement ps = conn.prepareStatement(p.getSQL());
    p.apply(ps);
    ResultSet rs = ps.executeQuery();
    conn.commit();
    conn.close();
    return rs;
  }

  public static ResultSet subResultSet(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.executeQuery();
  }

  public static boolean existColumn(ResultSet resultSet, String columnName) throws SQLException {
    ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
    int coulmnCount = resultSetMetaData.getColumnCount();
    for (int i = 1; i <= coulmnCount; i++) {
      if (columnName.equals(resultSetMetaData.getColumnName(i))) {
        return true;
      }
    }
    return false;
  }

  public static String removeHtmlFrom(String html) {
    return new HtmlCleaner().clean(StringEscapeUtils.unescapeHtml4(html)).getText().toString();
  }

  public static String getLabelCase(String filter) {
    StringBuilder sb = new StringBuilder();
    if (filter.contains("<")) {
      sb.append(filter.replace("<", "Menores que"));
    }
    if (filter.contains("BETWEEN")) {
      sb.append(filter.replace("BETWEEN", "Entre").replace("AND", "e"));
    }
    if (filter.contains("=")) {
      sb.append(filter.replace("=", ""));
    }
    if (filter.contains(">")) {
      sb.append(filter.replace(">", "Maiores que "));
    }
    return sb.append(" anos'").toString();
  }

  public static String getSexo(String filter) {
    switch (filter) {
    case "F":
      filter = "FEMININO";
      break;
    case "M":
      filter = "MASCULINO";
      break;
    }
    return filter;
  }

  public static boolean getStatus(String status) {
    return status.contains("A");
  }

  public static String getDataPorExtenso(Date data) {
    DateFormat sdf = new SimpleDateFormat("dd 'de' MMMMM 'de' yyyy", new Locale("pt", "BR"));
    return sdf.format(data);
  }

  public static String naoInformadoWhenNull(String valor) {
    return Objects.toString(valor, "NÃO INFORMADO");
  }

  public static String vazioWhenNull(String valor) {
    return Objects.toString(valor, "");
  }
}
