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

import cn.hutool.core.collection.CollectionUtil;
import com.bonus.common.biz.constant.MaterialConstants;
import com.bonus.common.biz.domain.vo.KeyValueVO;
import com.bonus.common.biz.enums.RepairTaskStatusEnum;
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.security.utils.SecurityUtils;
import com.bonus.material.repair.domain.*;
import com.bonus.material.repair.domain.vo.RepairAuditDetailsVO;
import com.bonus.material.repair.domain.vo.ScrapApplyDetailsVO;
import com.bonus.material.repair.domain.vo.ScrapAudit;
import com.bonus.material.repair.mapper.RepairAuditDetailsMapper;
import com.bonus.material.repair.mapper.RepairInputDetailsMapper;
import com.bonus.material.repair.service.IRepairAuditDetailsService;
import com.bonus.material.scrap.domain.ScrapApplyDetails;
import com.bonus.material.scrap.mapper.ScrapApplyDetailsMapper;
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 org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 修试审核详细Service业务层处理
 * 
 * @author syruan
 * @date 2024-10-16
 */
@Service
@Slf4j
public class RepairAuditDetailsServiceImpl implements IRepairAuditDetailsService {

    @Resource
    private RepairAuditDetailsMapper repairAuditDetailsMapper;

    @Resource
    private TmTaskMapper taskMapper;

    @Resource
    private TmTaskAgreementMapper agreementMapper;

    @Resource
    private ScrapApplyDetailsMapper scrapApplyDetailsMapper;

    @Resource
    private RepairInputDetailsMapper repairInputDetailsMapper;

    @Override
    public List<RepairPart> getPartRecord(RepairAuditDetails repairAuditDetails) {
        RepairAuditDetails bean = repairAuditDetailsMapper.getRepairId(repairAuditDetails);
        return repairAuditDetailsMapper.getPartRecord(bean);
    }

    @Override
    public List<RepairRecord> getRepairRecord(RepairAuditDetails repairAuditDetails) {
        RepairAuditDetails bean = repairAuditDetailsMapper.getRepairId(repairAuditDetails);
        return repairAuditDetailsMapper.getRepairRecord(bean);
    }

    /**
     * @param repairAuditDetails 查询参数
     */
    @Override
    public List<RepairAuditDetails> getRepairAuditList(RepairAuditDetails repairAuditDetails) {
        return repairAuditDetailsMapper.selectRepairAuditDetailsList(repairAuditDetails);
    }

    @Override
    public void queryTimeCope(@NotNull RepairAuditDetails repairAuditDetails) {
        Map<String, Object> params = repairAuditDetails.getParams();
        if (params != null && !params.isEmpty()) {
            formatTimeParam(params, "beginTime", " 00:00:00");
            formatTimeParam(params, "endTime", " 23:59:59");
            repairAuditDetails.setParams(params);
        }
    }

    @Override
    public List<RepairAuditDetailsVO> exportRepairQuestList(RepairAuditDetails bean) {
        return repairAuditDetailsMapper.exportRepairQuestList(bean);
    }

