package com.chushang.common.excel.listener;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.chushang.common.excel.service.ExcelImporter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

@Data
@Slf4j
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class ImportListener<T> extends AnalysisEventListener<T> {

	/**
	 * 默认每隔3000条存储数据库
	 */
	private int batchCount = 3000;
	/**
	 * 缓存的数据列表
	 */
	private List<T> list = new ArrayList<>();
	/**
	 * 数据导入类
	 */
	private final ExcelImporter<T> importer;

	@Override
	public void invoke(T data, AnalysisContext analysisContext) {
		log.info("read size {}", list.size());
		if (isNotNull(data)) list.add(data);
		// 达到BATCH_COUNT，则调用importer方法入库，防止数据几万条数据在内存，容易OOM
		if (list.size() >= batchCount) {
			// 调用importer方法
			importer.save(list);
			// 存储完成清理list
			list.clear();
		}
	}


	@SneakyThrows
	private boolean isNotNull(T data){
		Class<?> clazz = data.getClass();
		Field[] declaredFields = data.getClass().getDeclaredFields();
		List<Object> collect = new ArrayList<>();
		for (Field df : declaredFields) {
			PropertyDescriptor pd = new PropertyDescriptor(df.getName(), clazz);
			Object value = pd.getReadMethod().invoke(data);
			collect.add(value);
		}
		return !CollectionUtil.hasNull(collect);
	}

	@Override
	public void doAfterAllAnalysed(AnalysisContext analysisContext) {
		// 调用importer方法
		importer.save(list);
		// 存储完成清理list
		list.clear();
	}

}