package com.dsk.component;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dsk.common.excel.ExcelUtils;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.constant.CbProjectConstants;
import com.dsk.cscec.domain.CbProjectFile;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.service.CbProjectFileService;
import com.dsk.cscec.service.ICbQuantitySummaryService;
import com.dsk.oss.factory.OssFactory;
import com.dsk.system.domain.vo.SysOssVo;
import com.dsk.system.service.ISysOssService;
import org.apache.el.stream.Stream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 数据解析组件
 *
 * @Author lcl
 * @Data 2024/2/7 17:43
 */
@Component
public class DataAnalysisComponent {

    @Autowired
    private ICbQuantitySummaryService quantitySummaryService;
    @Autowired
    private CbProjectFileService projectFileService;
    @Autowired
    private ISysOssService ossService;
    @Resource
    private TransactionTemplate transactionTemplate;

    /**
     * 工料汇总数据解析
     */
    @Async
    public void quantitySummaryDataAnalysis(CbProjectBaseBo bo) throws Exception {
        //查询工料汇总导入文件
        List<CbProjectFile> fileList = projectFileService.list(Wrappers.<CbProjectFile>lambdaQuery()
                .eq(CbProjectFile::getProjectId, bo.getProjectId())
                .eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_QUANTITY_SUMMARY)
                .eq(CbProjectFile::getCbStage, bo.getCbStage())
                .in(CbProjectFile::getFileParseStatus, Arrays.asList(1, 3)));
        if (ObjectUtils.isEmpty(fileList)) return;
        //文件处理
        for (CbProjectFile file : fileList) {
            if (file.getDelFlag() == 0) {

                //文件下载
                InputStream inputStream = ossService.downFileIO(file.getFileOssId());
                if (ObjectUtil.isNull(inputStream)) {
                    file.setFileParseStatus(3);
                    file.setFailRemark("文件数据不存在");
                    projectFileService.updateById(file);
                    break;
                }
                //解析数据
                List<CbQuantitySummary> importList = new ExcelUtils<>(CbQuantitySummary.class).importExcelAllSheet(inputStream, 1);
                if (importList.isEmpty()) {
                    file.setFileParseStatus(3);
                    file.setFailRemark("表格中不存在待导入数据!");
                    projectFileService.updateById(file);
                    break;
                }
                List<CbQuantitySummary> quantitySummaryList = importList.stream().parallel()
                        .filter(item -> !ObjectUtils.isEmpty(item.getCbName()))
                        .peek(item -> {
                            item.setProjectId(bo.getProjectId());
                            item.setCbStage(bo.getCbStage());
                            item.setCbProjectFileId(file.getId());
                        }).collect(Collectors.toList());
                if (quantitySummaryList.isEmpty()) {
                    throw new ServiceException("表格中不存在有效数据数据!");
                }
                transactionTemplate.execute(status -> {
                    try {
                        //分批次插入
                        if (quantitySummaryList.size() > 1000) {
                            int index = 0;
                            int sum = quantitySummaryList.size();
                            while (index < sum) {
                                List<CbQuantitySummary> divideList = quantitySummaryList.subList(index, Math.max((index + 1) * 1000, sum));
                                boolean b = quantitySummaryService.saveBatch(divideList);
                                if (!b) {
                                    throw new ServiceException("数据插入失败！");
                                }
                                index += 1000;
                            }
                        } else {
                            boolean b = quantitySummaryService.saveBatch(quantitySummaryList);
                            if (!b) {
                                throw new ServiceException("数据插入失败！");
                            }
                        }
                        file.setFileParseStatus(2);
                        boolean b = projectFileService.updateById(file);
                        if (!b) {
                            throw new ServiceException("文件状态更新失败！");
                        }
                    } catch (Exception e) {
                        status.setRollbackOnly();
                        file.setFileParseStatus(3);
                        file.setFailRemark(e.getMessage());
                        projectFileService.updateById(file);
                    }
                    return Boolean.TRUE;
                });
            } else {
                quantitySummaryService.remove(Wrappers.<CbQuantitySummary>lambdaQuery().eq(CbQuantitySummary::getCbProjectFileId, file.getId()));
                projectFileService.removeById(file);
            }
        }
    }
}
