package com.yeejoin.amos.boot.module.jg.biz.data.fix.patcher;

import com.yeejoin.amos.boot.module.jg.biz.service.impl.IdxBizJgUseInfoServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StopWatch;

import java.util.List;
import java.util.Map;

@Slf4j
public abstract class FilterableBatchDataPatcher implements HistoricalDataPatcher<Map<String, Object>> {

    private final ApplicationContext applicationContext;

    protected FilterableBatchDataPatcher(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public Integer patchBatchData(Map<String, Object> params) {
        StopWatch watch = new StopWatch();
        watch.start();
        IdxBizJgUseInfoServiceImpl useInfoService = applicationContext.getBean(IdxBizJgUseInfoServiceImpl.class);
        Integer maxVersion = useInfoService.getBaseMapper().selectMaxVersionWithParams(buildFilter(params));
        Integer nextVersion = maxVersion + 1;
        List<String> refreshRecords = useInfoService.getBaseMapper().selectUseInfoOfOneVersionWithParams(nextVersion,buildFilter(params));
        int patchSize = refreshRecords.size();
        while (!refreshRecords.isEmpty()) {
            refreshRecords.parallelStream().forEach(record -> {
                try {
                    beforePatching(record);
                    patchSingleRecord(record);
                    afterPatching(record);
                } catch (Exception e) {
                    // 异常数据跳过
                    log.error("数据修补失败,设备:{}", record, e);
                }
            });
            useInfoService.getBaseMapper().updateVersionBatch(refreshRecords, nextVersion);
            refreshRecords = useInfoService.getBaseMapper().selectUseInfoOfOneVersionWithParams(nextVersion,buildFilter(params));
            patchSize = patchSize + refreshRecords.size();
        }
        watch.stop();
        log.info("数据修补完成，共处理{}条记录，耗时: {}秒", patchSize, watch.getTotalTimeSeconds());
        return patchSize;
    }

    protected abstract Map<String, Object> buildFilter(Map<String, Object> params);

    protected abstract void beforePatching(String record);

    protected abstract void patchSingleRecord(String record);

    protected abstract void afterPatching(String record);

}
