package com.bonus.material.purchase.service.impl;

import com.bonus.common.biz.config.BackstageApplication;
import com.bonus.common.biz.config.DateTimeHelper;
import com.bonus.common.biz.config.QrCodeUtils;
import com.bonus.common.biz.constant.BmConfigItems;
import com.bonus.common.biz.domain.BmFileInfo;
import com.bonus.common.biz.enums.HttpCodeEnum;
import com.bonus.common.biz.enums.MaTypeManageTypeEnum;
import com.bonus.common.biz.enums.PurchaseTaskStageEnum;
import com.bonus.common.biz.enums.PurchaseTaskStatusEnum;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.basic.mapper.BmFileInfoMapper;
import com.bonus.material.basic.service.IBmConfigService;
import com.bonus.material.codeCollection.domain.WsMaInfo;
import com.bonus.material.codeCollection.mapper.WsMaInfoMapper;
import com.bonus.material.purchase.config.RemoteConfig;
import com.bonus.common.biz.domain.purchase.PurchaseDto;
import com.bonus.material.purchase.domain.PurchaseCheckDetails;
import com.bonus.material.purchase.domain.PurchaseCheckInfo;
import com.bonus.material.purchase.domain.dto.PurchaseCheckDto;
import com.bonus.material.purchase.domain.dto.PurchaseQueryDto;
import com.bonus.material.purchase.mapper.PurchaseBindMapper;
import com.bonus.material.purchase.mapper.PurchaseCheckDetailsMapper;
import com.bonus.material.purchase.mapper.PurchaseCheckInfoMapper;
import com.bonus.material.purchase.mapper.PurchaseStorageMapper;
import com.bonus.material.purchase.service.IPurchaseBindService;
import com.bonus.material.purchase.domain.vo.PurchaseVo;
import com.bonus.material.task.domain.TmTask;
import com.bonus.material.task.mapper.TmTaskMapper;
import com.bonus.system.api.model.LoginUser;
import com.google.zxing.WriterException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Author ma_sh
 * @create 2024/10/21 18:42
 */
@Service
@Slf4j
public class PurchaseBindServiceImpl implements IPurchaseBindService {

    @Resource
    private PurchaseBindMapper purchaseBindMapper;

    @Resource
    private RemoteConfig remoteConfig;

    @Resource
    private PurchaseStorageMapper purchaseStorageMapper;

    @Resource
    private PurchaseCheckDetailsMapper purchaseCheckDetailsMapper;

    @Resource
    private PurchaseCheckInfoMapper purchaseCheckInfoMapper;

    @Resource
    private WsMaInfoMapper mapper;

    @Resource
    private TmTaskMapper tmTaskMapper;

    @Resource
    private IBmConfigService bmConfigService;

    @Resource
    private BmFileInfoMapper bmFileInfoMapper;

    // 引入新购任务阶段常量
    private static final int PURCHASE_TASK_STAGE_MANAGE = 1;
    private static final int PURCHASE_TASK_STAGE_CHECK = 2;
    private static final int PURCHASE_TASK_STAGE_BIND = 3;
    private static final int PURCHASE_TASK_STAGE_STORE = 4;


    /**
     * 查询所有绑定信息
     * @param dto
     * @return
     */
    @Override
    public List<PurchaseVo> selectAll(PurchaseDto dto) {
        List<PurchaseVo> list = purchaseBindMapper.selectAll(dto);
        if (CollectionUtils.isNotEmpty(list)) {
            Iterator<PurchaseVo> iterator = list.iterator();
            while (iterator.hasNext()) {
                PurchaseVo purchaseVo = iterator.next();
                String[] split = purchaseVo.getManageType().split(",");
                // 检查是否全部为 1
                boolean allOnes = true;
                for (String manageType : split) {
                    if (MaTypeManageTypeEnum.CODE_DEVICE.getTypeId().equals(Integer.valueOf(manageType.trim()))) {
                        allOnes = false;
                        // 发现不是 1，跳出循环
                        break;
                    }
                }
                // 如果全部为 1，移除该记录
                if (allOnes) {
                    iterator.remove();
                }
            }
        }
        return list;
    }

