package com.ag.secp.platform.common;

//import com.ag.entity.WbCompany;

import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2017/3/28 0028.
 */
public class SqlUtil<T> {

    public String getSaveSql(T t) {
        String tableName = getTableName(t);
        StringBuilder colSql = new StringBuilder();
        StringBuilder valueSql = new StringBuilder();

        Method[] ms = t.getClass().getMethods();
        for (Method m : ms) {
            String colName = getColName(m);
            //??????
            if (colName != null) {
                String colValue = getColValue(m, t, null);
                //????
                if (colValue != null) {
                    colSql.append("").append(colName).append("").append(",");
                    valueSql.append(colValue).append(",");
                }
            }
        }
        String saveSql = StrUtil.join("insert into " , tableName , "(" , subLastStr(colSql.toString()) , ") values (" , subLastStr(valueSql.toString()) , ")");
        return saveSql;
    }

    public String getUpdateSql(T t, String paramId) {
        String tableName = getTableName(t);
        StringBuilder setSql = new StringBuilder();
        String pkValue = "";//?????
        Method[] ms = t.getClass().getMethods();
        for (Method m : ms) {
            String colName = getColName(m);
            //??????
            if (colName != null) {
                String colValue = getColValue(m, t, "update");
                //????????
                if (colName.toLowerCase().equals(paramId.toLowerCase())) {
                    pkValue = colValue;
                    continue;
                }
                //????
                if (colValue != null) {
                    setSql.append("").append(colName).append("").append("=").append(colValue).append(",");
                }
            }
        }
        String updateSql = StrUtil.join("update " , tableName , " set " , subLastStr(setSql.toString()) , " where " , paramId , "=" , pkValue);
        return updateSql;
    }

    public String getDeleteSql(T t, String pkColName, String deleteColName) {
        String tableName = getTableName(t);
        String setSql = "";
        String whereSql = "";
        Method[] ms = t.getClass().getMethods();
        for (Method m : ms) {
            //????????
            if (deleteColName.equals(getColName(m))) {
                setSql = StrUtil.join("" , deleteColName , "=" , getColValue(m, t, null));
            }
            //????where??
            if (pkColName.equals(getColName(m))) {
                whereSql = StrUtil.join("" , pkColName , "=" , getColValue(m, t, null));
            }
        }
        String deleteSql = StrUtil.join("update " , tableName , " set " , setSql , " where " , whereSql);
        return deleteSql;
    }

    public String deleteSql(T t, String pkColName) {
        StringBuilder sql = new StringBuilder("delete from ");
        sql.append(getTableName(t)).append(" where ").append(pkColName).append(" = ");
        String pkValue = "";//?????
        Method[] ms = t.getClass().getMethods();
        for (Method m : ms) {
            String colName = getColName(m);
            // ??????
            if (colName != null) {
                String colValue = getColValue(m, t, "update");
                // ????????
                if (colName.toLowerCase().equals(pkColName.toLowerCase())) {
                    pkValue = colValue;
                    break;
                }
            }
        }
        sql.append(pkValue);
        return sql.toString();
    }

    public String deleteEqSql(T t, Object... colName) {
        String tableName = getTableName(t);
        String deleteSql = "delete from " + tableName;
        Method[] ms = t.getClass().getMethods();
        String whereSql = "";
        for (Method m : ms) {
            for (Object aColName : colName) {
                if (aColName.toString().equalsIgnoreCase(getColName(m))) {
                    String val = getColValue(m, t, null);
                    if (val != null) {
                        whereSql = StrUtil.join(whereSql,
                                " and ", aColName, "=", val);
                    } else {
                        throw new RuntimeException("删除方法中，列名" + aColName + "值不能为空！");
                    }
                    break;
                }
            }
        }
        if (!"".equals(whereSql)) {
            deleteSql += " where " + whereSql.substring(4, whereSql.length());
        } else {
            throw new RuntimeException("不能做整表删除！");
        }
        //System.out.println("deleteSql:"+deleteSql);
        return deleteSql;
    }

    private String getWhereSql(T t, Object... colName) {
        Method[] ms = t.getClass().getMethods();
        String whereSql = "";
        for (Method m : ms) {
            for (Object aColName : colName) {
                if (aColName.toString().equalsIgnoreCase(getColName(m))) {
                    String val = getColValue(m, t, null);
                    if (val != null) {
                        whereSql = StrUtil.join(whereSql,
                                " and ", aColName, "=", val);
                    }
                    break;
                }
            }
        }
        return whereSql;
    }


