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

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.util.PhoneUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.bonus.common.biz.enums.BackTaskStatusEnum;
import com.bonus.common.biz.enums.HttpCodeEnum;
import com.bonus.common.biz.enums.TmTaskTypeEnum;
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.back.domain.BackApplyDetails;
import com.bonus.material.back.domain.MaCodeDto;
import com.bonus.material.back.domain.vo.BackApplyRequestVo;
import com.bonus.material.back.domain.vo.MaCodeVo;
import com.bonus.material.basic.domain.BmFileInfo;
import com.bonus.material.basic.mapper.BmFileInfoMapper;
import com.bonus.material.settlement.domain.SltAgreementInfo;
import com.bonus.material.task.domain.TmTask;
import com.bonus.material.task.domain.TmTaskAgreement;
import com.bonus.material.task.mapper.TmTaskAgreementMapper;
import com.bonus.material.task.mapper.TmTaskMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.bonus.material.back.mapper.BackApplyInfoMapper;
import com.bonus.material.back.domain.BackApplyInfo;
import com.bonus.material.back.service.IBackApplyInfoService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 退料任务Service业务层处理
 * 
 * @author xsheng
 * @date 2024-10-16
 */
@Service
@Slf4j
public class BackApplyInfoServiceImpl implements IBackApplyInfoService {

    @Resource
    private BackApplyInfoMapper backApplyInfoMapper;

    @Resource
    private BmFileInfoMapper bmFileInfoMapper;

    @Resource
    private TmTaskMapper taskMapper;

    @Resource
    private TmTaskAgreementMapper taskAgreementMapper;

