package com.kcim.dao.mapper;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import org.apache.ibatis.annotations.Param;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 动态生成批量插入SQL，通过反射解析实体类注解
 * 优化生成的SQL语句以提高批量插入性能
 */
public class BatchInsertProvider {

    /**
     * 生成批量插入SQL
     * @param list 实体列表（必须传入非空列表，否则无法解析表结构）
     * @param <T> 实体类型
     * @return 动态生成的SQL语句
     */
    public <T> String insertBatch(@Param("list") List<T> list) {
        // 确保我们有一个标准的ArrayList，以处理SubList等特殊情况
        List<T> standardList = new ArrayList<>(list);
        long timeMillis = System.currentTimeMillis();
        if (standardList.isEmpty()) {
            throw new IllegalArgumentException("批量插入的列表不能为空");
        }

        // 获取实体类信息
        Class<?> entityClass = standardList.get(0).getClass();
        // 获取表名（优先使用@TableName注解，否则用类名）
        TableName tableNameAnnotation = entityClass.getAnnotation(TableName.class);
        String tableName = tableNameAnnotation != null ? tableNameAnnotation.value() : entityClass.getSimpleName();

        // 收集所有需要处理的字段（统一字段列表）
        List<Field> validFields = new ArrayList<>();
        Field[] fields = entityClass.getDeclaredFields();
        boolean haveDelFlag = Arrays.stream(fields).anyMatch(field ->"delFlag".equals(field.getName())|| "del_flag".equals(field.getName()));
        
        for (Field field : fields) {
            // 跳过static和final字段，如serialVersionUID
            if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) || java.lang.reflect.Modifier.isFinal(field.getModifiers())) {
                continue;
            }

            TableField fieldAnnotation = field.getAnnotation(TableField.class);
            // 跳过非数据库字段
            if (fieldAnnotation != null && !fieldAnnotation.exist()) {
                continue;
            }

            validFields.add(field);
        }

        // 解析所有数据库字段（基于统一的validFields列表）
        StringBuilder columns = new StringBuilder();
        for (Field field : validFields) {
            // 获取数据库字段名（优先使用@TableField注解，否则用驼峰转下划线）
            String columnName;
            TableField fieldAnnotation = field.getAnnotation(TableField.class);
            if (fieldAnnotation != null && !"".equals(fieldAnnotation.value())) {
                columnName = fieldAnnotation.value();
            } else {
                columnName = camelToUnderline(field.getName());
            }

            // 为字段名添加反引号，避免MySQL保留字冲突
            columns.append("`").append(columnName).append("`,");
        }

        // 移除最后一个逗号
        if (columns.length() > 0) {
            columns.setLength(columns.length() - 1);
        }

        // 生成VALUES部分 - 直接构建适合MyBatis @InsertProvider使用的SQL
        StringBuilder valueSql = new StringBuilder();
        valueSql.append("<foreach collection=\"list\" item=\"item\" separator=\",\">");
        valueSql.append("(");
        for (Field field : validFields) {
            String fieldName = field.getName();

            // 特殊字段处理逻辑
            if ("delFlag".equals(fieldName) && haveDelFlag) {
                // 当haveDelFlag为true时，设置del_flag=0
                valueSql.append("0,");
            } else if ("deleteTime".equals(fieldName) && !haveDelFlag) {
                // 当haveDelFlag为false时，设置delete_time=0
                valueSql.append("0,");
            } else if (("createTime".equals(fieldName) || "updateTime".equals(fieldName))&& !haveDelFlag) {
                // 无论haveDelFlag如何，create_time和update_time等于timeMillis
                valueSql.append(timeMillis).append(",");
            } else {
                // 使用实体类属性名（MyBatis会自动映射）
                valueSql.append("#{item.").append(fieldName).append("},");
            }
        }
        // 移除最后一个逗号
        if (valueSql.charAt(valueSql.length() - 1) == ',') {
            valueSql.setLength(valueSql.length() - 1);
        }
        valueSql.append(")");
        valueSql.append("</foreach>");

        // 拼接完整SQL - 添加<script>标签确保MyBatis正确解析动态SQL
        return "<script>INSERT INTO " + tableName + " (" + columns + ") VALUES " + valueSql + "</script>";
    }

    // 驼峰转下划线（适配数据库命名规范）
    private String camelToUnderline(String camelCase) {
        if (camelCase == null || camelCase.isEmpty()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        sb.append(Character.toLowerCase(camelCase.charAt(0)));
        for (int i = 1; i < camelCase.length(); i++) {
            char c = camelCase.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append("_").append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}