    public String getFindSql(T t, Class<T> returnType, String pkColName) {
        String tableName = getTableName(t);
        Method[] ms = t.getClass().getMethods();
        String whereSql = "";
        for (Method m : ms) {
            //????where??
            if (pkColName.equalsIgnoreCase(getColName(m))) {
                whereSql = StrUtil.join("" , pkColName , "=" , getColValue(m, t, null));
            }
        }
        String findSql = StrUtil.join("select * from " , tableName , " where " , whereSql);
        return findSql;
    }

    public String getFindAllSql(Class<T> claz) {
        String tableName = "";
        try {
            tableName = getTableName(claz.newInstance());
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        String findAllSql = "select * from " + tableName;
        return findAllSql;
    }

    public String getEqCriteriaSql(T t, Object... colName) {
        String tableName = getTableName(t);
        Method[] ms = t.getClass().getMethods();
        String whereSql = getWhereSql(t, colName);
        String findSql = "select * from " + tableName;
        if (!"".equals(whereSql)) {
            findSql += " where " + whereSql.substring(4, whereSql.length());
        }
        //System.out.println("findSql:"+findSql);
        return findSql;
    }

    /**
     * ??????????
     * ??????
     */
    protected String getTableName(T t) {
        String tableName = t.getClass().getSimpleName();
        //????????
        tableName = StrUtil.join(tableName.substring(0, 1).toLowerCase() , tableName.substring(1, tableName.length()));
        //??Entity
        //tableName = tableName.substring(0, tableName.indexOf("Entity"));
        //return "t_"+toLower(tableName)+"";
        return "C_" + toLower(tableName);
    }

    /**
     * ??????????
     * ???????????get?????
     */
    protected String getColName(Method m) {
        String name = m.getName();
        //???getClass?get*??
        if (!name.startsWith("get") || "getClass".equals(name)) {
            return null;
        } else {
            //????get
            String param = name.substring(3, name.length());
            //?????
            param = firstToLower(param);
            //????????????_
            return toLower(param);
        }
    }

    protected String getFieldName(Method m) {
        String name = m.getName();
        //???getClass?get*??
        if (!name.startsWith("set")) {
            return null;
        } else {
            String param = name.substring(3, name.length());
            return firstToLower(param);
        }
    }

    /**
     * ??value?????????
     */
    protected String getColValue(Method m, T t, String type) {
        Object value = null;
        try {
            //??????
            value = m.invoke(t);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (value == null) {
            return null;
        }
        if (value instanceof Integer) {
            return String.valueOf(value);
        } else if (value instanceof Long) {
            return String.valueOf(value);
        } else if (value instanceof Date) {

            return StrUtil.join("to_date('", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) value), "','yyyy-MM-dd HH24:mi:ss')");
        } else if (value instanceof Boolean) {
            return String.valueOf(value);
        } else if (value instanceof Double) {
            return String.valueOf(value);
        } else if (value instanceof Float) {
            return String.valueOf(value);
        } else if (value instanceof String) {
            //??update?????!=null?????????
            if ("update".equals(type)) {
                return StrUtil.join("'", value, "'");
            } else {
                if (!StringUtils.isEmpty(value)) {
                    return StrUtil.join("'", value, "'");
                }
            }
        }
        return null;
    }

    /**
     * ?????
     */
    protected String firstToLower(String param) {
        return StrUtil.join(param.substring(0, 1).toLowerCase() , param.substring(1, param.length()));
    }

    protected String firstToUpper(String param) {
        return StrUtil.join(param.substring(0, 1).toUpperCase() , param.substring(1, param.length()));
    }

    /**
     * ???????_?????
     */
    protected String toLower(String param) {
        StringBuilder sb = new StringBuilder();
        char[] col = param.toCharArray();
        for (char ch : col) {
            if (Character.isUpperCase(ch)) {
                sb.append("_").append(Character.toLowerCase(ch));
            } else {
                sb.append(ch);
            }
        }
        return sb.toString();
    }

    /**
     * ??????
     */
    private String subLastStr(String param) {
        return param.substring(0, param.length() - 1);
    }

    /**
     * ??????????
     */
    private Object getFieldValueByName(Object o, String fieldName) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = StrUtil.join("get" , firstLetter , fieldName.substring(1));
            Method method = o.getClass().getMethod(getter);
            return method.invoke(o);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * ??????????id1,id2,id3??
     *
     * @param lst
     * @param fieldName "userId"
     * @return
     */
    public String getAddInIds(List<T> lst, String fieldName) {
        String ids = "";
        for (T t : lst) {
            Object obj = getFieldValueByName(t, fieldName);
            if (obj instanceof String) {
                ids = StrUtil.join(ids, "'", obj, "',");
            } else {
                ids = StrUtil.join(ids, obj, ",");
            }
        }
        return subLastStr(ids);
    }


    public T getEntity(Class<T> tClz) {
        try {
            return tClz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) {



    }
}
