package cn.superdesk.uniorder.controller._thirdpart.szhtxx;

import cn.hutool.core.lang.Snowflake;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.dto.param.invoice.excel.TaxationSzhtxxE6ExcelRow;
import cn.superdesk.uniorder.dubbo.consumer.invoice.customer.invoiced.InvoiceInvoicedDubboConsumerService;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
 * @Author: linjinyu
 * @CreateDate: 2021/3/16 下午7:06
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/3/16 下午7:06
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
public class ThirdPartTaxationSzhtxxE6ExcelRowImportDataListener extends AnalysisEventListener<TaxationSzhtxxE6ExcelRow> {

	/**
	 * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
	 */
	private static final int BATCH_COUNT = 99999;

	List<TaxationSzhtxxE6ExcelRow> taxationAisinoE6ExcelRowParamList = new ArrayList<>();

	private String token;

	private InvoiceInvoicedDubboConsumerService invoiceInvoicedDubboConsumerService;

	private Snowflake snowflake;
	private String    batchId;

	/**
	 * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
	 *
	 * @param invoiceInvoicedDubboConsumerService
	 */
	public ThirdPartTaxationSzhtxxE6ExcelRowImportDataListener(
			InvoiceInvoicedDubboConsumerService invoiceInvoicedDubboConsumerService,
			Snowflake snowflake,
			String token
	) {
		this.invoiceInvoicedDubboConsumerService = invoiceInvoicedDubboConsumerService;

		this.snowflake = snowflake;

		this.token = token;
	}

	/**
	 * 这个每一条数据解析都会来调用
	 *
	 * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
	 * @param context
	 */
	@Override
	public void invoke(TaxationSzhtxxE6ExcelRow data, AnalysisContext context) {

		if (null == data.getInvoiceSequenceNumber()) {
			return;
		}


		log.info("解析到一条数据: {}", AnJsonUtils.toJson(data));

		taxationAisinoE6ExcelRowParamList.add(data);
		// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
		if (taxationAisinoE6ExcelRowParamList.size() >= BATCH_COUNT) {
			saveOrUpdateData();
			// 存储完成清理 list
			taxationAisinoE6ExcelRowParamList.clear();
		}
	}

	/**
	 * 所有数据解析完成了 都会来调用
	 *
	 * @param context
	 */
	@Override
	public void doAfterAllAnalysed(AnalysisContext context) {
		// 这里也要保存数据,确保最后遗留的数据也存储到数据库
		saveOrUpdateData();

		log.info("所有数据解析完成！");
	}

	/**
	 * 加上存储数据库
	 */
	private void saveOrUpdateData() {

		log.info("{} 条数据,开始存储数据库！\n{}", taxationAisinoE6ExcelRowParamList.size(), AnJsonUtils.toJson(taxationAisinoE6ExcelRowParamList));

		invoiceInvoicedDubboConsumerService.saveOrUpdate4ThirdPartTaxationSzhtxxE6ExcelRowListByInvoiceNumber(taxationAisinoE6ExcelRowParamList, token);

		log.info("存储数据库成功！");
	}
}
