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

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.bonus.common.biz.constant.MaterialConstants;
import com.bonus.common.biz.enums.*;
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.common.biz.domain.BmFileInfo;
import com.bonus.material.basic.mapper.BmFileInfoMapper;
import com.bonus.material.ma.domain.Type;
import com.bonus.material.ma.domain.vo.MachineVo;
import com.bonus.material.ma.mapper.MachineMapper;
import com.bonus.material.scrap.domain.MaCodeInfo;
import com.bonus.material.scrap.domain.vo.ScrapDetailsListVo;
import com.bonus.material.scrap.domain.vo.ScrapTaskListVo;
import com.bonus.material.scrap.domain.vo.ScrapTotalListVo;
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.scrap.mapper.ScrapApplyDetailsMapper;
import com.bonus.material.scrap.domain.ScrapApplyDetails;
import com.bonus.material.scrap.service.IScrapApplyDetailsService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 报废任务详细Service业务层处理
 *
 * @author xsheng
 * @date 2024-10-16
 */
@Service
@Slf4j
public class ScrapApplyDetailsServiceImpl implements IScrapApplyDetailsService {
    @Resource
    private ScrapApplyDetailsMapper scrapApplyDetailsMapper;

    @Resource
    private TmTaskMapper taskMapper;

    @Resource
    private TmTaskAgreementMapper taskAgreementMapper;

    @Resource
    private BmFileInfoMapper fileInfoMapper;

    @Resource
    private MachineMapper machineMapper;

    /**
     * 查询报废任务详细
     *
     * @param id 报废任务详细主键
     * @return 报废任务详细
     */
    @Override
    public ScrapApplyDetails selectScrapApplyDetailsById(Long id) {
        return scrapApplyDetailsMapper.selectScrapApplyDetailsById(id);
    }

    /**
     * 查询报废任务详细列表
     *
     * @param scrapApplyDetails 报废任务详细
     * @return 报废任务详细
     */
    @Override
    public List<ScrapTaskListVo> selectScrapApplyDetailsList(ScrapApplyDetails scrapApplyDetails) {
        List<ScrapTaskListVo> list = scrapApplyDetailsMapper.selectScrapApplyDetailsList(scrapApplyDetails);
        if (CollectionUtils.isNotEmpty(list)) {
            String keyWord = scrapApplyDetails.getKeyWord();
            // 如果关键字不为空，进行过滤
            if (!StringUtils.isBlank(keyWord)) {
                list = list.stream()
                        .filter(item -> containsKeyword(item, keyWord))
                        .collect(Collectors.toList());
            }
        }
        return list;
    }

    /**
     * 关键字搜索
     * @param item
     * @param keyWord
     * @return
     */
    private boolean containsKeyword(ScrapTaskListVo item, String keyWord) {
        return (item.getType() != null && item.getType().contains(keyWord)) ||
                (item.getRepairCode() != null && item.getRepairCode().contains(keyWord)) ||
                (item.getScrapCode() != null && item.getScrapCode().contains(keyWord)) ||
                (item.getBackUnit() != null && item.getBackUnit().contains(keyWord)) ||
                (item.getBackPro() != null && item.getBackPro().contains(keyWord)) ||
                (item.getCreateName() != null && item.getCreateName().contains(keyWord));
    }

    /**
     * 查询报废任务详细列表
     *
     * @param scrapApplyDetails 报废任务详细
     * @return 报废任务详细集合
     */
    @Override
    public List<ScrapApplyDetails> selectRepairQuestListByTaskId(ScrapApplyDetails scrapApplyDetails) {
        List<ScrapApplyDetails> list = scrapApplyDetailsMapper.selectRepairQuestListByTaskId(scrapApplyDetails);
        if (CollectionUtils.isNotEmpty(list)) {
            for (ScrapApplyDetails applyDetails : list) {
                BigDecimal totalCost = applyDetails.getScrapNum().multiply(applyDetails.getBuyPrice());
                applyDetails.setTotalCost(totalCost);
                BmFileInfo bmFileInfo = new BmFileInfo();
                bmFileInfo.setModelId(applyDetails.getRepairId());
                bmFileInfo.setTaskType(4);
                List<BmFileInfo> fileInfos = fileInfoMapper.selectBmFileInfoList(bmFileInfo);
                applyDetails.setFileList(fileInfos);
            }
        }
        return list;
    }

