package br.com.elotech.util;

import br.com.elotech.Main;
import br.com.elotech.config.ConnectionUtil;
import com.google.gson.Gson;
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.Map;

public abstract class Util {

    static String ADICIONA = "1";
    static String REDUZ = "-1";

    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) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, 1950);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DAY_OF_MONTH, 1);
        return (dt == null ? c.getTime() : dt);
    }

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


    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 int insertOrUpdate(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);
        int ret = ps.executeUpdate();
        conn.commit();
        conn.close();
        return ret;
    }

    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 Date adicionaDia(Date dt){
        Calendar c = Calendar.getInstance();
        c.setTime(dt);
        c.add(c.DAY_OF_MONTH, +1);
        return c.getTime();
    }
}
