package com.ximai.mes.qc.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ximai.common.constant.UserConstants;
import com.ximai.common.core.domain.entity.MdItemType;
import com.ximai.common.core.domain.entity.SysUser;
import com.ximai.common.core.domain.model.LoginUser;
import com.ximai.common.utils.MessageUtils;
import com.ximai.common.utils.SecurityUtils;
import com.ximai.common.utils.data.ExceptionUtil;
import com.ximai.common.utils.data.StringUtils;
import com.ximai.mes.constant.QcConst;
import com.ximai.mes.md.domain.MdItem;
import com.ximai.mes.md.service.IMdItemService;
import com.ximai.mes.pro.domain.ProFeedback;
import com.ximai.mes.pro.domain.proWorkOrder.ProWorkorder;
import com.ximai.mes.pro.domain.task.ProTask;
import com.ximai.mes.pro.domain.vo.ProWorkorderQuery;
import com.ximai.mes.pro.service.IProFeedbackService;
import com.ximai.mes.pro.service.proWorkOrder.IProWorkorderService;
import com.ximai.mes.pro.service.task.IProTaskService;
import com.ximai.mes.qc.domain.*;
import com.ximai.mes.qc.mapper.QcIpqcMapper;
import com.ximai.mes.qc.service.*;
import com.ximai.system.service.ISysUserService;
import com.ximai.system.strategy.AutoCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 过程检验单Service业务层处理
 *
 * @date 2022-08-29
 */
@Slf4j
@Service
public class QcIpqcServiceImpl implements IQcIpqcService {
    @Resource
    private QcIpqcMapper qcIpqcMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IQcTemplateService qcTemplateService;
    @Autowired
    private IQcTemplateProcessService qcTemplateProcessService;
    @Autowired
    private IQcTemplateIndexService qcTemplateIndexService;
    @Autowired
    private IQcIpqcLineService qcIpqcLineService;
    @Autowired
    private AutoCodeUtil autoCodeUtil;
    @Autowired
    private IProWorkorderService proWorkorderService;
    @Autowired
    private IQcIpqcService qcIpqcService;
    @Autowired
    private IProFeedbackService proFeedbackService;
    @Autowired
    private IMdItemService mdItemService;

    @Autowired
    private IProTaskService proTaskService;
    @Autowired
    private IQcIndexService qcIndexService;

    /**
     * 查询过程检验单
     *
     * @param ipqcId 过程检验单主键
     * @return 过程检验单
     */
    @Override
    public QcIpqc selectQcIpqcByIpqcId(Long ipqcId) {
        return qcIpqcMapper.selectQcIpqcByIpqcId(ipqcId);
    }

    /**
     * 查询过程检验单列表
     *
     * @param qcIpqc 过程检验单
     * @return 过程检验单
     */
    @Override
    public List<QcIpqc> selectQcIpqcList(QcIpqc qcIpqc) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        QueryWrapper<QcIpqc> qcIpqcQueryWrapper = new QueryWrapper<>();
        qcIpqcQueryWrapper.eq("t3.user_id", loginUser.getUser().getUserId());
        qcIpqcQueryWrapper.eq("t1.ipqc_type", qcIpqc.getIpqcType());
        if (StringUtils.isNotEmpty(qcIpqc.getTaskId())) {
            qcIpqcQueryWrapper.eq("t1.task_id", qcIpqc.getTaskId());
        }
        if (StringUtils.isNotEmpty(qcIpqc.getStatus())) {
            qcIpqcQueryWrapper.eq("t1.status", qcIpqc.getStatus());
        }