    /**
     * 新增报废任务详细
     *
     * @param scrapApplyDetails 报废任务详细
     * @return 结果
     */
    @Override
    public int insertScrapApplyDetails(ScrapApplyDetails scrapApplyDetails) {
        scrapApplyDetails.setCreateTime(DateUtils.getNowDate());
        try {
            return scrapApplyDetailsMapper.insertScrapApplyDetails(scrapApplyDetails);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 修改报废任务详细
     *
     * @param scrapApplyDetails 报废任务详细
     * @return 结果
     */
    @Override
    public int updateScrapApplyDetails(ScrapApplyDetails scrapApplyDetails) {
        scrapApplyDetails.setUpdateTime(DateUtils.getNowDate());
        try {
            return scrapApplyDetailsMapper.updateScrapApplyDetails(scrapApplyDetails);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 批量删除报废任务详细
     *
     * @param ids 需要删除的报废任务详细主键
     * @return 结果
     */
    @Override
    public int deleteScrapApplyDetailsByIds(Long[] ids) {
        return scrapApplyDetailsMapper.deleteScrapApplyDetailsByIds(ids);
    }

    /**
     * 删除报废任务详细信息
     *
     * @param id 报废任务详细主键
     * @return 结果
     */
    @Override
    public int deleteScrapApplyDetailsById(Long id) {
        return scrapApplyDetailsMapper.deleteScrapApplyDetailsById(id);
    }

    /**
     * 报废审核通过
     * @param scrapApplyDetails
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult approve(ScrapApplyDetails scrapApplyDetails) {
        // TODO: 报废审核二级页面通过
        int result = 0;
        if (scrapApplyDetails != null) {
           if (CollectionUtils.isNotEmpty(scrapApplyDetails.getScrapApplyDetailsList())) {
                for (ScrapApplyDetails applyDetails : scrapApplyDetails.getScrapApplyDetailsList()) {
                    applyDetails.setStatus("1");
                    applyDetails.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                    applyDetails.setAuditTime(DateUtils.getNowDate());
                    result = scrapApplyDetailsMapper.updateStatus(applyDetails);
                }
                if (result > 0) {
                    updateTaskStatus(scrapApplyDetails.getScrapApplyDetailsList().get(0));
                }
                // TODO: 报废审核一级页面通过
            } else if (CollectionUtils.isNotEmpty(scrapApplyDetails.getScrapTaskListVoList())) {
                for (ScrapTaskListVo taskListVo : scrapApplyDetails.getScrapTaskListVoList()) {
                    // 根据任务id 查询任务详情
                    ScrapApplyDetails applyDetails = new ScrapApplyDetails();
                    applyDetails.setTaskId(taskListVo.getTaskId());
                    List<ScrapApplyDetails> scrapApplyDetailsList = scrapApplyDetailsMapper.selectRepairQuestListByTaskId(applyDetails);
                    // 将集合中status为0的筛选出来
                    List<ScrapApplyDetails> applyDetailsList = scrapApplyDetailsList.stream().filter(applyDetails1 -> "0".equals(applyDetails1.getStatus())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(applyDetailsList)) {
                        for (ScrapApplyDetails applyDetails1 : applyDetailsList) {
                            applyDetails1.setStatus("1");
                            applyDetails1.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                            applyDetails1.setAuditTime(DateUtils.getNowDate());
                            result = scrapApplyDetailsMapper.updateStatus(applyDetails1);
                        }
                    }
                    if (result > 0) {
                        updateTaskStatus(applyDetails);
                    }
                }
            }
        }
        if (result > 0) {
            return AjaxResult.success("审核通过");
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 更新任务状态
     * @param scrapApplyDetails
     */
    private void updateTaskStatus(ScrapApplyDetails scrapApplyDetails) {
        List<ScrapApplyDetails> list = scrapApplyDetailsMapper.selectRepairQuestListByTaskId(scrapApplyDetails);
        List<Integer> statusList = list.stream()
                .map(scrapApplyDetail -> Integer.parseInt(scrapApplyDetail.getStatus()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(statusList)) {
            boolean notContainsNoFinished =!statusList.contains(ScrapTaskStatusEnum.SCRAP_TASK_NO_FINISHED.getStatus());
            boolean allReject = true;
            for (Integer status : statusList) {
                if (!status.equals(ScrapTaskStatusEnum.SCRAP_TASK_TO_REJECT.getStatus())) {
                    allReject = false;
                    break;
                }
            }
            if (notContainsNoFinished && !allReject) {
                taskMapper.updateTaskStatus(scrapApplyDetails.getTaskId().toString(), ScrapTaskStatusEnum.SCRAP_TASK_IN_FINISHED.getStatus());
            } else if (notContainsNoFinished && allReject) {
                taskMapper.updateTaskStatus(scrapApplyDetails.getTaskId().toString(), ScrapTaskStatusEnum.SCRAP_TASK_TO_REJECT.getStatus());
            }
        }
    }

    /**
     * 报废审核驳回
     * @param scrapApplyDetails
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult reject(ScrapApplyDetails scrapApplyDetails) {
        // TODO: 报废审核二级页面驳回
        int result = 0;
        if (scrapApplyDetails != null) {
            if (CollectionUtils.isNotEmpty(scrapApplyDetails.getScrapApplyDetailsList())) {
                //插入任务表
                Long newTaskId = insertTt(scrapApplyDetails.getTaskId());
                result += insertTta(newTaskId, scrapApplyDetails);
                for (ScrapApplyDetails applyDetails : scrapApplyDetails.getScrapApplyDetailsList()) {
                    applyDetails.setStatus("2");
                    applyDetails.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                    applyDetails.setAuditTime(DateUtils.getNowDate());
                    result = scrapApplyDetailsMapper.updateStatus(applyDetails);
                    Long backId = scrapApplyDetailsMapper.selectBackIdByTaskId(applyDetails.getParentId());
                    applyDetails.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                    applyDetails.setCreateTime(DateUtils.getNowDate());
                    applyDetails.setBackId(backId);
                    applyDetails.setNewTaskId(newTaskId);
                    if (applyDetails.getMaId() != null) {
                        applyDetails.setStatus(MaMachineStatusEnum.BACK_REPAIR.getStatus().toString());
                        result += scrapApplyDetailsMapper.updateMaStatus(applyDetails);
                    }
                    result += insertWxTask(applyDetails);
                }
                if (result > 0) {
                    updateTaskStatus(scrapApplyDetails.getScrapApplyDetailsList().get(0));
                }
                // TODO: 报废审核一级页面驳回
            } else if (CollectionUtils.isNotEmpty(scrapApplyDetails.getScrapTaskListVoList())) {
                for (ScrapTaskListVo taskListVo : scrapApplyDetails.getScrapTaskListVoList()) {
                    // 根据任务id 查询任务详情
                    ScrapApplyDetails applyDetails = new ScrapApplyDetails();
                    applyDetails.setTaskId(taskListVo.getTaskId());
                    applyDetails.setAgreementId(taskListVo.getAgreementId());
                    //插入任务表
                    Long newTaskId = insertTt(taskListVo.getTaskId());
                    result += insertTta(newTaskId, applyDetails);
                    List<ScrapApplyDetails> scrapApplyDetailsList = scrapApplyDetailsMapper.selectRepairQuestListByTaskId(applyDetails);
                    // 将集合中status为0的筛选出来
                    if (CollectionUtils.isNotEmpty(scrapApplyDetailsList)) {
                        List<ScrapApplyDetails> applyDetailsList = scrapApplyDetailsList.stream().filter(applyDetails1 -> "0".equals(applyDetails1.getStatus())).collect(Collectors.toList());
                        for (ScrapApplyDetails applyDetails1 : applyDetailsList) {
                            applyDetails1.setStatus("2");
                            applyDetails1.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                            applyDetails1.setAuditTime(DateUtils.getNowDate());
                            result = scrapApplyDetailsMapper.updateStatus(applyDetails1);
                            if (applyDetails1.getMaId() != null) {
                                applyDetails.setStatus(MaMachineStatusEnum.BACK_REPAIR.getStatus().toString());
                                result += scrapApplyDetailsMapper.updateMaStatus(applyDetails1);
                            }
                            Long backId = scrapApplyDetailsMapper.selectBackIdByTaskId(applyDetails1.getParentId());
                            applyDetails1.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                            applyDetails1.setCreateTime(DateUtils.getNowDate());
                            applyDetails1.setBackId(backId);
                            applyDetails1.setNewTaskId(newTaskId);
                            result += insertWxTask(applyDetails1);
                        }
                    }
                    if (result > 0) {
                        updateTaskStatus(applyDetails);
                    }
                }
            }
        }
        if (result > 0) {
            return AjaxResult.success("驳回成功");
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 查询报废台账任务列表
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public List<ScrapTotalListVo> selectTotalScrapApplyDetailsList(ScrapApplyDetails scrapApplyDetails) {
        List<ScrapTotalListVo> list = scrapApplyDetailsMapper.selectTotalScrapApplyDetailsList(scrapApplyDetails);
        if (CollectionUtils.isNotEmpty(list)) {
            for (ScrapTotalListVo applyDetails : list) {
//                BigDecimal totalCost = applyDetails.getScrapNum().multiply(applyDetails.getBuyPrice()).divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP);
                BigDecimal totalCost = applyDetails.getScrapNum().multiply(applyDetails.getBuyPrice()).setScale(2, RoundingMode.HALF_UP);
                applyDetails.setTotalCost(totalCost);
                List<String> asList = Arrays.asList(applyDetails.getIds().split(","));
                List<Long> longList = asList.stream()
                        .map(Long::parseLong)
                        .collect(Collectors.toList());
                List<String> taskList = Arrays.asList(applyDetails.getTaskIds().split(","));
                List<Long> longTaskList = taskList.stream()
                        .map(Long::parseLong)
                        .collect(Collectors.toList());
                applyDetails.setIdList(longList);
                applyDetails.setTaskIdList(longTaskList);
                if ("2".equals(applyDetails.getScrapSource())) {
                    applyDetails.setScrapStyle("维修报废");
                } else if ("3".equals(applyDetails.getScrapSource())) {
                    applyDetails.setScrapStyle("盘点报废");
                }
            }
        }
        return list;
    }

    /**
     * 报废台账审核通过
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public AjaxResult ledgerApprove(ScrapApplyDetails scrapApplyDetails) {
        if (scrapApplyDetails == null || CollectionUtils.isEmpty(scrapApplyDetails.getIdList())) {
            return AjaxResult.error("参数为空");
        }
        try {
            // 根据传参修改报废状态
            int result = 0;
            for (Long id : scrapApplyDetails.getIdList()) {
                scrapApplyDetails.setId(id);
                scrapApplyDetails.setLedgerStatus("1");
                scrapApplyDetails.setLedgerBy(SecurityUtils.getLoginUser().getUserid());
                scrapApplyDetails.setLedgerTime(DateUtils.getNowDate());
                result += scrapApplyDetailsMapper.ledgerApprove(scrapApplyDetails);
            }
            if (result > 0) {
                return AjaxResult.success("审核通过");
            }
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
        } catch (Exception e) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
        }
    }

    /**
     * 报废台账审核驳回
     * @param scrapApplyDetails
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult ledgerReject(ScrapApplyDetails scrapApplyDetails) {
        if (scrapApplyDetails == null || CollectionUtils.isEmpty(scrapApplyDetails.getIdList()) || CollectionUtils.isEmpty(scrapApplyDetails.getTaskIdList())) {
            return AjaxResult.error("参数为空");
        }
        int result = 0;
        try {
            // 将taskId进行去重
            List<Long> taskIdList = scrapApplyDetails.getTaskIdList().stream()
                    .distinct()
                    .collect(Collectors.toList());
            List<Long> idList = scrapApplyDetails.getIdList();
            for (Long taskId : taskIdList) {
                // 根据taskId查询协议id
                Long agreementId = taskAgreementMapper.selectAgreementIdByTaskId(taskId);
                scrapApplyDetails.setTaskId(taskId);
                List<ScrapApplyDetails> scrapApplyDetailsList = scrapApplyDetailsMapper.selectRepairQuestListByTaskId(scrapApplyDetails);
                scrapApplyDetails.setAgreementId(agreementId);
                // 维修报废标志
                boolean sourceWxFlag = false;
                if (CollectionUtils.isNotEmpty(scrapApplyDetailsList)) {
                    if (ScrapSourceEnum.REPAIR_SCRAP.getStatus().equals(scrapApplyDetailsList.get(0).getScrapSource())) {
                        sourceWxFlag = true;
                    }
                }
                //插入任务表
                Long newTaskId = null;
                if (sourceWxFlag) {
                    newTaskId = insertTt(taskId);
                    result += insertTta(newTaskId, scrapApplyDetails);
                } else {
                    newTaskId = insertScrapTtReject();
                }
                if (CollectionUtils.isNotEmpty(scrapApplyDetailsList)) {
                    for (ScrapApplyDetails applyDetails : scrapApplyDetailsList) {
                        if (idList.contains(applyDetails.getId())) {
                            applyDetails.setLedgerStatus(ScrapTaskStatusEnum.SCRAP_TASK_TO_REJECT.getStatus().toString());
                            applyDetails.setLedgerBy(SecurityUtils.getLoginUser().getUserid());
                            applyDetails.setLedgerTime(DateUtils.getNowDate());
                            applyDetails.setRejectReason(scrapApplyDetails.getRejectReason());
                            result = scrapApplyDetailsMapper.ledgerApprove(applyDetails);
                            // 维修报废
                            if (applyDetails.getMaId() != null && ScrapSourceEnum.REPAIR_SCRAP.getStatus().equals(applyDetails.getScrapSource())) {
                                applyDetails.setStatus(MaMachineStatusEnum.BACK_REPAIR.getStatus().toString());
                                result += scrapApplyDetailsMapper.updateMaStatus(applyDetails);
                                // 盘点报废
                            } else if (applyDetails.getMaId() != null && ScrapSourceEnum.INVENTORY_SCRAP.getStatus().equals(applyDetails.getScrapSource())){
                                applyDetails.setStatus(MaMachineStatusEnum.IN_STORE.getStatus().toString());
                                result += scrapApplyDetailsMapper.updateMaStatus(applyDetails);
                            }
                            // 维修报废
                            if (ScrapSourceEnum.REPAIR_SCRAP.getStatus().equals(applyDetails.getScrapSource())) {
                                Long backId = scrapApplyDetailsMapper.selectBackIdByTaskId(applyDetails.getParentId());
                                applyDetails.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                                applyDetails.setCreateTime(DateUtils.getNowDate());
                                applyDetails.setBackId(backId);
                                applyDetails.setNewTaskId(newTaskId);
                                result += insertWxTask(applyDetails);
                                // 盘点报废
                            } else if (ScrapSourceEnum.INVENTORY_SCRAP.getStatus().equals(applyDetails.getScrapSource())) {
                                applyDetails.setTaskId(newTaskId);
                                applyDetails.setStatus(ScrapTaskStatusEnum.SCRAP_TASK_TO_REJECT.getStatus().toString());
                                applyDetails.setLedgerStatus(ScrapTaskStatusEnum.SCRAP_TASK_NO_FINISHED.getStatus().toString());
                                applyDetails.setLedgerBy(null);
                                applyDetails.setLedgerTime(null);
                                applyDetails.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                                applyDetails.setCreateTime(DateUtils.getNowDate());
                                applyDetails.setRejectReason(null);
                                result += scrapApplyDetailsMapper.insertScrapApplyDetails(applyDetails);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("驳回失败", e);
            throw new RuntimeException("驳回失败");
        }
        if (result > 0) {
            return AjaxResult.success("驳回成功");
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 插入驳回报废任务
     * @return
     */
    private Long insertScrapTtReject() {
        Long newTask = null;
        int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_PART_SCRAP.getTaskTypeId());
        // 生成盘点报废单号
        String code = genderBfTaskCode(thisMonthMaxOrder);
        TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_PART_SCRAP.getTaskTypeId(), RepairInputStatusEnum.INPUT_TASK_TO_REJECT.getStatus(),
                null,thisMonthMaxOrder + 1, code);
        tmTask.setCreateTime(DateUtils.getNowDate());
        tmTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        // 插入任务
        int taskId = taskMapper.insertTmTask(tmTask);
        // 如果插入成功且返回的 taskId 大于 0
        if (taskId > 0 && tmTask.getTaskId() > 0) {
            newTask = tmTask.getTaskId();
        }
        return newTask;
    }

    /**
     * 查询报废台账审核总费用
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public ScrapTotalListVo getTotalPrice(ScrapApplyDetails scrapApplyDetails) {
        ScrapTotalListVo scrapTotalListVo = new ScrapTotalListVo();
        BigDecimal totalCost = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        List<ScrapTotalListVo> list = scrapApplyDetailsMapper.selectTotalScrapApplyDetailsList(scrapApplyDetails);
        if (CollectionUtils.isNotEmpty(list)) {
            for (ScrapTotalListVo item : list) {
//                totalCost = totalCost.add(item.getScrapNum().multiply(item.getBuyPrice()).divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP));
                totalCost = totalCost.add(item.getScrapNum().multiply(item.getBuyPrice()).setScale(2, RoundingMode.HALF_UP));
            }
            String result = list.stream()
                    .map(ScrapTotalListVo::getMonth) // 提取 month 属性
                    .distinct() // 去重
                    .sorted() // 按升序排序
                    .collect(Collectors.joining(",")); // 用逗号拼接
            scrapTotalListVo.setTotalCost(totalCost);
            scrapTotalListVo.setMonth(result);
        }
        return scrapTotalListVo;
    }

    /**
     * 查询盘点报废任务列表
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public List<ScrapTaskListVo> selectInventoryList(ScrapApplyDetails scrapApplyDetails) {
        try {
            List<ScrapTaskListVo> list = scrapApplyDetailsMapper.selectInventoryList(scrapApplyDetails);
            if (CollectionUtils.isNotEmpty(list)) {
                for (ScrapTaskListVo scrapTaskListVo : list) {
                    List<String> asList = Arrays.asList(scrapTaskListVo.getIds().split(","));
                    List<Long> longList = asList.stream()
                            .map(Long::parseLong)
                            .collect(Collectors.toList());
                    scrapTaskListVo.setIdList(longList);
                }
                String keyWord = scrapApplyDetails.getKeyWord();
                // 如果关键字不为空，进行过滤
                if (!StringUtils.isBlank(keyWord)) {
                    list = list.stream()
                            .filter(item -> containsScrapKeyword(item, keyWord))
                            .collect(Collectors.toList());
                }
            }
            return list;
        } catch (Exception e) {
            log.error("查询失败", e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 新增盘点报废
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public AjaxResult savePutInfo(ScrapApplyDetails scrapApplyDetails) {
        if (scrapApplyDetails == null || CollectionUtils.isEmpty(scrapApplyDetails.getScrapApplyDetailsList())) {
            return AjaxResult.error("报废详情数据为空！");
        }
        for (ScrapApplyDetails details : scrapApplyDetails.getScrapApplyDetailsList()) {
            if (details.getScrapNum().compareTo(details.getStorageNum()) > 0) {
                return AjaxResult.error("报废数量不能大于库存数量！");
            }
        }
        try {
            int result = 0;
            Long newTaskId = insertScrapTt();
            result = getScrapResult(scrapApplyDetails, result, newTaskId);
            result = getFileResult(scrapApplyDetails, result, newTaskId);
            if (result > 0) {
                return AjaxResult.success("新增成功");
            }
        } catch (Exception e) {
            log.error("新增失败", e);
            e.printStackTrace();
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 获取报废详情存储结果
     * @param scrapApplyDetails
     * @param result
     * @param newTaskId
     * @return
     */
    private int getScrapResult(ScrapApplyDetails scrapApplyDetails, int result, Long newTaskId) {
        List<ScrapApplyDetails> detailsList = scrapApplyDetails.getScrapApplyDetailsList();
        for (ScrapApplyDetails applyDetails : detailsList) {
            applyDetails.setTaskId(newTaskId);
            applyDetails.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            applyDetails.setCreateTime(DateUtils.getNowDate());
            applyDetails.setScrapSource("3");
            if (CollectionUtils.isNotEmpty(applyDetails.getMaCodeList())) {
                for (MaCodeInfo maCodeInfo : applyDetails.getMaCodeList()) {
                    applyDetails.setMaId(maCodeInfo.getMaId());
                    applyDetails.setScrapNum(BigDecimal.ONE);
                    applyDetails.setStatus(MaMachineStatusEnum.SCRAP_TO_AUDIT.getStatus().toString());
                    // 更改设备状态
                    result += scrapApplyDetailsMapper.updateMaStatus(applyDetails);
                    applyDetails.setStatus("0");
                    // 添加【报废详情表】
                    result += scrapApplyDetailsMapper.insertScrapApplyDetails(applyDetails);
                }
            } else {
                applyDetails.setStatus("0");
                // 添加【报废详情表】
                result += scrapApplyDetailsMapper.insertScrapApplyDetails(applyDetails);
            }
            // 更改设备库存
            if (CollectionUtils.isNotEmpty(applyDetails.getMaCodeList())) {
                applyDetails.setScrapNum(BigDecimal.valueOf(applyDetails.getMaCodeList().size()));
                applyDetails.setTypeId(applyDetails.getMaCodeList().get(0).getTypeId());
            }
            result += scrapApplyDetailsMapper.updateStorageNum(applyDetails);
        }
        return result;
    }

    /**
     * 获取文件存储结果
     * @param scrapApplyDetails
     * @param result
     * @param newTaskId
     * @return
     */
    private int getFileResult(ScrapApplyDetails scrapApplyDetails, int result, Long newTaskId) {
        if (CollectionUtils.isNotEmpty(scrapApplyDetails.getFileList())) {
            for (BmFileInfo fileInfo : scrapApplyDetails.getFileList()) {
                fileInfo.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                fileInfo.setCreateTime(DateUtils.getNowDate());
                fileInfo.setFileType(6L);
                fileInfo.setTaskType(TmTaskTypeEnum.TM_TASK_PART_SCRAP.getTaskTypeId());
                fileInfo.setTaskId(newTaskId);
                result += fileInfoMapper.insertBmFileInfo(fileInfo);
            }
        }
        return result;
    }

    /**
     * 插入任务表
     * @return
     */
    private Long insertScrapTt() {
        Long newTask = null;
        int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_PART_SCRAP.getTaskTypeId());
        // 生成盘点报废单号
        String code = genderBfTaskCode(thisMonthMaxOrder);
        TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_PART_SCRAP.getTaskTypeId(), RepairInputStatusEnum.INPUT_TASK_NO_FINISHED.getStatus(),
                null,thisMonthMaxOrder + 1, code);
        tmTask.setCreateTime(DateUtils.getNowDate());
        tmTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        // 插入任务
        int taskId = taskMapper.insertTmTask(tmTask);
        // 如果插入成功且返回的 taskId 大于 0
        if (taskId > 0 && tmTask.getTaskId() > 0) {
            newTask = tmTask.getTaskId();
        }
        return newTask;
    }

    /**
     * 查询盘点报废任务详情
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public ScrapApplyDetails getDetailsList(ScrapApplyDetails scrapApplyDetails) {
        try {
            ScrapApplyDetails details = new ScrapApplyDetails();
            List<ScrapApplyDetails> list = scrapApplyDetailsMapper.getDetailsList(scrapApplyDetails);
            if (CollectionUtils.isNotEmpty(list)) {
                for (ScrapApplyDetails applyDetails : list) {
                    List<Type> maTypes = scrapApplyDetailsMapper.selectMaTypeList(applyDetails.getTypeId());
                    if (CollectionUtils.isNotEmpty(maTypes)) {
                        applyDetails.setStorageNum(maTypes.get(0).getStorageNum().add(applyDetails.getScrapNum()));
                    }
                    List<MaCodeInfo> maCodeList = new ArrayList<>();
                    if (StringUtils.isNotBlank(applyDetails.getMaIds())) {
                        for (String maId : applyDetails.getMaIds().split(",")) {
                            MachineVo machineVo = machineMapper.selectMachineByMaId(Long.parseLong(maId));
                            MaCodeInfo maCodeInfo = new MaCodeInfo();
                            maCodeInfo.setMaId(Long.valueOf(maId));
                            maCodeInfo.setMaCode(machineVo.getMaCode());
                            maCodeList.add(maCodeInfo);
                        }
                        applyDetails.setMaCodeList(maCodeList);
                    }
                }
                // 查询文件信息
                BmFileInfo fileInfo = new BmFileInfo();
                fileInfo.setTaskType(TmTaskTypeEnum.TM_TASK_PART_SCRAP.getTaskTypeId());
                fileInfo.setFileType(6L);
                fileInfo.setTaskId(scrapApplyDetails.getTaskId());
                List<BmFileInfo> bmFileInfos = fileInfoMapper.selectBmFileInfoList(fileInfo);
                if (CollectionUtils.isNotEmpty(bmFileInfos)) {
                    details.setFileList(bmFileInfos);
                }
                details.setScrapApplyDetailsList(list);
            }
            return details;
        } catch (Exception e) {
            log.error("查询失败", e);
            throw new RuntimeException("查询失败");
        }
    }

    /**
     * 删除盘点报废
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public AjaxResult delete(ScrapApplyDetails scrapApplyDetails) {
        try {
            int result = 0;
            // 先根据taskId进行查询
            List<ScrapApplyDetails> list = scrapApplyDetailsMapper.getDetailsList(scrapApplyDetails);
            // 恢复设备库存及设备状态
            for (ScrapApplyDetails details : list) {
                result = scrapApplyDetailsMapper.updateStorageNumAdd(details);
                if (result == 0) {
                    return AjaxResult.error("库存回滚失败");
                }
                if (StringUtils.isNotBlank(details.getMaIds())) {
                    String[] maIds = details.getMaIds().split(",");
                    // 转换为long类型
                    for (String maId : maIds) {
                        Long maIdLong = Long.parseLong(maId);
                        // 更新设备状态
                        ScrapApplyDetails applyDetails = new ScrapApplyDetails();
                        applyDetails.setMaId(maIdLong);
                        applyDetails.setStatus(MaMachineStatusEnum.IN_STORE.getStatus().toString());
                        scrapApplyDetailsMapper.updateMaStatus(applyDetails);
                    }
                }
            }
            result = scrapApplyDetailsMapper.delete(scrapApplyDetails);
            if (result == 0) {
                return AjaxResult.error("删除主任务失败");
            }
            // 删除任务表
            result = taskMapper.deleteTmTaskByTaskId(scrapApplyDetails.getTaskId());
            if (result == 0) {
                return AjaxResult.error("删除任务信息失败");
            }
            // 删除文件信息
            BmFileInfo fileInfo = new BmFileInfo();
            fileInfo.setTaskType(TmTaskTypeEnum.TM_TASK_PART_SCRAP.getTaskTypeId());
            fileInfo.setFileType(6L);
            fileInfo.setTaskId(scrapApplyDetails.getTaskId());
            result += fileInfoMapper.deleteBmFileInfoByBizInfo(fileInfo);
            if (result > 0) {
                return AjaxResult.success("删除成功");
            }
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
        } catch (Exception e) {
            log.error("删除失败", e);
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
        }
    }

    /**
     * 修改盘点报废
     * @param scrapApplyDetails
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateList(ScrapApplyDetails scrapApplyDetails) {
        if (scrapApplyDetails == null || CollectionUtils.isEmpty(scrapApplyDetails.getScrapApplyDetailsList())) {
            return AjaxResult.error("报废详情数据为空！");
        }
        for (ScrapApplyDetails details : scrapApplyDetails.getScrapApplyDetailsList()) {
            if (details.getScrapNum().compareTo(details.getStorageNum()) > 0) {
                return AjaxResult.error("报废数量不能大于库存数量！");
            }
        }
        try {
            int result = 0;
            // 先根据taskId进行查询
            List<ScrapApplyDetails> list = scrapApplyDetailsMapper.getDetailsList(scrapApplyDetails);
            // 先根据taskId进行删除，然后再走新增
            result += scrapApplyDetailsMapper.delete(scrapApplyDetails);
            // 恢复设备库存及设备状态
            for (ScrapApplyDetails details : list) {
                result += scrapApplyDetailsMapper.updateStorageNumAdd(details);
                if (StringUtils.isNotBlank(details.getMaIds())) {
                    String[] maIds = details.getMaIds().split(",");
                    // 转换为long类型
                    for (String maId : maIds) {
                        Long maIdLong = Long.parseLong(maId);
                        // 更新设备状态
                        ScrapApplyDetails applyDetails = new ScrapApplyDetails();
                        applyDetails.setMaId(maIdLong);
                        applyDetails.setStatus(MaMachineStatusEnum.IN_STORE.getStatus().toString());
                        scrapApplyDetailsMapper.updateMaStatus(applyDetails);
                    }
                }
            }
            // 删除文件信息
            if (result > 0) {
                BmFileInfo fileInfo = new BmFileInfo();
                fileInfo.setTaskType(TmTaskTypeEnum.TM_TASK_PART_SCRAP.getTaskTypeId());
                fileInfo.setFileType(6L);
                fileInfo.setTaskId(scrapApplyDetails.getTaskId());
                fileInfoMapper.deleteBmFileInfoByBizInfo(fileInfo);
            }
            // 根据编辑提交的数据去和编辑前数据作对比，修改maId的状态
            extracted(scrapApplyDetails);
            TmTask tmTask = new TmTask();
            tmTask.setTaskId(scrapApplyDetails.getTaskId());
            tmTask.setTaskStatus(ScrapTaskStatusEnum.SCRAP_TASK_NO_FINISHED.getStatus());
            result = taskMapper.updateTmTask(tmTask);
            result = getScrapResult(scrapApplyDetails, result, scrapApplyDetails.getTaskId());
            result = getFileResult(scrapApplyDetails, result, scrapApplyDetails.getTaskId());
            if (result > 0) {
                return AjaxResult.success("修改成功");
            }
        } catch (Exception e) {
            log.error("修改失败", e);
            e.printStackTrace();
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 根据编辑提交的数据去和编辑前数据作对比，修改maId的状态
     * @param scrapApplyDetails
     */
    private void extracted(ScrapApplyDetails scrapApplyDetails) {
        List<ScrapApplyDetails> detailsList = scrapApplyDetails.getScrapApplyDetailsList();
        for (ScrapApplyDetails details : detailsList) {
            if (CollectionUtils.isNotEmpty(details.getMaCodeList())) {
                List<Long> maIdList = details.getMaCodeList().stream()
                        .map(MaCodeInfo::getMaId)
                        .collect(Collectors.toList());
                scrapApplyDetails.setTypeId(details.getTypeId());
                List<ScrapApplyDetails> list1 = scrapApplyDetailsMapper.getDetailsList(scrapApplyDetails);
                if (CollectionUtils.isNotEmpty(list1)) {
                    for (ScrapApplyDetails applyDetails : list1) {
                        if (StringUtils.isNotBlank(applyDetails.getMaIds())) {
                            String[] maIds = applyDetails.getMaIds().split(",");
                            for (String maId : maIds) {
                                if (!maIdList.contains(Long.parseLong(maId))) {
                                    // 更新设备状态
                                    ScrapApplyDetails info =  new ScrapApplyDetails();
                                    info.setMaId(Long.parseLong(maId));
                                    info.setStatus(MaMachineStatusEnum.IN_STORE.getStatus().toString());
                                    scrapApplyDetailsMapper.updateMaStatus(info);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 盘点报废审核
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public AjaxResult inventoryApprove(ScrapApplyDetails scrapApplyDetails) {
        if (CollectionUtil.isEmpty(scrapApplyDetails.getTaskIdList())) {
            return AjaxResult.error("请选择要审核的报废单");
        }
        int result = 0;
        try {
            // 根据前端传的status来判断审核通过还是驳回（1 通过 ，2 驳回）
            for (Long taskId : scrapApplyDetails.getTaskIdList()) {
                scrapApplyDetails.setTaskId(taskId);
                scrapApplyDetails.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                scrapApplyDetails.setAuditTime(DateUtils.getNowDate());
                result += scrapApplyDetailsMapper.updateTaskStatus(scrapApplyDetails);
                // 修改任务状态
                TmTask tmTask = new TmTask();
                tmTask.setTaskId(taskId);
                tmTask.setTaskStatus(Integer.valueOf(scrapApplyDetails.getStatus()));
                result += taskMapper.updateTmTask(tmTask);
            }
            if (result > 0) {
                return AjaxResult.success("审核成功");
            }
        } catch (Exception e) {
            log.error("审核失败", e);
            e.printStackTrace();
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 查询报废台账列表
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public List<ScrapTotalListVo> getScrapList(ScrapApplyDetails scrapApplyDetails) {
        List<ScrapTotalListVo> scrapTotalListVos = new ArrayList<>();
        List<ScrapTotalListVo> list = scrapApplyDetailsMapper.getScrapList(scrapApplyDetails);  // 获取数据
        // 如果列表不为空，则进行处理
        if (CollectionUtils.isNotEmpty(list)) {

            // 如果用户传入了具体月份，先进行过滤
            if (StringUtils.isNotBlank(scrapApplyDetails.getMonth())) {
                list = list.stream()
                        .filter(totalListVo -> totalListVo.getMonth().equals(scrapApplyDetails.getMonth()))
                        .collect(Collectors.toList());
            }
            // 按月分组
            Map<String, List<ScrapTotalListVo>> groupedByMonth = list.stream()
                    .collect(Collectors.groupingBy(ScrapTotalListVo::getMonth));

            // 遍历按月分组的结果
            groupedByMonth.forEach((month, monthList) -> {
                ScrapTotalListVo scrapTotalListVo = new ScrapTotalListVo();
                scrapTotalListVo.setMonth(month);  // 设置当前月份

                // 重新初始化 totalCost，避免多个月份累加
                BigDecimal monthTotalCost = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
                BigDecimal numTotalCost =  BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);

                // 累加每个月的 totalCost
                for (ScrapTotalListVo totalListVo : monthList) {
                    monthTotalCost = monthTotalCost.add(
                            totalListVo.getScrapNum()
                                    .multiply(totalListVo.getBuyPrice())
                                    .divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP)
                    );
                    numTotalCost = numTotalCost.add(totalListVo.getScrapNum());
                }
                scrapTotalListVo.setTotalCost(monthTotalCost);  // 设置总成本
                scrapTotalListVo.setScrapNum(numTotalCost);
                scrapTotalListVos.add(scrapTotalListVo);  // 添加到结果列表
            });
        }
        return scrapTotalListVos;  // 返回结果
    }

    /**
     * 查询报废台账明细列表
     * @param scrapApplyDetails
     * @return
     */
    @Override
    public List<ScrapDetailsListVo> getScrapDetailsList(ScrapApplyDetails scrapApplyDetails) {
        List<ScrapDetailsListVo> list = scrapApplyDetailsMapper.getScrapDetailsList(scrapApplyDetails);
        if (CollectionUtils.isNotEmpty(list)) {
            for (ScrapDetailsListVo applyDetails : list) {
                BigDecimal totalCost = applyDetails.getScrapNum().multiply(applyDetails.getBuyPrice()).divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP);
                applyDetails.setTotalCost(totalCost);
                if ("2".equals(applyDetails.getScrapSource())) {
                    applyDetails.setScrapStyle("维修报废");
                } else if ("3".equals(applyDetails.getScrapSource())) {
                    applyDetails.setScrapStyle("盘点报废");
                }
                if ("0".equals(applyDetails.getScrapType())) {
                    applyDetails.setScrapType("自然损坏");
                } else if ("1".equals(applyDetails.getScrapType())) {
                    applyDetails.setScrapType("人为损坏");
                }
            }
        }
        return list;
    }

    /**
     * 生成报废单号
     * @param thisMonthMaxOrder
     * @return
     */
    private String genderBfTaskCode(int thisMonthMaxOrder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String result = format.replace("-", "");
        return MaterialConstants.PD_SCRAP_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1);
    }

    /**
     * 判断关键字是否包含
     * @param item
     * @param keyWord
     * @return
     */
    private boolean containsScrapKeyword(ScrapTaskListVo item, String keyWord) {
        return (item.getType() != null && item.getType().contains(keyWord)) ||
                (item.getScrapCode() != null && item.getScrapCode().contains(keyWord)) ||
                (item.getCreateName() != null && item.getCreateName().contains(keyWord));
    }

    /**
     * 新增维修单
     * @param applyDetails
     * @return
     */
    private int insertWxTask(ScrapApplyDetails applyDetails) {
        return scrapApplyDetailsMapper.insertRad(applyDetails);
    }

    /**
     * 驳回后重新生成维修单 插入任务表
     * @return
     */
    private Long insertTt(Long preTaskId) {
        Long newTask = null;
        int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_REPAIR.getTaskTypeId());
        // 生成维修单号
        String code = genderWxTaskCode(thisMonthMaxOrder);
        TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_REPAIR.getTaskTypeId(), RepairTaskStatusEnum.TASK_STATUS_PROCESSING.getStatus(),
                null,thisMonthMaxOrder + 1, code);
        tmTask.setCreateTime(DateUtils.getNowDate());
        tmTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        tmTask.setPreTaskId(preTaskId);
        // 插入任务
        int taskId = taskMapper.insertTmTask(tmTask);
        // 如果插入成功且返回的 taskId 大于 0
        if (taskId > 0 && tmTask.getTaskId() > 0) {
            newTask = tmTask.getTaskId();
        }
        return newTask;
    }

    /**
     * 生成维修单号
     * @param thisMonthMaxOrder
     * @return
     */
    private String genderWxTaskCode(int thisMonthMaxOrder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String result = format.replace("-", "");
        return MaterialConstants.REPAIR_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1);
    }

    /**
     * 插入协议任务表
     * @param newTaskId
     * @param scrapApplyDetails
     * @return
     */
    private int insertTta(Long newTaskId, ScrapApplyDetails scrapApplyDetails) {
        int res;
        Long agreementId = null;
        if (CollectionUtils.isNotEmpty(scrapApplyDetails.getScrapApplyDetailsList())) {
            agreementId = scrapApplyDetails.getScrapApplyDetailsList().get(0).getAgreementId();
        } else {
            agreementId = scrapApplyDetails.getAgreementId();
        }
        TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(newTaskId, agreementId);
        tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
        tmTaskAgreement.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        res = taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
        return res;
    }
}
