package com.hotent.common.Gennerator;

import com.hotent.surveyinfo.model.CostSurveyTemplateHeaders;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

@Component
public class DynamicTableGenerator {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    // 流水号计数器（在实际应用中可能需要持久化）
    private final AtomicInteger sequenceCounter = new AtomicInteger(0);
    
    /**
     * 生成表名，规则为固定名称+年月日+四位流水号
     * @param baseName 固定名称部分
     * @return 生成的表名
     */
    public String generateTableName(String baseName) {
        // 获取当前日期
        String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        
        // 获取并递增流水号
        int sequence = sequenceCounter.incrementAndGet();
        
        // 格式化流水号为4位数字，不足补0
        String sequenceStr = String.format("%04d", sequence);
        
        // 组合表名
        return baseName + "_" + dateStr  + sequenceStr;
    }
    
    /**
     * 根据模板ID动态创建表
     * @param templateId 模板ID
     * @param baseName 表名前缀
     * @param headers 表头信息列表
     * @return 生成的表名
     */
    public String createDynamicTable(String templateId, String baseName, List<CostSurveyTemplateHeaders> headers) {
        // 生成表名
        String tableName = generateTableName(baseName);
        
        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append("CREATE TABLE ").append(tableName).append(" (");

        // 添加默认字段
        sqlBuilder.append("id VARCHAR(50) PRIMARY KEY COMMENT '主键', ");
        sqlBuilder.append("period VARCHAR(64) COMMENT '期间', ");
        sqlBuilder.append("dictid VARCHAR(64) COMMENT '字典ID', ");
        sqlBuilder.append("createBy VARCHAR(64) COMMENT '创建人', ");
        sqlBuilder.append("createtime DATETIME COMMENT '创建时间', ");
        sqlBuilder.append("caluctfomat text COMMENT '公式计算', ");
        sqlBuilder.append("ordername varchar(255) COMMENT '序号', ");
        sqlBuilder.append("note TEXT COMMENT '备注', ");
        
        // 根据CostSurveyTemplateHeaders动态添加字段
        for (CostSurveyTemplateHeaders header : headers) {
            String columnName = header.getFieldName();
            String columnType = getDatabaseColumnType(
                header.getFieldType(), 
                header.getFieldTypelen().toString(),
                header.getFieldTypenointlen().toString()
            );
            
            // 处理列名，确保符合数据库命名规范
            String safeColumnName = sanitizeColumnName(columnName);
            
            sqlBuilder.append("`").append(safeColumnName).append("` ")
                      .append(columnType);
            
            // 根据isRequired字段判断是否必填
            if ("Y".equalsIgnoreCase(header.getIsRequired())) {
                sqlBuilder.append(" NOT NULL");
            }

            sqlBuilder.append(" COMMENT '").append(columnName.replace("'", "''")).append("', ");
        }
        
        // 删除最后的逗号和空格
        String sql = sqlBuilder.toString();
        sql = sql.substring(0, sql.length() - 2);
        sql += ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='成本调查记录表'";
        
        // 执行建表语句
        jdbcTemplate.execute(sql);
        
        return tableName;
    }
    