    /**
     * 查询绑定信息
     * @param dto
     * @return
     */
    @Override
    public AjaxResult selectPurchaseCheckInfoById(PurchaseDto dto) {
        if (dto == null || dto.getTaskId() == null || dto.getTypeId() == null) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "参数不能为空");
        }
        List<PurchaseVo> list = purchaseBindMapper.selectPurchaseCheckInfoById(dto);
        //extracted(list);
        return AjaxResult.success(list);
    }

    /**
     * 获取新购绑定二级明细列表
     * @param dto
     * @return
     */
    @Override
    public List<PurchaseVo> getDetails(PurchaseDto dto) {
        final List<PurchaseVo> list = purchaseBindMapper.getDetails(dto);
        final Map<String, String> labelMap = remoteConfig.getDictValue("purchase_task_status");
        if (CollectionUtils.isNotEmpty(list)) {
            for (final PurchaseVo purchaseVo : list) {
                // 更新状态名称
                final Integer status = purchaseVo.getStatus();
                if (null != status) {
                    purchaseVo.setStatusName(labelMap.get(status.toString()));
                }
            }
        }
        return list;
    }

    /**
     * 绑定
     * @param dto 绑定物资信息
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult bind(PurchaseDto dto) {
        //先查询提交的编码中是否存在重复提交
        final long distinctCodes = dto.getDtoList().stream().map(PurchaseDto::getMaCode).distinct().count();
        if (distinctCodes < dto.getDtoList().size()) {
            return AjaxResult.error(1113,"提交的数据中设备编码存在重复，请勿重复添加");
        }
        for (final PurchaseDto purchaseDto : dto.getDtoList()) {
            //根据设备编码唯一校验
            final List<PurchaseDto> tbBdDeviceRecord = purchaseBindMapper.selectByCode(purchaseDto);
            if (purchaseBindMapper.checkQrCodeIsBind(purchaseDto.getQrCode())) {
                return AjaxResult.error(1114,"二维码已绑定物资，请勿重复绑定");
            }
            if (CollectionUtils.isNotEmpty(tbBdDeviceRecord)) {
                return AjaxResult.error(1114,purchaseDto.getMaCode() + "：该设备编码与库中重复，请勿重复添加");
            }
        }
        // 根据taskId查询厂商
        PurchaseCheckInfo purchaseCheckInfo = purchaseBindMapper.selectSupplierByTaskId(dto.getTaskId());
        PurchaseCheckDetails purchaseCheckDetails = new PurchaseCheckDetails();
        purchaseCheckDetails.setTaskId(Long.valueOf(dto.getTaskId()));
        purchaseCheckDetails.setTypeId(Long.valueOf(dto.getTypeId()));
        List<PurchaseCheckDetails> details = purchaseCheckDetailsMapper.selectPurchaseCheckDetailsList(purchaseCheckDetails);
        for (final PurchaseDto purchaseDto : dto.getDtoList()) {
            purchaseDto.setCreateBy(SecurityUtils.getLoginUser().getUserid().toString()).setCreateTime(DateUtils.getNowDate());
            purchaseDto.setTaskId(dto.getTaskId()).setTypeId(dto.getTypeId()).setStatus(0);
            if (null != purchaseDto.getQrCode()) {
                if (1 != purchaseBindMapper.bindMaCodeByQrCode(purchaseDto)) {
                    return AjaxResult.error(1115,"绑定maCode时SQL执行失败!");
                }
            } else {
                if (null != dto.getTypeId()) {
                    purchaseDto.setTypeId(dto.getTypeId());
                }
                purchaseBindMapper.insert(purchaseDto);
            }
            try {
                if (purchaseCheckInfo != null && !StringUtils.isBlank(purchaseCheckInfo.getSupplier())) {
                    purchaseDto.setSupplier(purchaseCheckInfo.getSupplier());
                }
                if (CollectionUtils.isNotEmpty(details)) {
                    if (StringUtils.isNotBlank(details.get(0).getProductionTime())){
                        purchaseDto.setProductDate(details.get(0).getProductionTime());
                    }
                }
                if (1 != purchaseStorageMapper.insertMachine(purchaseDto)) {
                    return AjaxResult.error(1116,"插入maMachine时SQL执行失败!");
                }
            } catch (Exception e) {
                throw new ServiceException(e.getMessage() + "插入maMachine时SQL执行失败!");
            }
        }
        // 更新绑定数量，并刷新状态
        if (1 > purchaseBindMapper.updateNum(dto, dto.getDtoList().size())) {
            return AjaxResult.error(1117,"更新绑定数量时SQL执行失败!");
        } else {
            purchaseBindMapper.updateStatusWhereNum(dto);
        }

        //根据任务id和类型id查询状态
        final List<PurchaseVo> voList = purchaseBindMapper.selectPurchaseCheckInfoById(dto);
        if (CollectionUtils.isNotEmpty(voList)) {
            for (final PurchaseVo purchaseVo : voList) {
                if (0 == purchaseVo.getBindNum().compareTo(purchaseVo.getCheckNum())) {
                    purchaseBindMapper.updateStatusById(PurchaseTaskStatusEnum.TO_STORE.getStatus(), purchaseVo.getPurchaseId());
                } else if (0 > purchaseVo.getBindNum().compareTo(purchaseVo.getCheckNum())) {
                    purchaseBindMapper.updateStatusById(PurchaseTaskStatusEnum.TO_BIND.getStatus(), purchaseVo.getPurchaseId());
                } else {
                    // 抛出异常 执行回滚
                    throw new RuntimeException("绑定数量大于验收数量，请重新绑定!");
                }
            }
        }
        return AjaxResult.success("绑定成功");
    }

    /**
     * 盘点绑定
     * @param dto 盘点绑定
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult inventoryBind(PurchaseVo dto) {
        if(dto.getQrCode() == null || dto.getQrCode().isEmpty()){
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "二维码不能为空");
        }
        if(dto.getMaCode()== null || dto.getMaCode().isEmpty()){
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "设备编码不能为空");
        }
        if(dto.getTypeId() == null){
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "未知设备类型，请扫描后再绑定");
        }
        //查找maCode是否重复
        int count = purchaseBindMapper.selectMaCodeCount(dto);
        if (count > 0) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "该设备编码已存在，请勿重复添加");
        }
        dto.setUpdateBy(SecurityUtils.getLoginUser().getUserid().toString());
        //修改bm_qrcode_info表中状态和ma_code
        int countOne = purchaseBindMapper.updateQrCodeInfo(dto);
        if (countOne == 0) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "修改bm_qrcode_info表失败");
        }
        //插入ma_machine表
        WsMaInfo wsMaInfo = new WsMaInfo();
        wsMaInfo.setMaName(dto.getMaterialName());
        wsMaInfo.setMaModel(dto.getMaterialModel());
        wsMaInfo.setMaCode(dto.getMaCode());
        wsMaInfo.setSupplier(dto.getSupplierName());
        wsMaInfo.setModelId(dto.getTypeId() + "");
        wsMaInfo.setQrCode(dto.getQrCode());
        int countTwo = mapper.insert(wsMaInfo);
        if (countTwo == 0) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "插入ws_ma_info表失败");
        }
        return AjaxResult.success("绑定成功");
    }


    /**
     * 提取状态更新逻辑到一个方法
     * @param taskId
     * @param statusList
     * @return
     */