        List<QcIpqc> qcIpqcs = qcIpqcMapper.selectWorkunitPermListByQw(qcIpqcQueryWrapper);
        if (CollectionUtil.isNotEmpty(qcIpqcs)) {
            SysUser sysUser = new SysUser();
            Set<String> usernames = qcIpqcs.stream().filter(StringUtils::isNotEmpty).map(QcIpqc::getInspector).collect(Collectors.toSet());
            if (CollectionUtil.isNotEmpty(usernames)) {
                sysUser.setUsernames(usernames);
            }

            Map<String, String> nickNameMap = sysUserService.selectUserList(sysUser).stream().filter(Objects::nonNull).collect(Collectors.toMap(SysUser::getUserName, SysUser::getNickName));

            qcIpqcs.forEach(x -> {
                String inspector = x.getInspector();
                String s = nickNameMap.get(inspector);
                x.setInspectorNickName(s);
            });
        }
        return qcIpqcs;
    }

    @Override
    public void insertInspectionOrder(ProTask task, String ipqcType) {
        ProTask proTask = proTaskService.selectBaseById(task.getTaskId());
        QcIpqc ipqc = new QcIpqc();
        ipqc.setTaskId(proTask.getTaskId());
        ipqc.setIpqcType(ipqcType);
        List<QcIpqc> ipqcList = this.selectQcIpqcList(ipqc);
        if (CollectionUtil.isNotEmpty(ipqcList)) {
            log.info("工单id:" + proTask.getWorkorderId() + ",检验单类型:" + ipqcType + ",工序任务id:" + proTask.getTaskId() + ",单据已经创建");
            return;
        }

        List<ProWorkorder> workorders = proWorkorderService.selectListByQw(new QueryWrapper<ProWorkorder>().eq("arrange_code", proTask.getArrangeCode()));
        ProWorkorder workorder = workorders.get(0);


        QcIpqc qcIpqc = proTask.deepSetObj(QcIpqc.class);
        qcIpqc.setIpqcName("首检单" + workorder.getWorkorderName());
        qcIpqc.setIpqcType(ipqcType);
        // 假设已有 QcIpqc qcIpqc 对象初始化
        qcIpqc.setTemplateId(null);
        qcIpqc.setQuantityCheck(BigDecimal.ZERO);
        qcIpqc.setQuantityUnqualified(BigDecimal.ZERO);
        qcIpqc.setQuantityQualified(BigDecimal.ZERO);
        qcIpqc.setCrRate(BigDecimal.ZERO);
        qcIpqc.setMajRate(BigDecimal.ZERO);
        qcIpqc.setMinRate(BigDecimal.ZERO);
        qcIpqc.setCrQuantity(BigDecimal.ZERO);
        qcIpqc.setMajQuantity(BigDecimal.ZERO);
        qcIpqc.setMinQuantity(BigDecimal.ZERO);
        qcIpqc.setStatus(UserConstants.ORDER_STATUS_PREPARE);

        //根据工单获取产品信息
        Long productId = workorder.getProductId();
        qcIpqc.setItemId(productId);
        qcIpqc.setSpecification(workorder.getProductSpc());
        qcIpqc.setUnitOfMeasure(workorder.getUnitOfMeasure());

        //查询工序相关信息
        List<QcIpqc> qcIpqcList = this.selectProcessInfoByQw(new QueryWrapper<QcIpqc>().eq("pwp.workorder_process_id", qcIpqc.getWorkorderProcessId()));
        if (CollectionUtils.isNotEmpty(qcIpqcList) && qcIpqcList.size() == 1) {
            QcIpqc ipqcVal = qcIpqcList.get(0);
            qcIpqc = ipqcVal.deepSetObj(qcIpqc);
        }

        MdItem item = mdItemService.selectMdItemById(productId);
        qcIpqc.setItemCode(item.getSapItemCode());
        qcIpqc.setItemName(item.getItemName());

        //根据产品和检测类型获取检测模板
        QueryWrapper<QcTemplateProcess> query = new QueryWrapper<>();
        query.eq("t1.process_id", proTask.getProcessId());
        query.eq("t1.item_type_id", item.getItemTypeCode());
        query.eq("t2.qc_type", QcConst.IPQC_TABLE);
        List<QcTemplateProcess> templateList = qcTemplateProcessService.selectListJoinTemplateByQw(query);
        if (templateList.size() == 1) {
            qcIpqc.setTemplateId(templateList.get(0).getTemplateId());

            //先保存
            this.insertQcIpqc(qcIpqc);

            //生成行信息
            generateLine(qcIpqc);
        }

    }

    /**
     * 根据头信息生成行信息
     *
     * @param iqc
     */
    private void generateLine(QcIpqc iqc) {
        QcTemplateIndex param = new QcTemplateIndex();
        param.setTemplateId(iqc.getTemplateId());
        List<QcTemplateIndex> qcTemplateIndices = qcTemplateIndexService.selectQcTemplateIndexList(param);
        if (CollUtil.isEmpty(qcTemplateIndices)) {
            return;
        }

        QcIndex qcIndex = new QcIndex();
        qcIndex.setIndexIds(qcTemplateIndices.stream().map(x -> x.getIndexId().toString()).distinct().collect(Collectors.toList()));
        List<QcIndex> qcIndices = qcIndexService.selectQcIndexList(qcIndex);
        Map<Long, Integer> inputTypeMap = qcIndices.stream().collect(Collectors.toMap(QcIndex::getIndexId, QcIndex::getInputType));
        for (QcTemplateIndex qcTemplateIndex : qcTemplateIndices) {
            Long indexId = qcTemplateIndex.getIndexId();
            QcIpqcLine qcIpqcLine = qcTemplateIndex.deepSetObj(QcIpqcLine.class);
            qcIpqcLine.setIpqcId(iqc.getIpqcId());
            qcIpqcLine.setInputType(inputTypeMap.get(indexId));
            qcIpqcLine.setCrQuantity(BigDecimal.ZERO);
            qcIpqcLine.setMajQuantity(BigDecimal.ZERO);
            qcIpqcLine.setMajQuantity(BigDecimal.ZERO);
            qcIpqcLineService.insertQcIpqcLine(qcIpqcLine);
        }
    }


    @Override
    public String checkIpqcCodeUnique(QcIpqc qcIpqc) {
        QcIpqc ipqc = qcIpqcMapper.checkIpqcCodeUnique(qcIpqc);
        Long ipqcId = qcIpqc.getIpqcId() == null ? -1 : qcIpqc.getIpqcId();
        if (StringUtils.isNotNull(ipqc) && ipqc.getIpqcId().longValue() != ipqcId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public List<QcIpqc> selectProcessInfoByQw(QueryWrapper<QcIpqc> query) {
        return qcIpqcMapper.selectProcessInfoByQw(query);
    }

    /**
     * 新增过程检验单
     *
     * @param qcIpqc 过程检验单
     * @return 结果
     */
    @Override
    public int insertQcIpqc(QcIpqc qcIpqc) {
        qcIpqc.createAction();
        if (qcIpqc.getInspector() == null) {
            qcIpqc.setInspector(qcIpqc.getCreateBy());
            qcIpqc.setInspectDate(qcIpqc.getCreateTime());
        }
        qcIpqc.setIpqcCode(autoCodeUtil.genSerialCode(UserConstants.IPQC_CODE, ""));
        return qcIpqcMapper.insertQcIpqc(qcIpqc);
    }

    /**
     * 修改过程检验单
     *
     * @param qcIpqc 过程检验单
     * @return 结果
     */
    @Override
    public int updateQcIpqc(QcIpqc qcIpqc) {
        qcIpqc.updateAction();
        if (qcIpqc.getInspector() == null) {
            qcIpqc.setInspector(qcIpqc.getCreateBy());
            qcIpqc.setInspectDate(qcIpqc.getCreateTime());
        }
        return qcIpqcMapper.updateQcIpqc(qcIpqc);
    }

    @Override
    public int updateCrMajMinQuaAndRate(Long qcId) {
        return qcIpqcMapper.updateCrMajMinQuaAndRate(qcId);
    }


    /**
     * 批量删除过程检验单
     *
     * @param ipqcIds 需要删除的过程检验单主键
     * @return 结果
     */
    @Override
    public int deleteQcIpqcByIpqcIds(Long[] ipqcIds) {
        return qcIpqcMapper.deleteQcIpqcByIpqcIds(ipqcIds);
    }

    /**
     * 删除过程检验单信息
     *
     * @param ipqcId 过程检验单主键
     * @return 结果
     */
    @Override
    public int deleteQcIpqcByIpqcId(Long ipqcId) {
        return qcIpqcMapper.deleteQcIpqcByIpqcId(ipqcId);
    }

    @Override
    public int updateObj(QcIpqc qcIpqc) {

        //对合格品和不合格品数量进行检查
        QcIpqc ipqc = qcIpqcService.selectQcIpqcByIpqcId(qcIpqc.getIpqcId());
        ExceptionUtil.checkTrueThrowException(ipqc == null, MessageUtils.message("qc.error.error2"));
        ipqc = qcIpqc.deepSetObj(ipqc);

        //根据工单获取产品信息
        ProWorkorderQuery proWorkorderQuery = new ProWorkorderQuery();
        proWorkorderQuery.setArrangeCode(ipqc.getArrangeCode());
        List<ProWorkorder> workorders = proWorkorderService.selectProWorkorderList(proWorkorderQuery);
        ProWorkorder workorder = workorders.get(0);


        //根据产品和检测类型获取检测模板
        QcTemplate param = new QcTemplate();
        param.setItemId(workorder.getProductId());
        param.setProcessId(ipqc.getProcessId());
        param.setQcTypes(ipqc.getIpqcType());
        QcTemplate template = qcTemplateService.selectQcTemplateByItemIdAndQcType(param);
        ExceptionUtil.checkTrueThrowException(StringUtils.isNull(template), MessageUtils.message("qc.error.error3"));
        qcIpqc.setTemplateId(template.getId());

        //如果是完成单据则根据单据上的来源单据，更新对应的关联检验单信息
        if (UserConstants.ORDER_STATUS_FINISHED.equals(qcIpqc.getStatus())) {
            if (StringUtils.isNotNull(qcIpqc.getSourceDocCode())) {
                //这里默认更新生产报工单的数据
                ProFeedback feedback = proFeedbackService.selectProFeedbackByRecordId(qcIpqc.getSourceDocId());
                if (StringUtils.isNotNull(feedback)) {
                    feedback.setQuantityQualify(qcIpqc.getQuantityQualified());
                    feedback.setQuantityUnqualify(qcIpqc.getQuantityUnqualified());
                    feedback.setQuantityUncheck(BigDecimal.ZERO);
                    proFeedbackService.updateProFeedback(feedback);
                }
            }
        }

        //根据产品和检测类型获取检测模板
        switch (ipqc.getStatus()) {
            case UserConstants.ORDER_STATUS_PREPARE:
                MdItemType itemTypeByItemId = mdItemService.getItemTypeByItemId(workorder.getProductId());
                QcTemplateProcess qcTemplateProcessParam = new QcTemplateProcess();
                qcTemplateProcessParam.setItemTypeId(itemTypeByItemId.getItemTypeId());
                qcTemplateProcessParam.setTemplateId(template.getId());
                List<QcTemplateProcess> qcTemplateProcesses = qcTemplateProcessService.selectQcTemplateProcessList(qcTemplateProcessParam);
                QcTemplateProcess qcTemplateProcess = qcTemplateProcesses.get(0);
                Integer isConfirm = qcTemplateProcess.getIsConfirm() == null ? 0 : qcTemplateProcess.getIsConfirm();
                Integer isNewProduct = qcTemplateProcess.getIsNewProduct() == null ? 0 : qcTemplateProcess.getIsNewProduct();
                if (qcIpqc.getQuantityCheck().intValue() > qcTemplateProcess.getMaxNum() || isConfirm == 1 || isNewProduct == 1) {
                    ipqc.setStatus(UserConstants.ORDER_STATUS_PENDING);
                } else {
                    ipqc.setStatus(UserConstants.ORDER_STATUS_CONFIRMED);
                }
                break;
            default:
                break;
        }

        QcTemplateIndex templateIndexParam = new QcTemplateIndex();
        templateIndexParam.setTemplateId(ipqc.getTemplateId());
        List<QcTemplateIndex> qcTemplateIndices = qcTemplateIndexService.selectQcTemplateIndexList(templateIndexParam);
        if (CollUtil.isEmpty(qcTemplateIndices)) {
            return 0;
        }

        Map<Long, QcTemplateIndex> qcTemplateIndexMap = qcTemplateIndices.stream().collect(Collectors.toMap(QcTemplateIndex::getId, x -> x));
        List<QcIpqcLine> qcIpqcList = qcIpqc.getQcIpqclineList();
        qcIpqcLineService.deleteByIpqcId(ipqc.getIpqcId());
        for (QcIpqcLine line : qcIpqcList) {
            line.setLineId(null);
            line.setCrQuantity(new BigDecimal(0L));
            line.setMajQuantity(new BigDecimal(0L));
            line.setMajQuantity(new BigDecimal(0L));
            line.setIpqcId(ipqc.getIpqcId());
            if (line.getQcTemplateIndexId() == null) {
                qcIpqcLineService.insertQcIpqcLine(line);
                continue;
            }

            QcTemplateIndex qcTemplateIndex = qcTemplateIndexMap.get(line.getQcTemplateIndexId());

            line = qcTemplateIndex.deepSetObj(line);
            line.setQcTemplateIndexId(qcTemplateIndex.getId());
            qcIpqcLineService.insertQcIpqcLine(line);
        }


        return qcIpqcService.updateQcIpqc(ipqc);
    }

    @Transactional
    @Override
    public int createObj(QcIpqc qcIpqc) {
        ExceptionUtil.checkTrueThrowException(UserConstants.NOT_UNIQUE.equals(this.checkIpqcCodeUnique(qcIpqc)), MessageUtils.message(MessageUtils.message("qc.error.error4")));
        ExceptionUtil.checkTrueThrowException(StringUtils.isEmpty(qcIpqc.getWorkorderCode()) && StringUtils.isEmpty(qcIpqc.getArrangeCode()), MessageUtils.message("pro.workOrder.error.not.exist"));
        ExceptionUtil.checkTrueThrowException(StringUtils.isEmpty(qcIpqc.getWorkorderProcessId()), MessageUtils.message("md.process.error.not.exist"));

        QueryWrapper<ProWorkorder> proWorkorderQueryWrapper = new QueryWrapper<>();
        proWorkorderQueryWrapper.eq(StringUtils.isNotEmpty(qcIpqc.getWorkorderCode()), "workorder_code", qcIpqc.getWorkorderCode());
        proWorkorderQueryWrapper.eq(StringUtils.isNotEmpty(qcIpqc.getArrangeCode()), "arrange_code", qcIpqc.getArrangeCode());
        List<ProWorkorder> workorders = proWorkorderService.selectListByQw(proWorkorderQueryWrapper);
        ExceptionUtil.checkTrueThrowException(CollectionUtil.isEmpty(workorders), MessageUtils.message("pro.workOrder.error.not.exist"));
        ProWorkorder workorder = workorders.get(0);

        //根据工单获取产品信息
        qcIpqc.setItemId(workorder.getProductId());
        qcIpqc.setItemCode(workorder.getProductCode());
        qcIpqc.setItemName(workorder.getProductName());
        qcIpqc.setSpecification(workorder.getProductSpc());
        qcIpqc.setUnitOfMeasure(workorder.getUnitOfMeasure());


        QueryWrapper<QcIpqc> qcIpqcQueryWrapper = new QueryWrapper<>();
        qcIpqcQueryWrapper.eq("pwp.workorder_process_id", qcIpqc.getWorkorderProcessId());
        //查询工序相关信息
        List<QcIpqc> infos = this.selectProcessInfoByQw(qcIpqcQueryWrapper);
        if (!org.springframework.util.CollectionUtils.isEmpty(infos) && infos.size() == 1) {
            QcIpqc ipqc = infos.get(0);
            qcIpqc.setProcessId(ipqc.getProcessId());
            qcIpqc.setProcessCode(ipqc.getProcessCode());
            qcIpqc.setProcessCode(ipqc.getProcessCode());
            qcIpqc.setWorkstationId(ipqc.getWorkstationId());
            qcIpqc.setWorkstationCode(ipqc.getWorkstationCode());
            qcIpqc.setWorkstationName(ipqc.getWorkstationName());
        }

        //根据产品和检测类型获取检测模板
        QcTemplate param = new QcTemplate();
        param.setItemId(workorder.getProductId());
        param.setQcTypes(qcIpqc.getIpqcType());
        param.setProcessId(qcIpqc.getProcessId());
        QcTemplate template = qcTemplateService.selectQcTemplateByItemIdAndQcType(param);
        ExceptionUtil.checkTrueThrowException(StringUtils.isNull(template), MessageUtils.message("qc.error.error5"));

        qcIpqc.setTemplateId(template.getId());

        // 先保存
        int i = this.insertQcIpqc(qcIpqc);

        QcTemplateIndex templateIndexParam = new QcTemplateIndex();
        templateIndexParam.setTemplateId(qcIpqc.getTemplateId());
        List<QcTemplateIndex> qcTemplateIndices = qcTemplateIndexService.selectQcTemplateIndexList(templateIndexParam);
        if (CollUtil.isEmpty(qcTemplateIndices)) {
            return 0;
        }

        Map<Long, QcTemplateIndex> qcTemplateIndexMap = qcTemplateIndices.stream().collect(Collectors.toMap(QcTemplateIndex::getId, x -> x));
        List<QcIpqcLine> qcIpqcList = qcIpqc.getQcIpqclineList();
        qcIpqcLineService.deleteByIpqcId(qcIpqc.getIpqcId());
        for (QcIpqcLine line : qcIpqcList) {
            line.setLineId(null);
            line.setCrQuantity(new BigDecimal(0L));
            line.setMajQuantity(new BigDecimal(0L));
            line.setMajQuantity(new BigDecimal(0L));
            line.setIpqcId(qcIpqc.getIpqcId());
            if (line.getQcTemplateIndexId() == null) {
                qcIpqcLineService.insertQcIpqcLine(line);
                continue;
            }

            QcTemplateIndex qcTemplateIndex = qcTemplateIndexMap.get(line.getQcTemplateIndexId());
            line.setIndexId(qcTemplateIndex.getIndexId());
            line.setQcTemplateIndexId(qcTemplateIndex.getId());
            line.setIndexCode(qcTemplateIndex.getIndexCode());
            line.setIndexName(qcTemplateIndex.getIndexName());
            line.setIndexType(qcTemplateIndex.getIndexType());
            line.setQcTool(qcTemplateIndex.getQcTool());
            line.setCheckMethod(qcTemplateIndex.getCheckMethod());
            line.setStanderVal(qcTemplateIndex.getStanderVal());
            line.setUnitOfMeasure(qcTemplateIndex.getUnitOfMeasure());
            line.setThresholdMax(qcTemplateIndex.getThresholdMax());
            line.setThresholdMin(qcTemplateIndex.getThresholdMin());
            qcIpqcLineService.insertQcIpqcLine(line);
        }


        return i;

    }
}