    /**
     * 查询试验审核列表
     *
     * @param repairAuditDetails 查询参数
     */
    @Override
    public List<ScrapApplyDetailsVO> selectRepairQuestList(RepairAuditDetails repairAuditDetails) {
        try {
            // 获取所有需要查询的 taskId、过滤空的
            List<ScrapApplyDetailsVO> repairQuestList = repairAuditDetailsMapper.selectRepairQuestList(repairAuditDetails);
            // 通过流过滤掉空对象 并转换为 List集合
            List<Long> taskIds = repairQuestList.stream()
                    .filter(Objects::nonNull)
                    .map(ScrapApplyDetailsVO::getTaskId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            // 批量查询 typeName
            List<KeyValueVO> keyValueList = repairAuditDetailsMapper.selectTypeNamesByTaskIds(taskIds);
            // 设置 itemType
            if (CollectionUtil.isNotEmpty(keyValueList)) {
                Map<String, String> keyValueMap = keyValueList.stream().collect(Collectors.toMap(KeyValueVO::getMapKey, KeyValueVO::getMapValue));
                for (ScrapApplyDetailsVO scrapApplyDetailsVO : repairQuestList) {
                    Long taskId = scrapApplyDetailsVO.getTaskId();
                    if (taskId != null) {
                        String typeName = keyValueMap.get(String.valueOf(taskId));
                        if (typeName != null) {
                            scrapApplyDetailsVO.setItemType(typeName);
                        }
                    }
                }
            }
            return repairQuestList;
        } catch (Exception e) {
            // 异常处理
            System.err.println("Error occurred while selecting repair quest list: " + e.getMessage());
            throw new ServiceException("Failed to get repair quest list" + e.getMessage());
        }
    }

    /**
     * 修饰审核任务审核
     *
     * @param scrapAudit 审核信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int auditRepair(@NotNull ScrapAudit scrapAudit) throws Exception {
        String checkResult = scrapAudit.getCheckResult();
        List<RepairAuditDetails> auditDetailList = scrapAudit.getAuditDetailList();
        List<Long> taskIdList = scrapAudit.getTaskIdList();
        Integer b = 0;
        char status;
        for (Long taskId : taskIdList) {
            TmTask tmTask = taskMapper.selectTmTaskByTaskId(taskId);
            if (Objects.equals(tmTask.getTaskStatus(), RepairTaskStatusEnum.TASK_STATUS_REVIEW.getStatus())) {
                throw new Exception("任务已审核已通过");
            }

            List<RepairAuditDetails> auditAllList = repairAuditDetailsMapper.selectRepairAuditDetailsByTaskId(taskId);
            List<RepairAuditDetails> notAuditList = repairAuditDetailsMapper.selectNotAuditByTaskId(taskId);
            // 查询协议表
            TmTaskAgreement tmTaskAgreement = agreementMapper.selectTmTaskAgreementByTaskId(taskId);
            String taskCode;
            int taskStatus;
            int taskType;
            int companyId = 0;
            if ("通过".equals(checkResult)) {
                status = 1;
                List<RepairAuditDetails> repairInputList = new ArrayList<>();
                List<RepairAuditDetails> scrapNumList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(auditDetailList)) {
                    for (RepairAuditDetails bean : auditDetailList) {
                        if (bean.getRepairedNum().compareTo(b) > 0) {
                            repairInputList.add(bean);
                        }
                        if (bean.getScrapNum().compareTo(b) > 0) {
                            scrapNumList.add(bean);
                        }
                    }
                } else {
                    repairInputList = repairAuditDetailsMapper.selectRepairInputByTaskId(taskId);
                    //获取维修报废列表
                    scrapNumList = repairAuditDetailsMapper.selectScrapNumByTaskId(taskId);
                }

                if (CollectionUtil.isNotEmpty(repairInputList)) {
                    if (repairInputList.get(0).getCompanyId() != null) {
                        companyId = repairInputList.get(0).getCompanyId();
                    }

                    taskCode = purchaseCodeRule("R", 50);
                    taskStatus = 53;
                    taskType = 50;
                    long inputTaskId = genTask(taskCode, taskType, taskStatus, tmTaskAgreement, companyId);
                    for (RepairAuditDetails inputDetails : repairInputList) {
                        Long typeId = inputDetails.getTypeId();
                        Long maId = inputDetails.getMaId();
                        Integer repairNum = inputDetails.getRepairedNum();
                        // 创建修饰后入库任务
                        if (repairNum.compareTo(b) > 0) {
                            // 添加修试后入库任务
                            RepairInputDetails repairInputDetails = new RepairInputDetails();
                            repairInputDetails.setTaskId(inputTaskId);
                            repairInputDetails.setAuditId(inputDetails.getId());
                            repairInputDetails.setRepairId(inputDetails.getRepairId());
                            repairInputDetails.setRepairNum(inputDetails.getRepairedNum());
                            repairInputDetails.setTypeId(inputDetails.getTypeId());
                            repairInputDetails.setMaId(inputDetails.getMaId());
                            repairInputDetails.setStatus("0");
                            repairInputDetails.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                            repairInputDetails.setCreateTime(new Date());
                            repairInputDetails.setCompanyId((long) companyId);
                            repairInputDetailsMapper.insertRepairInputDetails(repairInputDetails);
                        }
                        repairAuditDetailsMapper.updateRepairCost(inputDetails,status);
                        // 根据repairId找到taskId和 typeId 、maid
                        List<String> repairApplyRecordId = repairAuditDetailsMapper.getRepairApplyRecordId(inputDetails.getRepairId());
                        // 再去repair_apply_record 中查，并给一个标识表示审核完成
                        for (String id : repairApplyRecordId) {
                            repairAuditDetailsMapper.updateRecodeStatus(id);
                        }
                    }
                }
                if (CollectionUtil.isNotEmpty(scrapNumList)) {
                    if (scrapNumList.get(0).getCompanyId() != null) {
                        companyId = scrapNumList.get(0).getCompanyId();
                    }
                    taskCode = purchaseCodeRule("BF", TmTaskTypeEnum.TM_TASK_SCRAP.getTaskTypeId());
                    //创建报废任务
                    long scrapTaskId = genTask(taskCode, TmTaskTypeEnum.TM_TASK_SCRAP.getTaskTypeId(), RepairTaskStatusEnum.SCRAP_UNDER_REVIEW.getStatus(), tmTaskAgreement, companyId);
                    for (RepairAuditDetails scrapDetails : scrapNumList) {
                        RepairAuditDetails byRepairId = scrapApplyDetailsMapper.getByRepairId(String.valueOf(scrapDetails.getRepairId()));
                        List<RepairRecord> repairRecord = scrapApplyDetailsMapper.getGyoupRepairRecord(byRepairId);
                        Long typeId = scrapDetails.getTypeId();
                        Long maId = scrapDetails.getMaId();
                        // 创建报废任务
                        Integer scrapNum = scrapDetails.getScrapNum();
                        if (scrapNum.compareTo(b) > 0) {
                            for (RepairRecord bean : repairRecord){
                                ScrapApplyDetails scrapApplyDetails = new ScrapApplyDetails();
                                scrapApplyDetails.setTaskId(scrapTaskId);
                                scrapApplyDetails.setTypeId(typeId);
                                scrapApplyDetails.setMaId(maId);
                                scrapApplyDetails.setScrapNum(bean.getScrapNum());
                                scrapApplyDetails.setScrapType(bean.getScrapType());
                                scrapApplyDetails.setScrapSource("2");
                                scrapApplyDetails.setStatus("0");
                                scrapApplyDetails.setParentId(scrapDetails.getId());
                                scrapApplyDetails.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                                scrapApplyDetails.setCreateTime(new Date());
                                scrapApplyDetails.setCompanyId((long) companyId);
                                scrapApplyDetailsMapper.insertScrapApplyDetails(scrapApplyDetails);
                            }
                        }
                    }

                }
                // 修饰审核通过时改修任务为已通过审核
                if (auditDetailList != null) {
                    if (auditDetailList.size() == notAuditList.size()) {
                        tmTask.setTaskStatus(47);
                    }
                } else if (auditAllList != null) {
                    if (auditAllList.size() == notAuditList.size()) {
                        tmTask.setTaskStatus(47);
                    }
                }
                tmTask.setUpdateTime(new Date());
                tmTask.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                taskMapper.updateTmTask(tmTask);
            } else {
                status = 2;
                List<RepairAuditDetails> repairDetailList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(auditDetailList)) {
                    repairDetailList.addAll(auditDetailList);
                } else {
                    repairDetailList.addAll(auditAllList);
                }
                if (CollectionUtil.isNotEmpty(repairDetailList)) {
                    if (repairDetailList.get(0).getCompanyId() != null) {
                        companyId = repairDetailList.get(0).getCompanyId();
                    }
                    taskCode = purchaseCodeRule(MaterialConstants.REPAIR_TASK_TYPE_LABEL, 41);
                    taskStatus = 43;
                    taskType = 41;
                    long inputTaskId = genTask(taskCode, taskType, taskStatus, tmTaskAgreement, companyId);
                    for (RepairAuditDetails inputDetails : repairDetailList) {
                        Long backId = repairAuditDetailsMapper.getBackId(inputDetails.getRepairId());
                        /* 添加驳回后维修详细表数据*/
                        RepairTaskDetails repairTaskDetails = new RepairTaskDetails();
                        repairTaskDetails.setTaskId(String.valueOf(inputTaskId));
                        repairTaskDetails.setMaId(String.valueOf(inputDetails.getMaId()));
                        repairTaskDetails.setTypeId(String.valueOf(inputDetails.getTypeId()));
                        Integer repairNum = inputDetails.getRepairNum();
                        repairTaskDetails.setRepairNum(repairNum);
                        repairTaskDetails.setStatus("0");
                        repairTaskDetails.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                        repairTaskDetails.setCompanyId((long) companyId);
                        repairTaskDetails.setBackId(backId);
                        repairAuditDetailsMapper.insertRepairDetails(repairTaskDetails);
                        repairAuditDetailsMapper.updateRepairCost(inputDetails,status);
                    }
                }
                // 修饰审核任务不通过时
                TmTask tmTaskNotExam = new TmTask();
                tmTaskNotExam.setTaskId(taskId);
                tmTaskNotExam.setRemark(scrapAudit.getRemark());
                if (repairDetailList.size() == notAuditList.size()) {
                    tmTaskNotExam.setTaskStatus(RepairTaskStatusEnum.TASK_STATUS_NO_REVIEW.getStatus());
                }
                tmTaskNotExam.setUpdateTime(new Date());
                tmTaskNotExam.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                taskMapper.updateTmTask(tmTaskNotExam);
            }
            if (CollectionUtil.isNotEmpty(scrapAudit.getAuditDetailList())) {
                if (CollectionUtil.isNotEmpty(auditDetailList)) {
                    for (RepairAuditDetails bean : auditDetailList) {
                        bean.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                        bean.setStatus(String.valueOf(status));
                        bean.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                        bean.setAuditRemark(scrapAudit.getRemark());
                        repairAuditDetailsMapper.updateStatus(bean);
                    }
                }
            } else {
                if (auditAllList != null) {
                    for (RepairAuditDetails bean : auditAllList) {
                        bean.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                        bean.setStatus(String.valueOf(status));
                        bean.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                        bean.setAuditRemark(scrapAudit.getRemark());
                        repairAuditDetailsMapper.updateStatus(bean);
                    }
                }
            }
        }
        return 1;
    }

    /**采购单号编码生成规则*/
    private @NotNull String purchaseCodeRule(String code, Integer taskType) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String taskNum = taskMapper.selectTaskNumByMonths(nowDate, taskType);
        if (StringUtils.isNotEmpty(taskNum)){
            // 将字符串转换为整数并加一
            int num = Integer.parseInt(taskNum) + 1;
            // 将结果转换回字符串格式，并确保结果是四位数，不足四位则在前面补0
            taskNum = String.format("%04d", num);
        }else {
            taskNum = "0001";
        }
        String codeNum = code + format + "-" + taskNum;
        return codeNum;
    }

    /**
     * 生成任务并返回任务id
     */
    private long genTask(String taskCode, int taskType, int taskStatus, @NotNull TmTaskAgreement tmTaskAgreement, int companyId) {
        TmTask task = new TmTask();
        task.setCode(taskCode);
        task.setTaskStatus(taskStatus);
        task.setTaskType(taskType);
        task.setCompanyId((long) companyId);
        task.setCreateTime(new Date());
        task.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
        taskMapper.insertTmTask(task);
        // 添加协议信息表
        TmTaskAgreement taskAgreement = new TmTaskAgreement();
        long taskId = task.getTaskId();
        taskAgreement.setTaskId(taskId);
        if (tmTaskAgreement.getAgreementId() == null) {
            throw new ServiceException("缺少协议数据");
        } else {
            taskAgreement.setAgreementId(tmTaskAgreement.getAgreementId());
        }
        taskAgreement.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
        agreementMapper.insertTmTaskAgreement(taskAgreement);
        return taskId;
    }


    /**
     * 查询修试审核详细
     * 
     * @param id 修试审核详细主键
     * @return 修试审核详细
     */
    @Override
    public RepairAuditDetails selectRepairAuditDetailsById(Long id) {
        return repairAuditDetailsMapper.selectRepairAuditDetailsById(id);
    }

    /**
     * 公共方法来处理时间格式化
     */
    @Override
    public void formatTimeParam(@NotNull Map<String, Object> params, String key, String suffix) {
        String time = (String) params.get(key);
        if (time != null && !time.isEmpty()) {
            params.put(key, time.trim() + suffix);
        } else {
            params.remove(key);
        }
    }

    /**
     * 查询修试审核详细列表
     * 
     * @param repairAuditDetails 修试审核详细
     * @return 修试审核详细
     */
    @Override
    public List<RepairAuditDetails> selectRepairAuditDetailsList(RepairAuditDetails repairAuditDetails) {
        return repairAuditDetailsMapper.selectRepairAuditDetailsList(repairAuditDetails);
    }

    /**
     * 新增修试审核详细
     * 
     * @param repairAuditDetails 修试审核详细
     * @return 结果
     */
    @Override
    public int insertRepairAuditDetails(@NotNull RepairAuditDetails repairAuditDetails) {
        repairAuditDetails.setCreateTime(DateUtils.getNowDate());
        try {
            return repairAuditDetailsMapper.insertRepairAuditDetails(repairAuditDetails);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 修改修试审核详细
     * 
     * @param repairAuditDetails 修试审核详细
     * @return 结果
     */
    @Override
    public int updateRepairAuditDetails(@NotNull RepairAuditDetails repairAuditDetails) {
        repairAuditDetails.setUpdateTime(DateUtils.getNowDate());
        try {
            return repairAuditDetailsMapper.updateRepairAuditDetails(repairAuditDetails);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 批量修改修试审核详细
     *
     * @param repairAuditDetails 修试审核详细
     * @return 结果
     */
    @Override
    public int updateRepairAuditDetailsBatch(@NotNull List<RepairAuditDetails> repairAuditDetails) {
        // 提取所有需要更新的 ID
        List<Long> ids = repairAuditDetails.stream()
                .filter(Objects::nonNull)
                .map(RepairAuditDetails::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (ids.isEmpty()) {
            return 0;
        }

        try {
            // 调用 Mapper 方法进行批量更新
            return repairAuditDetailsMapper.updateRepairAuditDetailsBatch(ids, String.valueOf(repairAuditDetails.get(0).getStatus()));
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 批量删除修试审核详细
     * 
     * @param ids 需要删除的修试审核详细主键
     * @return 结果
     */
    @Override
    public int deleteRepairAuditDetailsByIds(Long[] ids) {
        return repairAuditDetailsMapper.deleteRepairAuditDetailsByIds(ids);
    }

    /**
     * 删除修试审核详细信息
     * 
     * @param id 修试审核详细主键
     * @return 结果
     */
    @Override
    public int deleteRepairAuditDetailsById(Long id) {
        return repairAuditDetailsMapper.deleteRepairAuditDetailsById(id);
    }
}
