package com.kcim.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kcim.dao.mapper.GenericBatchMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.function.BiFunction;

/**
 * 通用批量插入服务基类
 * @param <T> 实体类类型
 * @param <M> Mapper接口类型（需继承GenericBatchMapper）
 */
public abstract class BaseBatchServiceImpl<M extends GenericBatchMapper<T>, T>
        extends ServiceImpl<M, T>{

    /**
     * 默认批次大小（可根据表结构调整）
     */
    private int batchSize = 1000;

    /**
     * 设置批次大小
     */
    public void setBatchSize(int batchSize) {
        this.batchSize = batchSize;
    }

    /**
     * 批量插入数据（适合中等数据量）
     * @param dataList 要插入的数据列表
     * @return 总插入条数
     */
    @Transactional(rollbackFor = Exception.class)
    public int batchInsert(List<T> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            return 0;
        }

        int total = dataList.size();
        int batches = (total + batchSize - 1) / batchSize;

        for (int i = 0; i < batches; i++) {
            int start = i * batchSize;
            int end = Math.min(start + batchSize, total);
            baseMapper.insertBatch(dataList.subList(start, end));
        }

        return total;
    }

    /**
     * 分页加载并插入大数据量（避免OOM）
     * @param dataProvider 数据提供器（分页加载数据的回调函数）
     * @return 总插入条数
     */
    @Transactional(rollbackFor = Exception.class)
    public int batchInsertByPage(BiFunction<Integer, Integer, List<T>> dataProvider) {
        int page = 0;
        int total = 0;

        while (true) {
            // 调用回调函数加载当前页数据
            List<T> dataBatch = dataProvider.apply(page, batchSize);
            if (dataBatch.isEmpty()) {
                break; // 数据加载完成
            }

            // 插入当前页数据
            baseMapper.insertBatch(dataBatch);
            total += dataBatch.size();
            page++;
        }

        return total;
    }
}