package com.cf.imes.framework.mybatis.core.injector;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

/**
 * 自定义批量更新
 *
 * @author Gqr
 * @since 2025/3/24 11:26
 */
public class UpdateBatchMethod extends AbstractMethod {

    protected UpdateBatchMethod(String methodName) {
        super(methodName);
    }

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        // 1. 生成动态 SET 子句（属性为空时不更新）
        String setSql = generateConditionalSetSql(tableInfo);

        // 2. 处理乐观锁和逻辑删除的附加条件
        String additional = tableInfo.isWithVersion()
                ? tableInfo.getVersionFieldInfo().getVersionOli("item", "item.")
                : "" + tableInfo.getLogicDeleteSql(true, true);

        // 3. 构建完整 SQL
        String sqlTemplate = "<script>\n<foreach collection=\"list\" item=\"item\" separator=\";\">\n" +
                "UPDATE %s %s WHERE %s = #{item.%s} %s\n" +
                "</foreach>\n</script>";
        String sqlResult = String.format(
                sqlTemplate,
                tableInfo.getTableName(),
                setSql,
                tableInfo.getKeyColumn(),
                tableInfo.getKeyProperty(),
                additional
        );

        // 4. 创建 SqlSource 和 MappedStatement
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
        return addUpdateMappedStatement(mapperClass, modelClass, "updateBatch", sqlSource);
    }

    /**
     * 生成动态 SET 子句：属性为空时不更新
     */
    private String generateConditionalSetSql(TableInfo tableInfo) {
        StringBuilder setSqlBuilder = new StringBuilder("<set>");
        setSqlBuilder.append("<trim suffixOverrides=\",\">");

        String keyColumn = tableInfo.getKeyColumn();

        // 遍历所有字段（排除主键、逻辑删除字段、版本字段、organid租户字段）
        tableInfo.getFieldList().stream()
                .filter(f -> !f.getColumn().equals(keyColumn)
                        &&
                        !f.isLogicDelete()
                        &&
                        (tableInfo.isWithVersion() ? !f.isVersion() : true)
                        &&
                        !"organ_id".equals(f.getColumn())

                )
                .forEach(field -> {
                    String column = field.getColumn();
                    String property = "item." + field.getProperty();
                    // 添加条件判断：属性不为空时更新
                    setSqlBuilder.append(
                            String.format("<if test=\"%s != null\">%s = #{%s},</if>", property, column, property)
                    );
                });

        setSqlBuilder.append("</trim></set>");
        return setSqlBuilder.toString();
    }
}