package com.keyware.shandan.dynacmicform.core.db;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.keyware.shandan.common.util.StreamUtil;
import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.dynacmicform.core.basic.entity.FormInfoPo;
import com.keyware.shandan.dynacmicform.core.basic.entity.QueryParam;
import com.keyware.shandan.dynacmicform.core.db.pojo.Column;
import com.keyware.shandan.dynacmicform.core.db.pojo.Table;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class SqlHelper {

    /**
     * 建表sql
     *
     * @param table
     * @return
     */
    public static String tableCreateSql(Table table) {
        StringBuilder sqlBuilder = new StringBuilder("CREATE TABLE ");
        sqlBuilder.append("\"").append(table.getName()).append("\" (");

        Column primaryKey = table.getPrimaryKey();
        sqlBuilder.append("\"").append(primaryKey.getName()).append("\" ").append(primaryKey.getType()).append(" IDENTITY(1, 1) NOT NULL,");
        table.getColumns().forEach(col -> {
            if (!col.isPrimary()) {
                sqlBuilder.append("\"").append(col.getName()).append("\" ").append(col.getType());
                // 根据类型判断是否追加长度参数
                if (col.getLength() != null && col.getLength() != 0) {
                    sqlBuilder.append("(").append(col.getLength()).append(") ");
                }
                if (StringUtils.hasText(col.getDefaultValue())) {
                    sqlBuilder.append("default ").append(col.getDefaultValue());
                }
                sqlBuilder.append(",");
            }
        });
        sqlBuilder.append("PRIMARY KEY(\"").append(primaryKey.getName()).append("\")").append(")");
        return sqlBuilder.toString();
    }

    public static String tableRenameSql(String oldTableName, String newTableName) {
        return StrUtil.format("alter table \"{}\" rename to \"{}\"", oldTableName, newTableName);
    }

    /**
     * 修改表的sql
     *
     * @param columns 修改的列集合
     * @return
     */
    public static List<String> tableAlterSql(Map<String, List<Column>> columns) {
        List<String> alterSqlList = new ArrayList<>();

        return alterSqlList;
    }

    /**
     * 删除表sql
     *
     * @param table
     * @return
     */
    public static String tableDropSql(Table table) {
        return "DROP TABLE \"" + table.getName() + "\"";
    }

    /**
     * 数据插入sql
     *
     * @param data
     * @return
     */
    public static String insertSql(@NotNull FormInfoPo form, @NotNull Map<String, Object> data) {
        List<String> placeholders = StreamUtil.as(data.keySet()).map((m) -> "?").toList();
        return "INSERT INTO \"" + form.getFormId() + "\" (" + String.join(",", data.keySet()) + ") " +
                "VALUES (" + String.join(",", placeholders) + ")";
    }

    /**
     * 数据更新sql
     *
     * @param dataParam
     * @return
     */
    public static String updateSql(FormInfoPo form, Map<String, Object> dataParam, QueryParam queryParam) {
        List<String> setDataSql = StreamUtil.as(dataParam.entrySet()).filter(entry -> !"id".equalsIgnoreCase(entry.getKey()))
                .map(entry -> " \"" + entry.getKey() + "\" = " + "? ").toList();

        return "UPDATE \"" + form.getFormId() + "\" SET " + String.join(",", setDataSql) + " " + queryParam.getSqlSegment();
    }

    /**
     * 数据删除sql
     *
     * @param param
     * @return
     */
    public static String deleteSql(FormInfoPo form, QueryParam param) {
        return "DELETE FROM  \"" + form.getFormId() + "\"  " + param.getSqlSegment();
    }

    /**
     * 数据查询sql
     *
     * @param param
     * @return
     */
    public static String selectSql(FormInfoPo form, QueryParam param) {
        if (param == null) {
            return "SELECT " + form.getQueryColumnsString() + " FROM \"" + form.getFormId() + "\"";
        }
        return "SELECT " + form.getQueryColumnsString() + " FROM \"" + form.getFormId() + "\" " + param.getSqlSegment() + " " + param.getOrderSqlSegment();
    }

    /**
     * 分页查询sql
     *
     * @param form  表单
     * @param param 参数
     * @return
     */
    public static String pageSelectSql(FormInfoPo form, QueryParam param) {
        Assert.isTrue(param.getPage() > 0 || param.getPageSize() > 0, "Sql语句构建异常，分页参数有误");
        int endOffset = param.getPage() * param.getPageSize();
        int startOffset = endOffset - param.getPageSize();
        return "SELECT * FROM ( SELECT TMP.*, ROWNUM ROW_ID FROM (" + selectSql(form, param) + " ) TMP WHERE ROWNUM <= " + endOffset + " ) WHERE  ROW_ID > " + startOffset;
    }

    /**
     * 统计记录行数sql
     *
     * @param form  表单
     * @param param 参数
     * @return
     */
    public static String countSql(FormInfoPo form, QueryParam param) {
        return "SELECT COUNT(ID) AS \"COUNT\" FROM \"" + form.getFormId() + "\" " + param.getSqlSegment();
    }

    /**
     * 生成SQL：修改表-删除列的SQL
     *
     * @param oldTable
     * @param newTable
     * @return
     */
    public static List<String> alterTableDropColumnSql(Table oldTable, Table newTable) {
        Map<String, Column> oldMap = new HashMap<>();
        oldTable.getColumns().forEach(column -> oldMap.put(column.getId(), column));
        newTable.getColumns().forEach(column -> {
            oldMap.remove(column.getId());
        });

        if (oldMap.size() > 0) {
            return oldMap.values().stream().map(column -> "alter table \"" + oldTable.getName() + "\" drop column \"" + column.getName() + "\"").collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 生成SQL：修改表-修改列名的SQL
     *
     * @param oldTable
     * @param newTable
     * @return
     */
    public static List<String> alterTableAlterColumnSql(Table oldTable, Table newTable) {
        Map<String, String> newMap = new HashMap<>();
        newTable.getColumns().forEach(column -> newMap.put(column.getId(), column.getName()));

        List<String> sqlList = new ArrayList<>();
        oldTable.getColumns().forEach(column -> {
            String oldName = column.getName();
            String newName = newMap.get(column.getId());
            if (!oldName.equals(newName) && StringUtils.hasText(newName)) {
                sqlList.add("alter table \"" + oldTable.getName() + "\" alter column \"" + oldName + "\" rename to \"" + newName + "\"");
            }
        });
        return sqlList;
    }

    /**
     * 生成SQL：修改表-修改列类型的SQL
     *
     * @param oldTable
     * @param newTable
     * @return
     */
    public static List<String> alterTableModifyColumnSql(Table oldTable, Table newTable) {

        return new ArrayList<>();
    }

    /**
     * 生成SQL：修改表-添加列的SQL
     *
     * @param oldTable
     * @param newTable
     * @return
     */
    public static List<String> alterTableAddColumnSql(Table oldTable, Table newTable) {
        Map<String, Column> newMap = new HashMap<>();
        newTable.getColumns().forEach(column -> newMap.put(column.getId(), column));
        oldTable.getColumns().forEach(column -> {
            newMap.remove(column.getId());
        });

        if (newMap.size() > 0) {
            return newMap.values().stream().map(column -> {
                String typeStr = column.getType();
                if (column.getLength() != null && column.getLength() != 0) {
                    typeStr += "(" + column.getLength() + ")";
                }
                String defaultValue = "";
                if (StringUtils.hasText(column.getDefaultValue())) {
                    defaultValue = "default " + column.getDefaultValue();
                }
                return "alter table \"" + oldTable.getName() + "\" add column(\"" + column.getName() + "\" " + typeStr + " " + defaultValue + ")";
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 生成SQL：表的注释SQL
     *
     * @param oldTable
     * @param newTable
     * @return
     */
    public static List<String> commentTableSql(Table oldTable, Table newTable) {

        return new ArrayList<>();
    }

    /**
     * 生成SQL：列的注释SQL
     *
     * @param oldTable
     * @param newTable
     * @return
     */
    public static List<String> commentColumnSql(Table oldTable, Table newTable) {

        return new ArrayList<>();
    }

}
