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.CbProjectOther;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.service.CbProjectFileService;
import com.dsk.cscec.service.CbProjectOtherService;
import com.dsk.system.service.ISysOssService;
import lombok.extern.slf4j.Slf4j;
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
 */
@Slf4j
@Component
public class CbProjectOtherAnalysisComponent {

    @Resource
    private CbProjectOtherService projectOtherService;
    @Resource
    private CbProjectFileService projectFileService;
    @Resource
    private ISysOssService ossService;
    @Resource
    private TransactionTemplate transactionTemplate;

    /**
     * 其他费用数据解析
     */
    @Async
    public void projectOtherDataAnalysis(CbProjectBaseBo bo) throws Exception {
        //查询其他费用导入文件
        List<CbProjectFile> fileList = projectFileService.list(Wrappers.<CbProjectFile>lambdaQuery()
                .eq(CbProjectFile::getProjectId, bo.getProjectId())
                .eq(CbProjectFile::getCbType, CbProjectConstants.CB_TYPE_OTHER_PROJECT)
                .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<CbProjectOther> importList = new ExcelUtils<>(CbProjectOther.class).importExcelAllSheet(inputStream, 1);
                if (importList.isEmpty()) {
                    file.setFileParseStatus(3);
                    file.setFailRemark("表格中不存在待导入数据!");
                    projectFileService.updateById(file);
                    break;
                }
                List<CbProjectOther> projectOtherList = importList.stream().parallel()
                        .peek(item -> {
                            item.setProjectId(bo.getProjectId());
                            item.setCbStage(bo.getCbStage());
                            item.setCbProjectFileId(file.getId());
                        }).collect(Collectors.toList());
                if (projectOtherList.isEmpty()) {
                    throw new ServiceException("表格中不存在有效数据数据!");
                }
                transactionTemplate.execute(status -> {
                    try {
                        //分批次插入
                        if (projectOtherList.size() > 1000) {
                            int index = 0;
                            int sum = projectOtherList.size();
                            while (index < sum) {
                                List<CbProjectOther> divideList = projectOtherList.subList(index, Math.max((index + 1) * 1000, sum));
                                boolean b = projectOtherService.saveBatch(divideList);
                                if (!b) {
                                    throw new ServiceException("数据插入失败！");
                                }
                                index += 1000;
                            }
                        } else {
                            boolean b = projectOtherService.saveBatch(projectOtherList);
                            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 {
                projectOtherService.remove(Wrappers.<CbProjectOther>lambdaQuery().eq(CbProjectOther::getCbProjectFileId, file.getId()));
                projectFileService.removeById(file);
            }
        }
    }
}