//    private int updateTaskStatus(Integer taskId, List<Integer> statusList) {
//        if (statusList.contains(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus()) ||
//                statusList.contains(PurchaseTaskStatusEnum.TO_BIND.getStatus())) {
//            return tmTaskMapper.updateStatusById(MaterialConstants.TEN_CONSTANT, taskId.toString());
//        } else if (!statusList.contains(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus()) &&
//                !statusList.contains(PurchaseTaskStatusEnum.TO_BIND.getStatus()) &&
//                statusList.contains(PurchaseTaskStatusEnum.TO_STORE.getStatus())) {
//            return tmTaskMapper.updateStatusById(PurchaseTaskStatusEnum.IN_STORE.getStatus(), taskId.toString());
//        }
//        return 0;
//    }

    /**
     * 下载二维码
     * @param response
     * @param purchaseDto
     */
    @Override
    public void downloadQrCode(HttpServletResponse response, PurchaseDto purchaseDto) {
         //生成二维码
        Set<String> addedEntries = new HashSet<>();
        if (purchaseDto.getPurchaseId() == null) {
            throw new RuntimeException("内层id为空");
        }
        String genMonth = DateTimeHelper.getNowMonth();
        List<PurchaseVo> codeList = purchaseBindMapper.select(genMonth);
        try (OutputStream os = response.getOutputStream();
             ZipOutputStream zos = new ZipOutputStream(os)) {
            Integer status = purchaseBindMapper.selectStatus(purchaseDto);
            if (status == null) {
                return;
            }
            //内层二维码下载
            handlePurchaseId(addedEntries, purchaseDto, codeList, status, zos, genMonth);
            zos.flush();
        } catch (WriterException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 驳回或批量驳回操作
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult reject(PurchaseDto dto) {
        int result = 0;
        if (dto.getTaskId() != null) {
            //一级页面驳回
            //根据任务id查询详细信息
            List<PurchaseVo> list = purchaseBindMapper.getDetails(dto);
            if (CollectionUtils.isNotEmpty(list)) {
                for (PurchaseVo purchaseVo : list) {
                    //更新状态为已驳回
                    if (purchaseVo.getStatus().equals(PurchaseTaskStatusEnum.TO_BIND.getStatus()) || purchaseVo.getStatus().equals(PurchaseTaskStatusEnum.TO_BIND_AFTER_REJECT.getStatus())) {
                        result += purchaseBindMapper.updateStatusById(PurchaseTaskStatusEnum.TO_BIND_AFTER_REJECT.getStatus(), purchaseVo.getPurchaseId());
                    }
                }
            }
        } else if (dto.getPurchaseId() != null) {
            // 二级页面驳回
            String[] idList = dto.getPurchaseId().split(",");
            for (String purchaseId : idList) {
                result += purchaseBindMapper.updateStatusById(PurchaseTaskStatusEnum.TO_BIND_AFTER_REJECT.getStatus(), Long.valueOf(purchaseId));
            }
        }
        if (result > 0) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
        }
    }



    /**
     * 内层二维码下载
     * @param purchaseDto
     * @param codeList
     * @param status
     * @param zos
     * @param genMonth
     * @throws IOException
     * @throws WriterException
     */
    private void handlePurchaseId(Set<String> addedEntries, PurchaseDto purchaseDto, List<PurchaseVo> codeList, Integer status, ZipOutputStream zos, String genMonth) throws IOException, WriterException {
        if (status == 1) {
            List<PurchaseVo> details = purchaseBindMapper.getDetails(purchaseDto);
            if (CollectionUtils.isNotEmpty(details)) {
                PurchaseVo detail = details.get(0);
                if (detail.getBindNum() != null ) {
                    detail.setPendingBindNum(detail.getCheckNum().subtract(detail.getBindNum()) );
                }
                Select(addedEntries, purchaseDto, zos, detail);
            }
        } else {
            int num = getInitialNum(codeList);
            List<PurchaseVo> details = purchaseBindMapper.getDetails(purchaseDto);
            if (CollectionUtils.isNotEmpty(details)) {
                PurchaseVo detail = details.get(0);
                purchaseDto.setTaskId(detail.getTaskId().toString());
                if (detail.getBindNum() != null ) {
                    detail.setCheckNum(detail.getCheckNum().subtract(detail.getBindNum()) );
                }
                getString(addedEntries, purchaseDto, genMonth, num, zos, detail.getMaterialModel(), detail.getMaterialName(), detail.getTypeId(), detail.getCheckNum());
                extractedUpStatus(purchaseDto);
            }
        }
    }

    /**
     * 方法抽取
     * @param purchaseDto
     * @param genMonth
     * @param num
     * @param zos
     * @param materialModel
     * @param materialName
     * @param typeId
     * @param checkNum
     * @throws WriterException
     * @throws IOException
     */
    private void getString(Set<String> addedEntries, PurchaseDto purchaseDto, String genMonth, int num, ZipOutputStream zos, String materialModel, String materialName, Integer typeId, BigDecimal checkNum) throws WriterException, IOException {
        int genNum = (int) checkNum.doubleValue();
        for (int j = 1; j <= genNum; j++) {
            genMonth = genMonth.replace("-", "");
            String code = genMonth + "-" + String.format("%5d", num + j).replace(" ", "0");
            // 新购管理-二维码打印-新增
            String url = BackstageApplication.getUrl() + "backstage/machine/qrCodePage?qrcode=" + code;
            // // 二维码的图片格式
            String format = "jpg";
            //设置路径
            String mkdirsName = "images";
            // linux 系统路径
            String saveDirectory = "/data/imw/" + mkdirsName + "/";
            String os = System.getProperty("os.name");
            if (os.toLowerCase().startsWith("win")) {
                //本地路径
                saveDirectory = "D://files/" + mkdirsName + "/";
            }
            // 生成二维码
            File files = new File(saveDirectory);
            if (!files.exists()) {
                files.mkdirs();
            }
            QrCodeUtils.generateQRImage(url, saveDirectory, code + ".jpg", format);
            String qrUrl = saveDirectory + code + ".jpg";
            PurchaseDto dto = PurchaseDto.builder().taskId(purchaseDto.getTaskId()).typeId(typeId).qrCode(code).qrUrl(qrUrl).createBy(SecurityUtils.getLoginUser().getUserid().toString()).build();
            purchaseBindMapper.insert(dto);
            extracted( addedEntries, zos, materialModel, materialName, code, qrUrl);
        }
    }

    /**
     * 修改任务表方法抽取
     * @param purchaseDto
     */
    private void extractedUpStatus(PurchaseDto purchaseDto) {
        //修改任务表的是否下载状态
        purchaseBindMapper.updateStatus(purchaseDto.getTaskId(), purchaseDto.getPurchaseId());
    }

    /**
     * 获取初始化num
     * @param codeList
     * @return
     */
    private int getInitialNum(List<PurchaseVo> codeList) {
        if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(codeList)) {
            PurchaseVo purchaseVo = codeList.get(0);
            return Integer.parseInt(purchaseVo.getQrCode().split("-")[1]);
        }
        return 0;
    }

    /**
     * 查询方法抽取
     * @param purchaseDto
     * @param zos
     * @throws IOException
     */
    private void Select(Set<String> addedEntries, PurchaseDto purchaseDto, ZipOutputStream zos, PurchaseVo detail) throws IOException {
        List<PurchaseVo> list = purchaseBindMapper.selectPurchaseCheckDetailsById(purchaseDto);
        if (detail.getPendingBindNum() != null && detail.getPendingBindNum().compareTo(BigDecimal.ZERO) > 0) {
            int num = (int) detail.getPendingBindNum().doubleValue();
            list = list.subList(0, num);
        }
        if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(list)) {
            for (PurchaseVo purchaseVo : list) {
                String materialModel = purchaseVo.getMaterialModel();
                String materialName = purchaseVo.getMaterialName();
                String path = purchaseVo.getQrUrl();
                String qrCode = purchaseVo.getQrCode();
                path = path.replace("filePath", "/data/imw");
                extractedQrCode(qrCode);
                extracted(addedEntries, zos, materialModel, materialName, qrCode, path);
            }
        }
    }

    /**
     * 二维码生产方法抽取
     * @param qrCode
     */
    private void extractedQrCode(String qrCode) {
        // 新购管理-二维码打印-新增
        String url = BackstageApplication.getUrl() + "backstage/machine/qrCodePage?qrcode=" + qrCode;
        // // 二维码的图片格式
        String format = "jpg";
        //设置路径
        String mkdirsName = "images";
        // linux 系统路径
        String saveDirectory = "/data/imw/" + mkdirsName + "/";
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            //本地路径
            saveDirectory = "D://files/" + mkdirsName + "/";
        }
        // 生成二维码
        File files = new File(saveDirectory);
        if (!files.exists()) {
            files.mkdirs();
        }
        QrCodeUtils.generateQRImage(url, saveDirectory, qrCode + ".jpg", format);
    }

    /**
     * 二维码下载方法抽取
     * @param zos
     * @param materialModel
     * @param materialName
     * @param code
     * @param path
     * @throws IOException
     */
    private void extracted(Set<String> addedEntries, ZipOutputStream zos, String materialModel, String materialName, String code, String path) throws IOException {
        // 判断路径是否存在
        File imageFile = new File(path);
        if (!imageFile.exists()) {
            return;
        }
        String entryName = "[" + materialModel + "-" + materialName + "]" + code + ".jpg";
        if (addedEntries.contains(entryName)) {
            System.out.println("Duplicate entry skipped: " + entryName);
            return;
        }
        addedEntries.add(entryName);

        zos.setLevel(0);
        zos.putNextEntry(new ZipEntry(entryName));
        try (InputStream fis = new FileInputStream(imageFile)) {
            byte[] buffer = new byte[1024];
            int r;
            while ((r = fis.read(buffer)) != -1) {
                zos.write(buffer, 0, r);
            }
        }
        zos.closeEntry();
    }


    /**
     * 查询二维码绑定信息
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getTypeByQrcode(PurchaseDto dto) {

        List<PurchaseVo> list = purchaseBindMapper.getTypeByQrcode(dto);
        //extracted(list);
        return AjaxResult.success(list);
    }

    /**
     * 查询盘点绑定信息
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getInventoryInfo(PurchaseDto dto) {
        if (dto == null || dto.getQrCode() == null || dto.getQrCode().isEmpty()) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "参数不能为空");
        }
        PurchaseVo vo = purchaseBindMapper.getInventoryInfo(dto);
        if(vo == null){
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "该二维码不存在，请重新扫描");
        }
        if(vo.getMaCode()!=null && !vo.getMaCode().equals("")){
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "该二维码已绑定，请勿重复绑定");
        }
        if(vo.getIsBindInventory()==1){
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "该二维码已绑定，请勿重复绑定");
        }
        return AjaxResult.success(vo);
    }

    /**
     * 查询新购验收绑定任务列表
     * @param purchaseQueryDto
     * @return
     */
    @Override
    public List<PurchaseCheckInfo> selectPurchaseCheckInfoList(PurchaseQueryDto purchaseQueryDto) {
        log.info("=== MaterialLeaseInfoServiceImpl.selectPurchaseCheckInfoList开始执行，purchaseQueryDto: {}", purchaseQueryDto);

        final List<PurchaseCheckInfo> purchaseCheckInfos = purchaseCheckInfoMapper.selectPurchaseCheckInfoJoinList(purchaseQueryDto);
        if (org.springframework.util.CollectionUtils.isEmpty(purchaseCheckInfos)) {
            return Collections.emptyList();
        }

        // 检查 SecurityUtils.getLoginUser() 是否为 null
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            log.error("当前用户未登录或登录信息丢失，无法获取用户ID");
            return Collections.emptyList();
        }

        final Long loginUserId = loginUser.getUserid();
        if (Objects.isNull(loginUserId) || Objects.isNull(purchaseQueryDto.getTaskStage())) {
            return Collections.emptyList();
        }

        // 提取所有任务ID，用于批量查询
        List<Long> taskIds = purchaseCheckInfos.stream()
                .map(PurchaseCheckInfo::getTaskId)
                .collect(Collectors.toList());

        // 批量查询所有任务的明细信息
        List<PurchaseCheckDetails> allDetails = purchaseCheckDetailsMapper.selectBindList(taskIds, loginUserId);
        Map<Long, List<PurchaseCheckDetails>> detailsMap = allDetails.stream()
                .filter(detail -> detail.getTaskId() != null)
                .collect(Collectors.groupingBy(PurchaseCheckDetails::getTaskId));

        // 批量查询任务状态信息
        List<TmTask> tmTasks = tmTaskMapper.selectTmTaskByTaskIdsBatch(taskIds);
        Map<Long, TmTask> taskMap = tmTasks.stream()
                .filter(task -> task.getTaskId() != null)
                .collect(Collectors.toMap(TmTask::getTaskId, Function.identity()));

        // 批量查询物资类型名称
        final boolean isAllowPartTransfer = bmConfigService.isBmConfigEnabledWithDefaultFalse(BmConfigItems.BOOLEAN_ALLOW_PURCHASE_PART_TRANSFER);
        List<PurchaseCheckInfo> maTypeNames;
        if (isAllowPartTransfer) {
            maTypeNames = purchaseCheckDetailsMapper.selectMaTypeNameByTaskIdsBatch(taskIds, purchaseQueryDto.getStatusList());
        } else {
            maTypeNames = purchaseCheckDetailsMapper.selectMaTypeNameByTaskIdsBatch(taskIds, Collections.emptyList());
        }
        Map<Long, String> maTypeNameMap = maTypeNames.stream()
                .filter(info -> info.getTaskId() != null)
                .collect(Collectors.toMap(PurchaseCheckInfo::getTaskId,
                        info -> info.getPurchaseMaTypeName() != null ? info.getPurchaseMaTypeName() : ""));

        List<PurchaseCheckInfo> purchaseCheckInfoResult = new ArrayList<>();
        for (final PurchaseCheckInfo purchaseInfo : purchaseCheckInfos) {
            Long taskId = purchaseInfo.getTaskId();

            // 获取采购物资明细
            List<PurchaseCheckDetails> purchaseCheckDetails = detailsMap.getOrDefault(taskId, Collections.emptyList());
            if (org.springframework.util.CollectionUtils.isEmpty(purchaseCheckDetails)) {
                continue;
            }

            // 过滤掉数量管理并且是待绑定状态或者驳回后待绑定状态的物资
            purchaseCheckDetails = purchaseCheckDetails.stream().filter(o ->
                    !(MaTypeManageTypeEnum.NUMBER_DEVICE.getTypeId().equals(o.getManageType()) &&
                            (o.getStatus().equals(PurchaseTaskStatusEnum.TO_BIND.getStatus()) ||
                                    o.getStatus().equals(PurchaseTaskStatusEnum.TO_BIND_AFTER_REJECT.getStatus())))).collect(Collectors.toList());

            if (isAllowPartTransfer) {
                // 根据任务阶段过滤
                switch (purchaseQueryDto.getTaskStage()) {
                    case PURCHASE_TASK_STAGE_MANAGE:
                        // 新购管理阶段展示全部任务、不进行过滤
                        break;
                    case PURCHASE_TASK_STAGE_CHECK:
                        purchaseCheckDetails = purchaseCheckDetails.stream().filter(o ->
                                !PurchaseTaskStatusEnum.TO_NOTICE.getStatus().equals(o.getStatus()) &&
                                        !PurchaseTaskStatusEnum.TO_CHECK_AFTER_REJECT.getStatus().equals(o.getStatus())).collect(Collectors.toList());
                        break;
                    case PURCHASE_TASK_STAGE_BIND:
                        purchaseCheckDetails = purchaseCheckDetails.stream().filter(o ->
                                !PurchaseTaskStatusEnum.TO_NOTICE.getStatus().equals(o.getStatus()) &&
                                        !PurchaseTaskStatusEnum.TO_CHECK_AFTER_REJECT.getStatus().equals(o.getStatus()) &&
                                        !PurchaseTaskStatusEnum.TO_CHECK.getStatus().equals(o.getStatus()) &&
                                        !PurchaseTaskStatusEnum.TO_BIND_AFTER_REJECT.getStatus().equals(o.getStatus())
                        ).collect(Collectors.toList());
                        break;
                    case PURCHASE_TASK_STAGE_STORE:
                        purchaseCheckDetails = purchaseCheckDetails.stream().filter(o ->
                                PurchaseTaskStatusEnum.IN_STORE.getStatus().equals(o.getStatus()) ||
                                        PurchaseTaskStatusEnum.TO_STORE.getStatus().equals(o.getStatus()) ||
                                        PurchaseTaskStatusEnum.TASK_FINISHED.getStatus().equals(o.getStatus()) ||
                                        (PurchaseTaskStatusEnum.TO_BIND.getStatus().equals(o.getStatus()) && null != o.getBindNum() && 0 < o.getBindNum().compareTo(BigDecimal.ZERO)) ||
                                        (PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus().equals(o.getStatus()) && null != o.getBindNum() && 0 < o.getBindNum().compareTo(BigDecimal.ZERO))
                        ).collect(Collectors.toList());
                        break;
                    default:
                        System.err.println("未知的新购任务阶段：" + purchaseQueryDto.getTaskStage());
                        return Collections.emptyList();
                }
            }

            // 设置物资类型名称
            purchaseInfo.setPurchaseMaTypeName(maTypeNameMap.get(taskId));

            if (!org.springframework.util.CollectionUtils.isEmpty(purchaseCheckDetails)) {
                // 计算数量和金额
                BigDecimal purchaseMaTotalNumber = BigDecimal.ZERO;
                BigDecimal checkMaTotalNumber = BigDecimal.ZERO;
                BigDecimal bindMaTotalNumber = BigDecimal.ZERO;
                BigDecimal inputMaTotalNumber = BigDecimal.ZERO;
                BigDecimal purchaseMaTotalPrice = BigDecimal.ZERO;
                BigDecimal purchaseTaxPriceTotal = BigDecimal.ZERO;

                boolean isIncludeStage = false;
                for (final PurchaseCheckDetails detail : purchaseCheckDetails) {
                    if (null == detail.getPurchaseNum() || null == detail.getPurchasePrice()) {
                        continue;
                    }
                    if (0 > detail.getPurchaseNum().compareTo(BigDecimal.ZERO) || 0 > detail.getPurchasePrice().compareTo(BigDecimal.ZERO)) {
                        throw new IllegalArgumentException("采购数量和价格必须为非负数");
                    }
                    if (!isIncludeStage) {
                        isIncludeStage = PurchaseTaskStatusEnum.isStatusOfStage(detail.getStatus(), PurchaseTaskStageEnum.getByCode(purchaseQueryDto.getTaskStage()), detail.getManageType());
                    }

                    purchaseMaTotalNumber = purchaseMaTotalNumber.add(Optional.of(detail.getPurchaseNum()).orElse(BigDecimal.ZERO));
                    checkMaTotalNumber = checkMaTotalNumber.add(Optional.ofNullable(detail.getCheckNum()).orElse(BigDecimal.ZERO));
                    bindMaTotalNumber = bindMaTotalNumber.add(Optional.ofNullable(detail.getBindNum()).orElse(BigDecimal.ZERO));
                    inputMaTotalNumber = inputMaTotalNumber.add(Optional.ofNullable(detail.getInputNum()).orElse(BigDecimal.ZERO));
                    purchaseMaTotalPrice = purchaseMaTotalPrice.add(detail.getPurchaseNum().multiply(detail.getPurchasePrice()).setScale(10, RoundingMode.HALF_DOWN));
                    purchaseTaxPriceTotal = purchaseTaxPriceTotal.add(detail.getPurchaseNum().multiply(detail.getPurchaseTaxPrice()).setScale(10, RoundingMode.HALF_DOWN));
                }

                purchaseInfo.setPurchaseMaNumber(purchaseMaTotalNumber);
                purchaseInfo.setPurchasePrice(purchaseMaTotalPrice);
                purchaseInfo.setPurchaseTaxPrice(purchaseTaxPriceTotal);
                purchaseInfo.setBindMaNumber(bindMaTotalNumber);
                purchaseInfo.setCheckMaNumber(checkMaTotalNumber);
                purchaseInfo.setInputMaNumber(inputMaTotalNumber);
                purchaseInfo.setWaitInputNumber(purchaseMaTotalNumber.subtract(inputMaTotalNumber));

                // 设置任务状态
                final TmTask tmTask = taskMap.get(taskId);
                purchaseInfo.setTaskStatusName(isIncludeStage ? "未完成" : "已完成");
                if (null != purchaseQueryDto.getIsFinish()) {
                    if (1 == purchaseQueryDto.getIsFinish()) {
                        if (isIncludeStage) {continue;}
                    } else {
                        if (!isIncludeStage) {continue;}
                    }
                }

                // 设置采购状态
                List<Integer> statusList = purchaseCheckDetails.stream()
                        .map(PurchaseCheckDetails::getStatus)
                        .collect(Collectors.toList());

                if (!CollectionUtils.isEmpty(statusList)) {
                    if (statusList.contains(PurchaseTaskStatusEnum.TO_BIND.getStatus()) ||
                            statusList.contains(PurchaseTaskStatusEnum.TO_STORE.getStatus()) ||
                            statusList.contains(PurchaseTaskStatusEnum.TO_BIND_AFTER_REJECT.getStatus()) ||
                            statusList.contains(PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus())) {
                        purchaseInfo.setPurchaseStatus(PurchaseTaskStatusEnum.TO_BIND.getStatus());
                    } else if (statusList.contains(PurchaseTaskStatusEnum.IN_STORE.getStatus()) ||
                            statusList.contains(PurchaseTaskStatusEnum.TASK_IN_PROGRESS.getStatus()) ||
                            statusList.contains(PurchaseTaskStatusEnum.TASK_FINISHED.getStatus())) {
                        purchaseInfo.setPurchaseStatus(PurchaseTaskStatusEnum.IN_STORE.getStatus());
                    } else {
                        purchaseInfo.setPurchaseStatus(0);
                    }
                }

                if (tmTask != null) {
                    purchaseInfo.setTaskStatus(tmTask.getTaskStatus());
                }

                // 检查是否应该加入结果列表
                if (isAllowPartTransfer) {
                    purchaseCheckInfoResult.add(purchaseInfo);
                } else {
                    final OptionalInt minStatus = purchaseCheckDetails.stream().mapToInt(PurchaseCheckDetails::getStatus).min();
                    if (minStatus.isPresent() && purchaseQueryDto.getStatusList().contains(minStatus.getAsInt())) {
                        purchaseCheckInfoResult.add(purchaseInfo);
                    }
                }
            }
        }

        if (!CollectionUtils.isEmpty(purchaseCheckInfoResult)) {
            // 关键字过滤
            String keyWord = purchaseQueryDto.getKeyWord();
            if (!StringUtils.isBlank(keyWord)) {
                purchaseCheckInfoResult = purchaseCheckInfoResult.stream()
                        .filter(item -> containsKeyword(item, keyWord))
                        .collect(Collectors.toList());
            }
        }

        return purchaseCheckInfoResult;
    }

    /**
     * 获取新购验收任务详细信息
     * @param purchaseQueryDto
     * @return
     */
    @Override
    public PurchaseCheckDto getSelectPurchaseCheckInfoById(PurchaseQueryDto purchaseQueryDto) {
        purchaseQueryDto.setUserId(SecurityUtils.getLoginUser().getUserid());
        PurchaseCheckDto purchaseCheckDtoResult = new PurchaseCheckDto();
        PurchaseCheckInfo purchaseCheckInfo = purchaseCheckInfoMapper.selectPurchaseCheckInfoById(purchaseQueryDto.getId());
        if (null != purchaseCheckInfo) {
            purchaseCheckDtoResult.setPurchaseCheckInfo(purchaseCheckInfo);
            List<PurchaseCheckDetails> purchaseCheckDetailsList = purchaseCheckDetailsMapper.selectPurchaseCheckDetailsListById(purchaseQueryDto);
            if (null != purchaseQueryDto.getTaskStage()) {
                // 根据阶段来过滤详情数据
                switch (purchaseQueryDto.getTaskStage()) {
                    case PURCHASE_TASK_STAGE_MANAGE:
                        // 新购管理阶段展示全部任务、不进行过滤
                        break;
                    case PURCHASE_TASK_STAGE_CHECK:
                        purchaseCheckDetailsList = purchaseCheckDetailsList.stream().filter(o -> !PurchaseTaskStatusEnum.TO_NOTICE.getStatus().equals(o.getStatus())).collect(Collectors.toList());
                        break;
                    case PURCHASE_TASK_STAGE_BIND:
                        purchaseCheckDetailsList = purchaseCheckDetailsList.stream().filter(o ->
                                !PurchaseTaskStatusEnum.TO_NOTICE.getStatus().equals(o.getStatus()) && !PurchaseTaskStatusEnum.TO_CHECK_AFTER_REJECT.getStatus().equals(o.getStatus()) &&
                                        !PurchaseTaskStatusEnum.TO_CHECK.getStatus().equals(o.getStatus()) && !PurchaseTaskStatusEnum.TO_BIND_AFTER_REJECT.getStatus().equals(o.getStatus())
                        ).collect(Collectors.toList());
                        break;
                    case PURCHASE_TASK_STAGE_STORE:
                        purchaseCheckDetailsList = purchaseCheckDetailsList.stream().filter(o ->
                                PurchaseTaskStatusEnum.IN_STORE.getStatus().equals(o.getStatus()) ||
                                        PurchaseTaskStatusEnum.TO_STORE.getStatus().equals(o.getStatus()) ||
                                        PurchaseTaskStatusEnum.TASK_FINISHED.getStatus().equals(o.getStatus()) ||
                                        (PurchaseTaskStatusEnum.TO_BIND.getStatus().equals(o.getStatus()) && null != o.getBindNum() && 0 < o.getBindNum().compareTo(BigDecimal.ZERO)) ||
                                        (PurchaseTaskStatusEnum.TO_STORE_AFTER_REJECT.getStatus().equals(o.getStatus()) && null != o.getBindNum() && 0 < o.getBindNum().compareTo(BigDecimal.ZERO))
                        ).collect(Collectors.toList());
                        break;
                    default:
                        System.err.println("未知的新购任务阶段：" + purchaseQueryDto.getTaskStage());
                }
            }
            //查询是否存在附件，给前端用于文件颜色判断
            extractedExitFile(purchaseCheckDetailsList);
            //针对于app查询可能存在的验收图片
            extractedFile(purchaseCheckDetailsList);
            purchaseCheckDtoResult.setPurchaseCheckDetailsList(purchaseCheckDetailsList);
        }
        return purchaseCheckDtoResult;
    }

    /**
     * 提取app新购验收文件信息
     * @param purchaseCheckDetailsList 新购验收明细列表
     */
    private void extractedFile(List<PurchaseCheckDetails> purchaseCheckDetailsList) {
        if (!org.springframework.util.CollectionUtils.isEmpty(purchaseCheckDetailsList)) {
            for (PurchaseCheckDetails purchaseCheckDetails : purchaseCheckDetailsList) {
                final BmFileInfo fileInfo = new BmFileInfo();
                fileInfo.setTaskType(10);
                fileInfo.setModelId(purchaseCheckDetails.getId());
                fileInfo.setTaskId(purchaseCheckDetails.getTaskId());
                final List<BmFileInfo> bmFileInfoList = bmFileInfoMapper.selectBmFileInfoList(fileInfo);
                if (!org.springframework.util.CollectionUtils.isEmpty(bmFileInfoList)) {
                    purchaseCheckDetails.setBmFileInfos(bmFileInfoList);
                }
            }
        }
    }

    /**
     * 查询是否存在附件，给前端用于文件颜色判断
     * @param purchaseCheckDetailsList 新购验收明细列表
     */
    private void extractedExitFile(List<PurchaseCheckDetails> purchaseCheckDetailsList) {
        if (!org.springframework.util.CollectionUtils.isEmpty(purchaseCheckDetailsList)) {
            for (PurchaseCheckDetails purchaseCheckDetails : purchaseCheckDetailsList) {
                final BmFileInfo fileInfo = new BmFileInfo();
                fileInfo.setTaskType(0);
                fileInfo.setModelId(purchaseCheckDetails.getTypeId());
                fileInfo.setTaskId(purchaseCheckDetails.getTaskId());
                final List<BmFileInfo> bmFileInfoList = bmFileInfoMapper.selectBmFileInfoList(fileInfo);
                if (!org.springframework.util.CollectionUtils.isEmpty(bmFileInfoList)) {
                    purchaseCheckDetails.setIsExitFile(0);
                    purchaseCheckDetails.setBmFileInfos(bmFileInfoList);
                }else {
                    purchaseCheckDetails.setIsExitFile(1);
                }
            }
        }
    }

    /**
     * 关键字搜索
     * @param item
     * @param keyWord
     * @return
     */
    private boolean containsKeyword(PurchaseCheckInfo item, String keyWord) {
        return (item.getPurchaseMaTypeName() != null && item.getPurchaseMaTypeName().contains(keyWord)) ||
                (item.getCode() != null && item.getCode().contains(keyWord)) ||
                (item.getSupplier() != null && item.getSupplier().contains(keyWord)) ||
                (item.getCreateBy() != null && item.getCreateBy().contains(keyWord));
    }
}