    /**
     * 根据字段类型信息获取数据库列类型
     * @param fieldType 字段类型
     * @param fieldTypelen 字段长度
     * @param fieldTypenointlen 小数位长度
     * @return 数据库列类型
     */
    private String getDatabaseColumnType(String fieldType, String fieldTypelen, String fieldTypenointlen) {
        if (fieldType == null) {
            return "VARCHAR(255)";
        }
        
        switch (fieldType.toUpperCase()) {
            case "VARCHAR":
            case "CHAR":
                if (fieldTypelen != null && !fieldTypelen.isEmpty()) {
                    try {
                        int length = Integer.parseInt(fieldTypelen);
                        // 限制最大长度
                        if (length > 65535) length = 65535;
                        return fieldType.toUpperCase() + "(" + length + ")";
                    } catch (NumberFormatException e) {
                        return "VARCHAR(255)";
                    }
                } else {
                    return "VARCHAR(255)";
                }
            case "INT":
            case "INTEGER":
                return "INT";
            case "BIGINT":
                return "BIGINT";
            case "DECIMAL":
            case "NUMERIC":
                StringBuilder decimalType = new StringBuilder("DECIMAL");
                if (fieldTypelen != null && !fieldTypelen.isEmpty()) {
                    try {
                        int precision = Integer.parseInt(fieldTypelen);
                        if (precision > 65) precision = 65; // MySQL最大精度
                        
                        if (fieldTypenointlen != null && !fieldTypenointlen.isEmpty()) {
                            try {
                                int scale = Integer.parseInt(fieldTypenointlen);
                                if (scale > 30) scale = 30; // MySQL最大小数位
                                if (scale > precision) scale = precision; // 小数位不能大于总位数
                                decimalType.append("(").append(precision).append(",").append(scale).append(")");
                            } catch (NumberFormatException e) {
                                decimalType.append("(").append(precision).append(")");
                            }
                        } else {
                            decimalType.append("(").append(precision).append(")");
                        }
                    } catch (NumberFormatException e) {
                        decimalType.append("(10,2)");
                    }
                } else {
                    decimalType.append("(10,2)");
                }
                return decimalType.toString();
            case "DATETIME":
            case "TIMESTAMP":
                return "DATETIME";
            case "DATE":
                return "DATE";
            case "TEXT":
                return "TEXT";
            case "LONGTEXT":
                return "LONGTEXT";
            case "DOUBLE":
                return "DOUBLE";
            case "FLOAT":
                return "FLOAT";
            default:
                return "VARCHAR(255)";
        }
    }
    
    /**
     * 处理列名，确保符合数据库命名规范
     * @param columnName 原始列名
     * @return 安全的列名
     */
    private String sanitizeColumnName(String columnName) {
        if (columnName == null || columnName.isEmpty()) {
            return "unnamed_column";
        }

        // 将中文转换为拼音
        StringBuilder pinyinStr = new StringBuilder();
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

        try {
            for (char c : columnName.toCharArray()) {
                if (Character.toString(c).matches("[\\u4E00-\\u9FA5]")) {
                    // 是中文字符，转换为拼音
                    String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
                    if (pinyinArray != null && pinyinArray.length > 0) {
                        pinyinStr.append(pinyinArray[0]);
                    }
                } else {
                    // 非中文字符直接添加
                    pinyinStr.append(c);
                }
            }
        } catch (BadHanyuPinyinOutputFormatCombination e) {
            // 出错时使用原始列名
            pinyinStr.append(columnName);
        }

        String processedName = pinyinStr.toString();

        // 移除非法字符，只保留字母、数字、下划线
        String sanitized = processedName.replaceAll("[^a-zA-Z0-9_]", "_");

        // 如果以数字开头，添加前缀
        if (Character.isDigit(sanitized.charAt(0))) {
            sanitized = "col_" + sanitized;
        }

        // 限制长度
        if (sanitized.length() > 64) {
            sanitized = sanitized.substring(0, 64);
        }

        return sanitized;
    }
    /**
     * 检查表是否存在
     * @param tableName 表名
     * @return 是否存在
     */
    public boolean isTableExists(String tableName) {
        String sql = "SHOW TABLES LIKE '" + tableName.replace("'", "''") + "'";
        List<String> result = jdbcTemplate.query(sql, (rs, rowNum) -> rs.getString(1));
        return !result.isEmpty();
    }
    
    /**
     * 删除表
     * @param tableName 表名
     */
    public void dropTable(String tableName) {
        String sql = "DROP TABLE IF EXISTS `" + tableName.replace("`",
                "") + "`";
        jdbcTemplate.execute(sql); }
}