    /**
     * 查询退料任务
     * 
     * @param id 退料任务主键
     * @return 退料任务
     */
    @Override
    public BackApplyRequestVo selectBackApplyInfoById(Long id) {
        BackApplyRequestVo backApplyRequestVo = new BackApplyRequestVo();
        //先根据外层id查询上层信息
        BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id);
        backApplyRequestVo.setBackApplyInfo(backApplyInfo);
        //查询退料详情信息
        List<BackApplyDetails> backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(id);
        if (CollectionUtils.isNotEmpty(backApplyDetailsList)) {
            // 批量查询附件信息，减少数据库访问次数
            List<BmFileInfo> bmFileInfos = fetchBmFileInfos(id, backApplyDetailsList);
            // 查询编码设备信息
            List<MaCodeVo> maCodeList = fetchMaCodeList(id);
            for (BackApplyDetails details : backApplyDetailsList) {
                // 为每个退料详情设置附件信息
                setBmFileInfosForDetails(details, bmFileInfos);
                // 如果是编码设备，查询并设置相关的编码信息和附件
                if ("0".equals(details.getManageType())) {
                    setMaCodeDetails(details, maCodeList);
                }
            }
            backApplyRequestVo.setBackApplyDetailsList(backApplyDetailsList);
        }
        return backApplyRequestVo;
    }

    /**
     * 批量查询附件信息
     * @param id
     * @param backApplyDetailsList
     * @return
     */
    private List<BmFileInfo> fetchBmFileInfos(Long id, List<BackApplyDetails> backApplyDetailsList) {
        List<BmFileInfo> bmFileInfos = new ArrayList<>();
        for (BackApplyDetails details : backApplyDetailsList) {
            BmFileInfo bmFileInfo = new BmFileInfo();
            bmFileInfo.setTaskId(id);
            bmFileInfo.setTaskType(3);
            bmFileInfo.setModelId(details.getId());
            List<BmFileInfo> bmFileInfoList = bmFileInfoMapper.selectBmFileInfoList(bmFileInfo);
            // 合并所有附件信息
            bmFileInfos.addAll(bmFileInfoList);
        }
        return bmFileInfos;
    }

    /**
     * 查询编码设备信息
     * @param id
     * @return
     */
    private List<MaCodeVo> fetchMaCodeList(Long id) {
        return backApplyInfoMapper.selectByCode(id);
    }

    /**
     * 为每个退料详情设置附件信息
     * @param details
     * @param bmFileInfos
     */
    private void setBmFileInfosForDetails(BackApplyDetails details, List<BmFileInfo> bmFileInfos) {
        // 为每个退料详情设置附件信息
        List<BmFileInfo> relatedFileInfos = bmFileInfos.stream()
                .filter(fileInfo -> fileInfo.getModelId().equals(details.getId()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(relatedFileInfos)) {
            details.setBmFileInfos(relatedFileInfos);
        }
    }

    /**
     * 为编码设备详情设置编码信息和附件信息
     * @param details
     * @param maCodeList
     */
    private void setMaCodeDetails(BackApplyDetails details, List<MaCodeVo> maCodeList) {
        List<MaCodeDto> maCodeDtos = new ArrayList<>();
        for (MaCodeVo maCodeVo : maCodeList) {
            MaCodeDto maCodeDto = new MaCodeDto();
            maCodeDto.setMaCode(maCodeVo.getMaCode());
            maCodeDto.setMaId(maCodeVo.getMaId());
            maCodeDto.setApDetection(maCodeVo.getApDetection());
            maCodeDto.setTypeName(maCodeVo.getTypeName());
            maCodeDto.setMaterialName(maCodeVo.getMaterialName());
            maCodeDto.setTypeId(maCodeVo.getTypeId());
            maCodeDto.setMaStatus(maCodeVo.getMaStatus());
            maCodeDto.setMaterialType(maCodeVo.getMaterialType());
            // 查询并设置编码附件
            List<BmFileInfo> bmFileInfoList = fetchBmFileInfos(details.getId(), maCodeVo.getMaId());
            if (CollectionUtils.isNotEmpty(bmFileInfoList)) {
                maCodeDto.setBmFileInfos(bmFileInfoList);
            }
            maCodeDtos.add(maCodeDto);
        }
        details.setMaCodeList(maCodeDtos);
    }

    /**
     * 查询编码设备附件信息
     * @param taskId
     * @param modelId
     * @return
     */
    private List<BmFileInfo> fetchBmFileInfos(Long taskId, Long modelId) {
        BmFileInfo fileInfo = new BmFileInfo();
        fileInfo.setTaskId(taskId);
        fileInfo.setTaskType(3);
        fileInfo.setModelId(modelId);
        return bmFileInfoMapper.selectBmFileInfoList(fileInfo);
    }

    /**
     * 查询退料任务列表
     * 
     * @param backApplyInfo 退料任务
     * @return 退料任务
     */
    @Override
    public List<BackApplyInfo> selectBackApplyInfoList(BackApplyInfo backApplyInfo) {
        List<BackApplyInfo> list = backApplyInfoMapper.selectBackApplyInfoList(backApplyInfo);
        // 如果列表为空，直接返回空列表
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        // 如果需要导出
        if (backApplyInfo.getIsExport()) {
            for (BackApplyInfo applyInfo : list) {
                applyInfo.setPrintStatus("0".equals(applyInfo.getPrintStatus()) ? "未打印" : "已打印");
                switch (applyInfo.getStatus()) {
                    case "0":
                        applyInfo.setStatus("退料未完成");
                        break;
                    case "1":
                        applyInfo.setStatus("维修驳回");
                        break;
                    case "2":
                        applyInfo.setStatus("退料已完成");
                        break;
                    default:
                        break;
                }
            }
        }
        return list;
    }

    /**
     * 新增退料任务
     * 
     * @param dto 退料任务
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertBackApplyInfo(BackApplyRequestVo dto) {
        if (dto == null || dto.getBackApplyInfo() == null || CollectionUtils.isEmpty(dto.getBackApplyDetailsList())) {
            return AjaxResult.error("参数为空，请重新选择后上传!");
        }
        //对传入的手机号进行校验
        if (StringUtils.isNotBlank(dto.getBackApplyInfo().getPhone()) && !PhoneUtil.isMobile(dto.getBackApplyInfo().getPhone())) {
            return AjaxResult.error("手机号格式不正确，请重新填写!");
        }
        //对提交的退料详情数目进行校验
        for (BackApplyDetails backApplyDetails : dto.getBackApplyDetailsList()) {
            if (backApplyDetails.getNum() != null && backApplyDetails.getPreNum() != null) {
                if (backApplyDetails.getNum() < backApplyDetails.getPreNum()) {
                    return AjaxResult.error("退料数量不能大于预退数量，请重新填写!");
                }
            }
        }
        //生成退料单号
        String code = getString();
        if (StringUtils.isBlank(code)) {
            return AjaxResult.error("后台退料编号生成异常，请重试!");
        }
        int result = 0;
        try {
             int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId());
             TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(),
                    BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus(),
                    null,thisMonthMaxOrder + 1, code);
             tmTask.setCreateTime(DateUtils.getNowDate());
             tmTask.setCreateBy(SecurityUtils.getUsername());
             BackApplyInfo backApplyInfo = dto.getBackApplyInfo();
             backApplyInfo.setTaskId(tmTask.getTaskId());
             backApplyInfo.setCode(code);
             backApplyInfo.setCreateBy(SecurityUtils.getUsername());
             backApplyInfo.setCreateTime(DateUtils.getNowDate());
             // 保存退料信息到 tm_task 表中
             result += taskMapper.insertTmTask(tmTask);
             if (result > 0) {
                TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(tmTask.getTaskId(), dto.getBackApplyInfo().getAgreementId());
                tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
                tmTaskAgreement.setCreateBy(SecurityUtils.getUsername());
                taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
                result += backApplyInfoMapper.insertBackApplyInfo(backApplyInfo);
             }
             // 保存退料详情
             result = saveBackApplyDetails(dto, backApplyInfo, result);
        } catch (Exception e) {
            log.error("保存退料信息时发生异常: ", e);
        }
        return result > 0 ? AjaxResult.success() : AjaxResult.error("保存失败，请重试!");
    }

    /**
     * 保存退料详情
     * @param dto
     * @param backApplyInfo
     * @param result
     * @return
     */
    private int saveBackApplyDetails(BackApplyRequestVo dto, BackApplyInfo backApplyInfo, int result) {
        for (BackApplyDetails details : dto.getBackApplyDetailsList()) {
            details.setCode(backApplyInfo.getCode());
            details.setParentId(backApplyInfo.getId());
            details.setAuditNum(details.getPreNum());
            details.setStatus(String.valueOf(BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus()));
            details.setCreateBy(SecurityUtils.getUsername());
            details.setCreateTime(DateUtils.getNowDate());
            // 保存退料详情
            result += backApplyInfoMapper.insertBackApplyDetails(details);
            // 处理附件
            result = saveBmFileInfo(details, backApplyInfo.getId(), result);
            // 判断是否为编码设备并处理附件
            result = saveMaCodeBmFileInfo(details, backApplyInfo.getId(), result);
        }
        return result;
    }

    /**
     * 保存附件
     * @param details
     * @param taskId
     * @param result
     * @return
     */
    private int saveBmFileInfo(BackApplyDetails details, Long taskId, int result) {
        if (CollectionUtils.isNotEmpty(details.getBmFileInfos())) {
            for (BmFileInfo bmFileInfo : details.getBmFileInfos()) {
                bmFileInfo.setCreateBy(SecurityUtils.getUsername());
                bmFileInfo.setCreateTime(DateUtils.getNowDate());
                bmFileInfo.setTaskId(taskId);
                bmFileInfo.setTaskType(3);
                bmFileInfo.setModelId(details.getId());
                result += bmFileInfoMapper.insertBmFileInfo(bmFileInfo);
            }
        }
        return result;
    }

    /**
     * 保存编码设备附件
     * @param details
     * @param id
     * @param result
     * @return
     */
    private int saveMaCodeBmFileInfo(BackApplyDetails details, Long id, int result) {
        // 设置公共字段
        setCommonFields(details, id);
        if (CollectionUtils.isNotEmpty(details.getMaCodeList())) {
            for (MaCodeDto maCodeDto : details.getMaCodeList()) {
                // 设置每个 MaCodeDto 的独立属性
                details.setMaId(maCodeDto.getMaId());
                details.setPreNum(1);
                // 插入 CheckDetails
                result += backApplyInfoMapper.insertCheckDetails(details);
                if (CollectionUtils.isNotEmpty(maCodeDto.getBmFileInfos())) {
                    for (BmFileInfo bmFileInfo : maCodeDto.getBmFileInfos()) {
                        bmFileInfo.setCreateBy(SecurityUtils.getUsername());
                        bmFileInfo.setCreateTime(DateUtils.getNowDate());
                        bmFileInfo.setTaskId(details.getId());
                        bmFileInfo.setTaskType(3);
                        bmFileInfo.setModelId(maCodeDto.getMaId());
                        result += bmFileInfoMapper.insertBmFileInfo(bmFileInfo);
                    }
                }
            }
        } else {
            // 如果 MaCodeList 为空，只插入 CheckDetails
            result += backApplyInfoMapper.insertCheckDetails(details);
        }
        return result;
    }

    /**
     * 设置公共字段
     * @param details
     * @param id
     */
    private void setCommonFields(BackApplyDetails details, Long id) {
        details.setParentId(id);
        details.setCreateBy(SecurityUtils.getUsername());
        details.setCreateTime(DateUtils.getNowDate());
        details.setStatus("0");
        // 默认为 0，表示未完成
        details.setIsFinished(0);
        // 默认返回状态 1
        details.setBackStatus("1");
    }

    /**
     * 生成退料单号
     * @return
     */
    private String getString() {
        //根据前台传过来的数据，生成退料单号
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String taskNum = backApplyInfoMapper.selectTaskNumByMonth(nowDate, 3);
        if (StringUtils.isNotBlank(taskNum)) {
            // 将字符串转换为整数
            int num = Integer.parseInt(taskNum);
            // 执行加一操作
            num++;
            // 将结果转换回字符串格式，并确保结果是2位数，不足2位则在前面补0
            taskNum = String.format("%02d", num);
        } else {
            taskNum = "01";
        }
        return "T" + format + "-" + taskNum;
    }

    /**
     * 修改退料任务
     * 
     * @param dto 退料任务
     * @return 结果
     */
    @Override
    public AjaxResult updateBackApplyInfo(BackApplyRequestVo dto) {
        if (dto == null || dto.getBackApplyInfo() == null || CollectionUtils.isEmpty(dto.getBackApplyDetailsList())) {
            return AjaxResult.error("参数为空，请重新选择后上传!");
        }
        //对提交的退料详情树木进行校验
        for (BackApplyDetails backApplyDetails : dto.getBackApplyDetailsList()) {
            if (backApplyDetails.getNum() != null && backApplyDetails.getPreNum() != null) {
                if (backApplyDetails.getNum() < backApplyDetails.getPreNum()) {
                    return AjaxResult.error("退料数量不能大于预退数量，请重新填写!");
                }
            }
        }
        try {
            //针对修改，先删除，后添加
            //对传入的手机号进行校验
            if (StringUtils.isNotBlank(dto.getBackApplyInfo().getPhone()) && !PhoneUtil.isMobile(dto.getBackApplyInfo().getPhone())) {
                return AjaxResult.error("手机号格式不正确，请重新填写!");
            }
            // 查询信息
            Long id = dto.getId();
            BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id);
            List<BackApplyDetails> backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(id);
            List<MaCodeVo> maCodeList = backApplyInfoMapper.selectByCode(id);
            // 删除相关任务信息
            int result = 0;
            result += taskMapper.deleteTmTaskByTaskId(backApplyInfo.getTaskId());
            result += taskAgreementMapper.deleteTmTaskAgreementByTaskId(backApplyInfo.getTaskId());
            result += backApplyInfoMapper.deleteBackApplyDetails(backApplyInfo.getId());
            result += backApplyInfoMapper.deleteCheckDetails(backApplyInfo.getId());
            // 删除退料详情附件
            result += deleteFileInfoForDetails(backApplyDetailsList, id);
            // 删除编码设备附件
            result += deleteFileInfoForMaCodes(maCodeList, id);

            if (result > 0) {
                //执行新增操作
                backApplyInfo.setTaskType(TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId());
                backApplyInfo.setTaskStatus(BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus());
                backApplyInfo.setId(id);
                backApplyInfo.setUpdateTime(DateUtils.getNowDate());
                backApplyInfo.setUpdateBy(SecurityUtils.getUsername());
                backApplyInfo.setBackPerson(dto.getBackApplyInfo().getBackPerson());
                backApplyInfo.setPhone(dto.getBackApplyInfo().getPhone());
                backApplyInfo.setRemark(dto.getBackApplyInfo().getRemark() == null ? backApplyInfo.getRemark() : dto.getBackApplyInfo().getRemark());
                int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId());
                TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(), BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus(),
                    null,thisMonthMaxOrder + 1, backApplyInfo.getCode());
                tmTask.setCreateTime(DateUtils.getNowDate());
                tmTask.setCreateBy(SecurityUtils.getUsername());
                // 保存退料信息到 tm_task 表中
                result += taskMapper.insertTmTask(tmTask);
                backApplyInfo.setTaskId(tmTask.getTaskId());
                if (result > 0) {
                    TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(tmTask.getTaskId(), dto.getBackApplyInfo().getAgreementId());
                    tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
                    tmTaskAgreement.setCreateBy(SecurityUtils.getUsername());
                    taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
                    result += backApplyInfoMapper.updateBackApplyInfo(backApplyInfo);
                }
                // 保存退料详情
                result = saveBackApplyDetails(dto, backApplyInfo, result);
                return AjaxResult.success(result);
            }
        } catch (Exception e) {
            throw new ServiceException("修改失败，请联系管理员");
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 删除退料任务信息
     * 
     * @param id 退料任务主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteBackApplyInfoById(Long id) {
        try {
            // 查询信息
            BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id);
            List<BackApplyDetails> backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(id);
            List<MaCodeVo> maCodeList = backApplyInfoMapper.selectByCode(id);
            // 删除相关任务信息
            int result = deleteTaskInfo(backApplyInfo);
            // 删除退料详情附件
            result += deleteFileInfoForDetails(backApplyDetailsList, id);
            // 删除编码设备附件
            result += deleteFileInfoForMaCodes(maCodeList, id);
            if (result > 0) {
                return AjaxResult.success(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 删除任务信息
     * @param backApplyInfo
     * @return
     */
    private int deleteTaskInfo(BackApplyInfo backApplyInfo) {
        // 删除任务、任务协议及相关信息
        int result = 0;
        result += taskMapper.deleteTmTaskByTaskId(backApplyInfo.getTaskId());
        result += taskAgreementMapper.deleteTmTaskAgreementByTaskId(backApplyInfo.getTaskId());
        result += backApplyInfoMapper.deleteBackApply(backApplyInfo.getId());
        result += backApplyInfoMapper.deleteBackApplyDetails(backApplyInfo.getId());
        result += backApplyInfoMapper.deleteCheckDetails(backApplyInfo.getId());
        return result;
    }

    /**
     * 删除退料详情相关附件
     * @param backApplyDetailsList
     * @param taskId
     * @return
     */
    private int deleteFileInfoForDetails(List<BackApplyDetails> backApplyDetailsList, Long taskId) {
        // 删除退料详情相关附件
        int result = 0;
        if (CollectionUtils.isNotEmpty(backApplyDetailsList)) {
            for (BackApplyDetails details : backApplyDetailsList) {
                BmFileInfo bmFileInfo = new BmFileInfo();
                bmFileInfo.setModelId(details.getId());
                bmFileInfo.setTaskId(taskId);
                bmFileInfo.setTaskType(3);
                result += bmFileInfoMapper.deleteBmFileInfoByBizInfo(bmFileInfo);
            }
        }
        return result;
    }

    /**
     * 删除编码设备相关附件
     * @param maCodeList
     * @param taskId
     * @return
     */
    private int deleteFileInfoForMaCodes(List<MaCodeVo> maCodeList, Long taskId) {
        // 删除编码设备相关附件
        int result = 0;
        if (CollectionUtils.isNotEmpty(maCodeList)) {
            for (MaCodeVo maCodeVo : maCodeList) {
                BmFileInfo bmFileInfo = new BmFileInfo();
                bmFileInfo.setModelId(maCodeVo.getMaId());
                bmFileInfo.setTaskId(taskId);
                bmFileInfo.setTaskType(3);
                result += bmFileInfoMapper.deleteBmFileInfoByBizInfo(bmFileInfo);
            }
        }
        return result;
    }

    /**
     * 根据机具编码和类型查询机具是否存在
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getMachineById(BackApplyInfo dto) {
        if (dto == null || dto.getUnitId() == null || dto.getProId() == null || StringUtils.isBlank(dto.getTypeId())) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "参数不能为空");
        }
        return AjaxResult.success(backApplyInfoMapper.getMachineById(dto));
    }

    /**
     * 提交退料申请
     * @param backApplyInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submitBackApply(BackApplyInfo backApplyInfo) {
        int result = 0;
        //先查询退料详情信息
        List<BackApplyDetails> applyDetails = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(backApplyInfo.getId());
        if (CollectionUtils.isNotEmpty(applyDetails)) {
            for (BackApplyDetails applyDetail : applyDetails) {
                if (applyDetail.getPreNum() > applyDetail.getNum()) {
                    return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "退料数量不能大于在用数量");
                }
                result += backApplyInfoMapper.updateBackApplyDetails(applyDetail);
            }
        }
        // 根据传入的id查询退料申请信息
        List<BackApplyInfo> applyInfoList = backApplyInfoMapper.selectBackDetails(backApplyInfo);
        // 设置更新信息
        backApplyInfo.setUpdateBy(SecurityUtils.getUsername());
        backApplyInfo.setUpdateTime(DateUtils.getNowDate());
        backApplyInfo.setTaskStatus(2);
        // 更新任务表及退料申请表状态
        result += updateTaskAndBackInfo(backApplyInfo);
        if (result > 0 && CollectionUtils.isNotEmpty(applyInfoList)) {
            // 获取applyInfoList的typeId并生成集合
            List<String> typeIdList = applyInfoList.stream()
                    .map(BackApplyInfo::getTypeId).distinct()
                    .collect(Collectors.toList());
            // 插入任务表
            Long newTaskId = insertTt(SecurityUtils.getUsername());
            // 插入协议任务表
            result += insertTta(newTaskId, applyInfoList);
            for (String typeId : typeIdList) {
                // 查询待维修的机具设备
                backApplyInfo.setTypeId(typeId);
                List<BackApplyInfo> wxList = backApplyInfoMapper.getWxList(backApplyInfo);
                if (CollectionUtils.isNotEmpty(wxList)) {
                    // 插入维修记录表
                    result += insertRad(newTaskId, wxList);
                    // 更新结算表
                    List<BackApplyInfo> allList = backApplyInfoMapper.selectBackDetails(backApplyInfo);
                    if (CollectionUtils.isNotEmpty(allList)) {
                        int res = updateSlt4Bean(backApplyInfo, allList);
                        // 检查机具是否领料
                        if (res == 0) {
                            throw new RuntimeException("该机具未被领料使用");
                        }
                    }
                    // 完成退料部分，更新 back_check_details
                    finishBackCheckDetails(backApplyInfo);
                }
            }
            // 如果所有操作都成功
            if (result > 0) {
                return AjaxResult.success();
            }
        }
        // 操作失败，返回错误
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 编辑打印状态
     * @param dto
     * @return
     */
    @Override
    public AjaxResult editPrintStatus(BackApplyInfo dto) {
        int result = backApplyInfoMapper.updateBackApplyInfo(dto);
        return result > 0 ? AjaxResult.success() : AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 新增退料申请app
     * @param dto
     * @return
     */
    @Override
    public AjaxResult insertApp(BackApplyRequestVo dto) {
        return null;
    }

    /**
     * 更新任务表及退料申请表状态
     * @param backApplyInfo
     * @return
     */
    private int updateTaskAndBackInfo(BackApplyInfo backApplyInfo) {
        int result = backApplyInfoMapper.updateTaskStatus(backApplyInfo);
        result += backApplyInfoMapper.updateBack(backApplyInfo);
        result += backApplyInfoMapper.updateBackDetails(backApplyInfo);
        return result;
    }

    /**
     * 更新结算表
     * @param record
     * @param allList
     * @return
     */
    private int updateSlt4Bean(BackApplyInfo record, List<BackApplyInfo> allList) {
        for (BackApplyInfo bean : allList) {
            List<SltAgreementInfo> infoList = backApplyInfoMapper.getStlInfo(bean);
            if (infoList.size() > 0) {
                Integer backNum = bean.getBackNum();
                for (SltAgreementInfo info : infoList) {
                    Integer num = info.getBackNum();
                    if (backNum.equals(num)) {
                        backApplyInfoMapper.updateStlInfo(info, record);
                        break;
                    } else if (backNum > num) {
                        backNum = backNum - num;
                        backApplyInfoMapper.updateStlInfo(info, record);
                    } else {
                        Integer many = num - backNum;
                        backApplyInfoMapper.updateStlInfoTwo(info, record, backNum);
                        backApplyInfoMapper.insStlInfoTwo(info, many);
                        break;
                    }
                }
            } else {
                return 0;
            }
        }
        return 1;
    }

    /**
     * 完成退料申请
     * @param backApplyInfo
     */
    private void finishBackCheckDetails(BackApplyInfo backApplyInfo) {
        backApplyInfoMapper.updateCheckDetails(backApplyInfo);
    }

    /**
     * 插入维修记录表
     * @param taskId
     * @param wxList
     * @return
     */
    private int insertRad(Long taskId, List<BackApplyInfo> wxList) {
        int result = 0;
        if (wxList != null) {
            for (BackApplyInfo wx : wxList) {
                wx.setTaskId(taskId);
                wx.setStatus("0");
                result = backApplyInfoMapper.insertRad(wx);
            }
        }
        return result;
    }

    /**
     * 插入协议任务表
     * @param taskId
     * @param list
     * @return
     */
    private int insertTta(Long taskId, List<BackApplyInfo> list) {
        int res;
        String agreementId = String.valueOf(list.get(0).getAgreementId());
        TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(taskId, Long.parseLong(agreementId));
        tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
        tmTaskAgreement.setCreateBy(SecurityUtils.getUsername());
        res = taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
        return res;
    }

    /**
     * 插入任务表
     * @param createBy
     * @return
     */
    private Long insertTt(String createBy) {
        Long newTask = null;
        // 生成维修单号
        String code = genCodeRule();
        int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId());
        TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(), BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus(),
                    null,thisMonthMaxOrder + 1, code);
        tmTask.setCreateTime(DateUtils.getNowDate());
        tmTask.setCreateBy(createBy);
        // 插入任务
        int taskId = taskMapper.insertTmTask(tmTask);
        // 如果插入成功且返回的 taskId 大于 0
        if (taskId > 0 && tmTask.getTaskId() > 0) {
            newTask = tmTask.getTaskId();
        }
        return newTask;
    }

    /**
     * 生成维修单号
     * @return
     */
    private String genCodeRule() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        Integer taskNum = backApplyInfoMapper.selectTaskNumByMonthWx(nowDate);
        String taskNumStr = "";
        if (taskNum != null) {
            // 将字符串转换为整数
//            int num = Integer.parseInt(taskNum);
            // 执行加一操作
            taskNum++;
            // 将结果转换回字符串格式，并确保结果是四位数，不足四位则在前面补0
            taskNumStr = String.format("%02d", taskNum);
        } else {
            taskNumStr = "01";
        }
        return "WX" + format + "-" + taskNumStr;
    }

}
