package com.sw.mes.yb.pc.service.impl;

import com.sw.mes.base.factory.inspect.entity.RoundSpellRule;
import com.sw.mes.base.factory.inspect.service.DefaultCrystalAttrService;
import com.sw.mes.base.factory.inspect.service.RoundSpellRuleService;
import com.sw.mes.base.workinprocess.dto.CurrentWipStorageStatusDto;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.entity.WipStorage;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.yb.mcs.service.PublishRankResultService;
import com.sw.mes.yb.pc.dao.SectionDAO;
import com.sw.mes.yb.pc.dto.SectionRankDto;
import com.sw.mes.yb.pc.entity.Section;
import com.sw.mes.yb.pc.entity.SectionRank;
import com.sw.mes.yb.pc.entity.SpellInfo;
import com.sw.mes.yb.pc.service.SectionRankService;
import com.sw.mes.yb.pc.service.SectionService;
import com.sw.mes.yb.pc.service.SpellInfoService;
import com.sw.mes.yb.pc.service.TrayBindingRecordService;
import com.sw.mes.yb.plan.service.ProductionOrderService;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class SectionServiceImpl extends BaseServiceImpl<Section> implements SectionService {

    private static final List<String> CURRENT_WIP_STORAGE = new ArrayList<>();
    private static final List<String> CURRENT_WIP_STORAGE_NAME = new ArrayList<>();

    //开方待进站、圆棒检验进站、方棒检验进站
    private static final List<String> UN_CURRENT_WIP_STORAGE = new ArrayList<>();
    private static final List<String> UN_CURRENT_WIP_STORAGE_NAME = new ArrayList<>();

    public SectionServiceImpl() {
        //绑定站点
        //用作判断
        CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.圆棒检验.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey());
        CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.粘圆棒.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey());
        CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.粘方棒.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey());
        CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.方棒检验.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey());
        //用作提示
        CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.圆棒检验.getValue() + EnumValuesFactory.WipStorageStatus.已进站.getValue());
        CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.粘圆棒.getValue() + EnumValuesFactory.WipStorageStatus.已进站.getValue());
        CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.粘方棒.getValue() + EnumValuesFactory.WipStorageStatus.已进站.getValue());
        CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.方棒检验.getValue() + EnumValuesFactory.WipStorageStatus.已进站.getValue());

        //解绑站点
        //用作判断
        UN_CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.开方.getKey() + EnumValuesFactory.WipStorageStatus.待进站.getKey());
        UN_CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.圆棒检验.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey());
        UN_CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.方棒检验.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey());
        //用作提示
        UN_CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.开方.getValue() + EnumValuesFactory.WipStorageStatus.待进站.getValue());
        UN_CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.圆棒检验.getValue() + EnumValuesFactory.WipStorageStatus.已进站.getValue());
        UN_CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.方棒检验.getValue() + EnumValuesFactory.WipStorageStatus.已进站.getValue());
    }

    SectionDAO sectionDAO;

    @Autowired
    private RoundSpellRuleService roundSpellRuleService;

    @Autowired
    public void setDao(SectionDAO sectionDAO) {
        this.sectionDAO = sectionDAO;
        super.setBaseDao(sectionDAO);
    }

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private YbInspectDataService inspectDataBaseService;

    @Autowired
    private SectionRankService sectionRankService;

    @Autowired
    private TrayBindingRecordService trayBindingRecordService;

    @Autowired
    private SpellInfoService spellInfoService;

    @Autowired
    private WipStorageService wipStorageService;

    @Autowired
    private DefaultCrystalAttrService defaultCrystalAttrService;

    @Autowired
    private PublishRankResultService publishRankResultService;

    @Autowired
    private ProductionOrderService productionOrderService;

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    @Override
    public void updateRank(List<SectionRankDto> sectionRankDtos) {

        List<String> sectionNos = new ArrayList<>();
        Map<String, SectionRankDto> map = new HashMap<>();

        List<SectionRank> ranks = new ArrayList<>();

        SectionRank sectionRank;
        for (SectionRankDto dto : sectionRankDtos) {
            sectionNos.add(dto.getSectionNo());
            map.put(dto.getSectionNo(), dto);

            sectionRank = modelMapper.map(dto, SectionRank.class);
            sectionRank.setCreateTime(new Date());
            ranks.add(sectionRank);
        }

        if (sectionNos.size() > 0) {
            List<Section> sections = sectionDAO.findBySectionNoIn(sectionNos);
            if (sections != null && sections.size() > 0) {
                List<Section> updateList = new ArrayList<>();
                SectionRankDto item;
                for (Section section : sections) {
                    if (map.containsKey(section.getSectionNo())) {
                        item = map.get(section.getSectionNo());
                        if ("FQ".equalsIgnoreCase(item.getProductTypeSecond())) {
                            delete(section.getId());
                        } else {
                            section.setProductRankExperiment(item.getProductLevelExperiment());
                            section.setProductRank(item.getProductLevelSecond());
                            section.setProductType(item.getProductTypeSecond());
                            updateList.add(section);
                        }
                    }
                }
                if (updateList.size() > 0) {
                    sectionDAO.saveAll(updateList);
                }
            }

            try {
                sectionRankService.saveAll(ranks);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 拼棒
     *
     * @param sectionNos 晶段编号组
     * @return
     */
    @Override
    public Result stickTogether(List<String> sectionNos, String createUser, int source) {

        for (String inspectDataBase : sectionNos) {
            PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCode(inspectDataBase);
            if (null == planProcessingOrder) {
                throw new BusinessException(inspectDataBase + "工单号不存在");
            }
            if (planProcessingOrder.getStatus().equals(EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey())) {
                throw new BusinessException(inspectDataBase + "在组托状态，不允许粘棒");
            }
        }

        List<String> sectionNoList = new ArrayList<>();
        for (String sectionNo : sectionNos) {
            if (StringUtils.isNotBlank(sectionNo)) {
                sectionNoList.add(sectionNo);
            }
        }
        //验证扫码绑定晶段数
        if (sectionNoList.size() < 2) {
            throw new RuntimeException("错误,至少要填写两个单晶编号");
        }
        //验证晶段编号重复
        Set<String> set = new HashSet<String>(sectionNos);
        boolean checkResult = sectionNos.size() == set.size();
        if (!checkResult) {
            return ResultGenerator.fail("晶段编号重复");
        }

        //查询是否绑定过 - zhxx_yb_data_spell_info
        List<SpellInfo> spellInfoCheckList = spellInfoService.findBySectionNos(sectionNoList);
        if (spellInfoCheckList != null && spellInfoCheckList.size() > 0) {
            StringBuilder sectionNoError = new StringBuilder();
            for (SpellInfo entity : spellInfoCheckList) {
                sectionNoError.append(entity.getSectionNo()).append(",");
            }
            throw new RuntimeException("错误," + sectionNoError + "单晶已绑定");
        }

        //验证晶棒是否存在检验记录
        List<YbInspectData> inspectList = inspectDataBaseService.findBySections(sectionNoList);
        if (inspectList == null || inspectList.size() == 0) {
            throw new RuntimeException("错误,查不到圆棒检验信息");
        }
        StringBuilder sectionNoError = new StringBuilder();
        List<String> inspectSectionNos = new ArrayList<>();
        Set<String> specsSet = new HashSet<>();
        if (inspectList.size() != sectionNoList.size()) {
            for (YbInspectData inspect : inspectList) {
                inspectSectionNos.add(inspect.getSectionNo());
                if (inspect.getProductTypeSecond() == null || inspect.getProductTypeSecond().equals("")) {
                    return ResultGenerator.fail("错误，" + inspect.getSectionNo() + "没有检验信息");
                }
                specsSet.add(inspect.getProductTypeSecond());
            }
            if (specsSet.size() > 1) {
                return ResultGenerator.fail("错误，选择的圆棒圆棒规则不相等");
            }
            for (String sectionNoCheck : sectionNoList) {
                if (!inspectSectionNos.contains(sectionNoCheck)) {
                    sectionNoError.append(sectionNoCheck).append(",");
                }
            }
            return ResultGenerator.fail("错误," + sectionNoError + "等单晶无检验信息");
        }
        //获取规则
        List<RoundSpellRule> list2 = roundSpellRuleService.findRuleBySpecs(inspectList.get(0).getProductTypeSecond(), 1);
        //计算拼棒总长
        BigDecimal totalLength = inspectList.stream().map(e -> e.getActualLength() == null ? new BigDecimal(0) : e.getActualLength()).reduce(BigDecimal.ZERO, BigDecimal::add);
        totalLength.add(BigDecimal.valueOf(2 * (sectionNoList.size() - 1)));
//        //计算总重量
//        BigDecimal totalWeight = inspectList.stream().map(e -> e.getWeight() == null ? new BigDecimal(0) : e.getActualWeight()).reduce(BigDecimal.ZERO, BigDecimal::add);
        //计算总理论重量
        BigDecimal theoryWeight = inspectList.stream().map(e -> e.getTheoryWeight() == null ? new BigDecimal(0) : e.getTheoryWeight()).reduce(BigDecimal.ZERO, BigDecimal::add);
        RoundSpellRule ruleBySpecs = null;
        if (list2.size() > 0) {
            lab:
            for (RoundSpellRule roundSpellRule : list2) {
                boolean flag1 = false;
                for (int w = 0; w < inspectList.size(); w++) {
                    boolean flag = false;
                    boolean flag2 = true;
                    //验证产品等级
                    if (inspectList.get(w).getProductLevel() == null) {
                        return ResultGenerator.fail("错误," + inspectList.get(w).getSectionNo() + "单晶无产品等级");
                    }
                    if (roundSpellRule.getProductGrade() != null) {
                        String[] str1 = roundSpellRule.getProductGrade().split(",");
                        for (String s : str1) {
                            if (s.equals(inspectList.get(w).getProductLevel())) {
                                flag2 = false;
                                break;
                            }
                        }
                    }
                    if (flag2) {
                        continue lab;
                    }
                    //验证实验等级
                    if (roundSpellRule.getExperimentGrade() != null && !roundSpellRule.getExperimentGrade().equals(inspectList.get(w).getProductLevelExperiment())) {
                        continue lab;
                    }
                    //验证直径差
                    if (inspectList.get(w).getDiameterMax().subtract(inspectList.get(w == inspectList.size() - 1 ? w - 1 : w + 1).getDiameterMax()).abs().floatValue() > roundSpellRule.getDiamDiff() && inspectList.get(w).getDiameterMin().subtract(inspectList.get(w == inspectList.size() - 1 ? w - 1 : w + 1).getDiameterMin()).abs().floatValue() > roundSpellRule.getDiamDiff()) {
                        continue lab;
                    }
                    //验证扭（如果规则扭是验证条件，检验数据中扭有值判定为不可拼棒）
                    if (roundSpellRule.getTwist() == 0 && inspectList.get(w).getDistortion() != null && inspectList.get(w).getDistortion().intValue() > 0) {
                        continue lab;
                    }
//                    //验证细（如果规则细是验证条件，检验数据中细总长有值判定为不可拼棒）
//                    if (roundSpellRule.getThin() == 0 && inspectList.get(w).getFineDiameter() != null && inspectList.get(w).getFineDiameter().intValue() > 0) {
//                        continue lab;
//                    }
//                    //验证细减（如果规则细减是验证条件，检验数据中细减有值判定为不可拼棒）
//                    if (roundSpellRule.getThinCut() == 0 && inspectList.get(w).getFineCutLength() != null && inspectList.get(w).getFineCutLength().intValue() > 0) {
//                        continue lab;
//                    }
                    //验证细斜（如果规则斜是验证条件，检验数据中斜有值判定为不可拼棒）
                    if (roundSpellRule.getThinCut() == 0 && inspectList.get(w).getIsBevel() != null && inspectList.get(w).getIsBevel() > 0) {
                        continue lab;
                    }
                    //验证长度范围
                    String length = roundSpellRule.getLength();

                    if (length != null && !length.equals("")) {
                        String[] str = length.split(",");
                        for (String s : str) {
                            List<String> list;
                            String[] str1 = s.split("-");
                            list = Arrays.asList(str1);
                            if (totalLength.floatValue() >= Integer.parseInt(list.get(0)) && totalLength.floatValue() <= Integer.parseInt(list.get(1))) {
                                flag = true;
                                break;
                            }
                        }
                    }
                    flag1 = flag;
                }
                if (flag1) {
                    ruleBySpecs = roundSpellRule;
                    break;
                }
            }
        }

        if (ruleBySpecs != null) {
        } else {
            throw new RuntimeException("错误，没有可匹配的拼棒规则");
        }

        //按顺序拼接单晶编号、单晶编号长度组，计算单晶总长度
        //构造单晶圆棒编号组
        StringBuilder lengthGroup = new StringBuilder();
        StringBuilder weightGroup = new StringBuilder();
        for (String sectionNo : sectionNoList) {
            YbInspectData inspect = inspectList.stream().filter(o -> o.getSectionNo().trim().equalsIgnoreCase(sectionNo.trim())).findAny().orElse(null);
            if (inspect == null) {
                throw new RuntimeException("错误," + sectionNo + "单晶无检验信息");
            } else {
                lengthGroup.append(inspect.getActualLength() == null ? "0" : inspect.getActualLength().toString()).append(",");
//                weightGroup.append(inspect.getActualWeight() == null ? "0" : inspect.getActualWeight().toString()).append(",");
            }
        }
        if (lengthGroup.toString().contains(",")) {
            lengthGroup = new StringBuilder(lengthGroup.substring(0, lengthGroup.length() - 1));
        }
        if (weightGroup.toString().contains(",")) {
            weightGroup = new StringBuilder(weightGroup.substring(0, weightGroup.length() - 1));
        }
        YbInspectData inspectFirst = inspectList.stream().filter(o -> o.getSectionNo().trim().equalsIgnoreCase(sectionNoList.get(0).trim())).findAny().orElse(null);
        //晶段类型根据晶段规格、参杂剂、长度判断，圆棒生产管理》检验数据管理》辨准与规则维护》默认值维护》晶棒属性
        String type = defaultCrystalAttrService.getDefaultCrystalAttrOneTimes(inspectFirst.getDopant(), inspectFirst.getProductTypeSecond(), inspectFirst.getProductLevel(), totalLength);
        // 更改圆棒检验拼棒字段
        // inspectDataBaseService.updateSticksCountFbSectionNoList(sectionNos, sectionNos.size(), totalLength, type, StringUtils.join(sectionNoList, ","));
        inspectList.forEach(inspect -> {
            inspect.setSectionCompose(StringUtils.join(sectionNoList, ","));
            inspect.setSticksCount(sectionNos.size());
            inspect.setSpellBarLength(totalLength);
            inspect.setSectionType(type);
            // 圆棒评级下发
            publishRankResultService.publishRankResult(inspect, null, theoryWeight);
        });
        //第一个单晶圆棒检验信息
        Section sectionGroup = new Section();
        //第一根晶段的信息（为组号）
        sectionGroup.setSectionNo(inspectFirst.getSectionNo());
        //晶段编号组
        sectionGroup.setSectionNoGroup(StringUtils.join(sectionNoList, ","));
        //晶段长度组
        sectionGroup.setLengthGroup(lengthGroup.toString());
        //晶段重量组
        sectionGroup.setWeightGroup(weightGroup.toString());
        //拼数
        sectionGroup.setStickCount(sectionNoList.size());
        //产品类型
        sectionGroup.setProductType(type);
        //产品等级
        sectionGroup.setProductRank(inspectFirst.getProductLevel());
        //实验等级
        sectionGroup.setProductRankExperiment(inspectFirst.getProductLevelExperiment());
        //重量
        sectionGroup.setActualWeight(null);
        //总理论重量
        sectionGroup.setTheoryWeight(theoryWeight);
        //导电型号
        sectionGroup.setConductiveType(inspectFirst.getConductiveType());
        //规格
        sectionGroup.setSpecs(inspectFirst.getProductTypeSecond());
        //晶段总长度
        sectionGroup.setTotalLength(totalLength);
        //操作人员id
        sectionGroup.setWorkNo(String.valueOf(BaseContextHandler.getUserID()));
        //操作人员
        sectionGroup.setRecordUser(BaseContextHandler.getUsername());
        //操作时间
        sectionGroup.setOperateTime(new Date());
        sectionGroup.setState(0);
        sectionGroup.setSource(source);
        saveOrUpdate(sectionGroup);
        //创建拼棒中间表
        createSpellInfo(sectionGroup.getId(), sectionGroup.getSectionNoGroup());
        inspectDataBaseService.saveAll(inspectList);
        return ResultGenerator.success(sectionGroup);
    }

    /**
     * 拼棒
     *
     * @param sectionNos 晶段编号组
     * @return
     */
    @Override
    public Result stickTogetherBySectionNos(List<String> sectionNos, String createUser) {
        String sectionNoGroup = null;
        String wipStorageCode = null;
        String wipStorageUuidCode = null;
        for (String sectionNo : sectionNos) {
            Result<CurrentWipStorageStatusDto> currentWipStorageStatusDtoResult = wipStorageService.selectWipStorageResult(sectionNo);
            if (currentWipStorageStatusDtoResult.getCode() == ResultCode.SUCCESS.getCode()) {
                CurrentWipStorageStatusDto currentWipStorageStatusDto = currentWipStorageStatusDtoResult.getData();
                String wipStorageCodeStatus = currentWipStorageStatusDto.getWipStorageCode() + currentWipStorageStatusDto.getWipStorageStatus();
                if (!CURRENT_WIP_STORAGE.contains(wipStorageCodeStatus)) {
                    return ResultGenerator.fail("当前站点为：" + currentWipStorageStatusDto.getWipStorageCodeName()
                            + currentWipStorageStatusDto.getWipStorageStatusName()
                            + "，只有为（" + StringUtils.join(CURRENT_WIP_STORAGE_NAME, "，") + "）这些站点才能拼棒");
                }
                if (sectionNoGroup == null) {
                    sectionNoGroup = sectionNo;
                    wipStorageCode = currentWipStorageStatusDto.getWipStorageCode() + currentWipStorageStatusDto.getWipStorageStatus();
                    wipStorageUuidCode = currentWipStorageStatusDto.getWipStorageUuid();
                } else {
                    if (!wipStorageCode.equals(wipStorageCodeStatus) || !wipStorageUuidCode.equals(currentWipStorageStatusDto.getWipStorageUuid())) {
                        return ResultGenerator.fail(sectionNo + "与" + sectionNoGroup + "站点状态不一致，请确认");
                    }
                }
            } else {
                return ResultGenerator.fail(currentWipStorageStatusDtoResult.getMessage());
            }
        }
        for (String sectionNo : sectionNos) {
            if (wipStorageCode.equals(EnumValuesFactory.WipStorageCode.粘圆棒.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey())) {
                //2022年3月24日10:57:59（更改逻辑，如果是粘圆棒站点的做出站处理）粘棒完成变更（粘圆棒数据提交，站点为：粘圆棒出站，开方待进站）
                Result result = wipStorageService.outStation(sectionNo, "A", "ff32hotb86".equals(wipStorageUuidCode) ? EnumValuesFactory.WipStorageStatus.已进站.getKey() : EnumValuesFactory.WipStorageStatus.待进站.getKey());
                if (result.getCode() != ResultCode.SUCCESS.getCode()) {
                    throw new RuntimeException(result.getMessage());
                }
            }
        }
        stickTogether(sectionNos, createUser, 0);
        return ResultGenerator.success();
    }


    //region 废弃代码 start 2022-04-26
    //    @Override
//    public void ybJoinUnbind(Integer id, String userName) {
//        //获取拼棒绑定记录
//        TrayBindingRecord trayBindingRecord = trayBindingRecordService.get(id);
//        if (trayBindingRecord.getStatus() == null || trayBindingRecord.getStatus().equals(EnumValues.trayBindingRecordStatus.UNBUNDLING.getKey())) {
//            throw new RuntimeException("错误，此记录已解绑");
//        }
//        if (StringUtils.isBlank(trayBindingRecord.getSectionNoGroup())) {
//            throw new RuntimeException("单晶组号错误");
//        }
//        //获取圆棒单晶编号list
//        List<String> sectionNos = new ArrayList<>();
//        String[] sectionArry = trayBindingRecord.getSectionNoGroup().split(",");
//        for (String sectionNo : sectionArry) {
//            sectionNos.add(sectionNo);
//            Result<CurrentWipStorageStatusDto> result = wipStorageService.selectWipStorageResult(sectionNo);
//            if (result.getCode() == ResultCode.SUCCESS.getCode()
//                    && EnumValuesFactory.WipStorageCode.开方.getKey().equals(result.getData().getWipStorageCode())
//            ) {
//                //解绑完成变更（如果解绑，就要变成：粘圆棒进站）
//                wipStorageService.exitStation(sectionNo);
//            }
//        }
//        //删除拼圆棒中间表
//        spellInfoService.deleteBySectionNos(sectionNos);
//        //删除zhxx_fb_data_section表
//        sectionDAO.deleteBySectionNos(sectionNos);
//        //更改拼棒绑定记录表状态
//        trayBindingRecord.setStatus(EnumValues.trayBindingRecordStatus.UNBUNDLING.getKey());
//        trayBindingRecord.setUnbundlingUserName(userName);
//        trayBindingRecord.setUnbundlingTime(new Date());
//        trayBindingRecordService.saveOrUpdate(trayBindingRecord);
//    }
//
//    @Override
//    public void ybJoinPdaUnbind(String code, String userName, String relieveReason) {
//        //获取拼棒绑定记录
//        List<TrayBindingRecord> byCodeAndStatus = trayBindingRecordService.findByCodeAndStatus(code, EnumValues.trayBindingRecordStatus.BUNDLING.getKey());
//        if (null == byCodeAndStatus || byCodeAndStatus.size() == 0) {
//            throw new RuntimeException("错误，此托号不存在需要解绑的单晶！");
//        }
//        byCodeAndStatus.forEach((trayBindingRecord) -> {
//            if (StringUtils.isBlank(trayBindingRecord.getSectionNoGroup())) {
//                throw new RuntimeException("单晶组号错误");
//            }
//            //获取圆棒单晶编号list
//            List<String> sectionNos = new ArrayList<>();
//            String[] sectionArry = trayBindingRecord.getSectionNoGroup().split(",");
//            for (String sectionNo : sectionArry) {
//                sectionNos.add(sectionNo);
//                Result<CurrentWipStorageStatusDto> result = wipStorageService.selectWipStorageResult(sectionNo);
//                if (result.getCode() == ResultCode.SUCCESS.getCode()
//                        && EnumValuesFactory.WipStorageCode.开方.getKey().equals(result.getData().getWipStorageCode())
//                ) {
//                    //解绑完成变更（如果解绑，就要变成：粘圆棒进站）
//                    wipStorageService.exitStation(sectionNo);
//                }
//            }
//            //删除拼圆棒中间表
//            spellInfoService.deleteBySectionNos(sectionNos);
//            //删除zhxx_fb_data_section表
//            sectionDAO.deleteBySectionNos(sectionNos);
//            //更改拼棒绑定记录表状态
//            trayBindingRecord.setStatus(EnumValues.trayBindingRecordStatus.UNBUNDLING.getKey());
//            trayBindingRecord.setUnbundlingUserName(userName);
//            trayBindingRecord.setUnbundlingTime(new Date());
//            trayBindingRecordService.saveOrUpdate(trayBindingRecord);
//        });
//    }
//
//    @Override
//    public void deleteById(Long id) {
//        Section section = sectionDAO.getOne(id);
//        if (section.getState() == 1) {
//            sectionDAO.deleteById(id);
//        } else {
//            //获取圆棒单晶编号list
//            List<String> sectionNos = new ArrayList<>();
//            String[] sectionArray = section.getSectionNoGroup().split(",");
//            Collections.addAll(sectionNos, sectionArray);
//            //删除拼圆棒中间表
//            spellInfoService.deleteBySectionNos(sectionNos);
//            String sectionType = "非标棒";
//            //更改圆棒检验拼棒字段
//            inspectDataBaseService.updateSticksCountFbSectionNoList(sectionNos, 1, null, sectionType, null);
//            //2022年4月5日10:14:40，修改方棒检验数据库，修复解绑圆棒，方棒反切无法操作，暂时没做工单类型区分，原本功能检验暂时也做更改，因为部分单晶站点过不去，需要重新绑定
//            inspectDataBaseService.updateSticksCountFbSectionNoListFromYb(sectionNos, 1, null, sectionType, null);
//            //判断自动粘棒与人工粘棒，自动粘棒的不做退站处理
//            if (section.getSource() == 0) {
//                for (String no : sectionNos) {
//                    Result<CurrentWipStorageStatusDto> result = wipStorageService.selectWipStorageResult(no);
//                    if (result.getCode() == ResultCode.SUCCESS.getCode()
//                            && EnumValuesFactory.WipStorageCode.开方.getKey().equals(result.getData().getWipStorageCode())
//                    ) {
//                        WipStorage wipStorage = wipStorageService.get(result.getData().getParentId());
//                        String processUuid = Optional.ofNullable(wipStorage).map(WipStorage::getProcessUuid).orElse(null);
//                        //如果上一次是粘圆棒，则退站
//                        if ("ypaqe699t".equals(processUuid)) {
//                            //解绑完成变更（如果解绑，就要变成：粘圆棒进站）
//                            wipStorageService.exitStation(no);
//                        }
//                    }
//                }
//            }
//            sectionDAO.deleteById(id);
//        }
//    }
    //endregion

    @Override
    public void ybRelieve(Long id, String relieveReason) {
        Section section = sectionDAO.getOne(id);
        Result<CurrentWipStorageStatusDto> result = wipStorageService.selectWipStorageResult(section.getSectionNo());
        CurrentWipStorageStatusDto currentWipStorageStatusDto = result.getData();
        String wipStorageCodeStatus = currentWipStorageStatusDto.getWipStorageCode() + currentWipStorageStatusDto.getWipStorageStatus();
        if (!UN_CURRENT_WIP_STORAGE.contains(wipStorageCodeStatus)) {
            throw new RuntimeException("当前站点为：" + currentWipStorageStatusDto.getWipStorageCodeName()
                    + currentWipStorageStatusDto.getWipStorageStatusName()
                    + "，只有为（" + StringUtils.join(UN_CURRENT_WIP_STORAGE_NAME, "，") + "）这些站点才能解绑拼棒");
        }
        //获取圆棒单晶编号list
        List<String> sectionNos = new ArrayList<>();
        String[] sectionArray = section.getSectionNoGroup().split(",");
        Collections.addAll(sectionNos, sectionArray);
        //删除拼圆棒中间表
        spellInfoService.deleteBySectionNos(sectionNos);
        String sectionType = "非标棒";
        //2022年4月5日10:14:40，修改方棒检验数据库，修复解绑圆棒，方棒反切无法操作，暂时没做工单类型区分，原本功能检验暂时也做更改，因为部分单晶站点过不去，需要重新绑定
        inspectDataBaseService.updateSticksCountFbSectionNoListFromYb(sectionNos, 1, null, sectionType, null);
        //判断自动粘棒与人工粘棒，自动粘棒的不做退站处理
        for (String no : sectionNos) {
            Result<CurrentWipStorageStatusDto> resultCurrent = no.equals(section.getSectionNo()) ? result : wipStorageService.selectWipStorageResult(no);
            if (resultCurrent.getCode() == ResultCode.SUCCESS.getCode() && EnumValuesFactory.WipStorageCode.开方.getKey().equals(resultCurrent.getData().getWipStorageCode())) {
                WipStorage wipStorage = wipStorageService.get(resultCurrent.getData().getParentId());
                String processUuid = Optional.ofNullable(wipStorage).map(WipStorage::getProcessUuid).orElse(null);
                //如果上一次是粘圆棒，则退站
                if ("ypaqe699t".equals(processUuid)) {
                    //解绑完成变更（如果解绑，就要变成：粘圆棒进站）
                    wipStorageService.exitStation(no);
                }
            }
        }
        //更改圆棒检验拼棒字段，并且重新下发评级
        List<YbInspectData> inspectDataBases = new ArrayList<>();
        for (String sectionNo : sectionNos) {
            YbInspectData inspectDataBase = inspectDataBaseService.findBySectionNo(sectionNo);
            inspectDataBase.setSticksCount(1);
            inspectDataBase.setSpellBarLength(null);
            inspectDataBase.setSectionType(sectionType);
            inspectDataBase.setSectionCompose(null);
            inspectDataBases.add(inspectDataBase);
        }
        //优先保存，确保保存成功，在重新下发评级
        inspectDataBaseService.saveAll(inspectDataBases);
        sectionDAO.UpdateState(id, BaseContextHandler.getUserID(), BaseContextHandler.getUsername(), new Date(), relieveReason);
        //重新下发评级，圆棒评级下发
        for (YbInspectData inspectDataBase : inspectDataBases) {
            CurrentWipStorageStatusDto currentWipStorageStatusDto1 =
                    section.getSectionNo().equals(inspectDataBase.getSectionNo()) ? currentWipStorageStatusDto : wipStorageService.selectWipStorageResult(inspectDataBase.getSectionNo()).getData();
            if (currentWipStorageStatusDto1.getWipStorageStatus() == EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey()
                    && ((EnumValuesFactory.WipStorageCode.开方.getKey().equals(currentWipStorageStatusDto1.getWipStorageCode()) && currentWipStorageStatusDto1.getWipStorageStatus() == EnumValuesFactory.WipStorageStatus.待进站.getKey())
                    || (EnumValuesFactory.WipStorageCode.粘圆棒.getKey().equals(currentWipStorageStatusDto1.getWipStorageCode()) && currentWipStorageStatusDto1.getWipStorageStatus() < EnumValuesFactory.WipStorageStatus.已出站.getKey())
                    || (EnumValuesFactory.WipStorageCode.圆棒检验.getKey().equals(currentWipStorageStatusDto1.getWipStorageCode()) && currentWipStorageStatusDto1.getWipStorageStatus() < EnumValuesFactory.WipStorageStatus.已出站.getKey()))
            ) {
                publishRankResultService.publishRankResult(inspectDataBase, null, inspectDataBase.getTheoryWeight());
            }
        }
    }

    /**
     * @param sectionId
     * @param noGroup
     */
    private void createSpellInfo(Long sectionId, String noGroup) {
        if (StringUtils.isNotBlank(noGroup)) {
            List<String> nos = Arrays.asList(noGroup.split(","));
            if (nos.size() > 1) {
                for (String no : nos) {
                    SpellInfo info = spellInfoService.findBySectionNo(no);
                    if (info == null) {
                        info = new SpellInfo();
                    }
                    info.setSectionId(sectionId);
                    info.setSectionNo(no);
                    spellInfoService.saveOrUpdate(info);
                }
            }
        }
    }

    @Override
    public Section findBySectionNo(String sectionNo) {
        List<Section> list = sectionDAO.getBySectionNo(sectionNo);
        if (list.size() <= 0) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 拼棒
     *
     * @param sectionNos 晶段编号组
     * @return
     */
    @Override
    public void stickTogetherV2(List<String> sectionNos, int source) {
        List<String> sectionNoList = new ArrayList<>();
        for (String sectionNo : sectionNos) {
            if (StringUtils.isNotBlank(sectionNo)) {
                sectionNoList.add(sectionNo);
            }
        }
        //查询是否绑定过 - zhxx_yb_data_spell_info
        List<SpellInfo> spellInfoCheckList = spellInfoService.findBySectionNos(sectionNoList);
        if (spellInfoCheckList != null && spellInfoCheckList.size() > 0) {
            StringBuilder sectionNoError = new StringBuilder();
            for (SpellInfo entity : spellInfoCheckList) {
                sectionNoError.append(entity.getSectionNo()).append(",");
            }
            throw new RuntimeException("错误," + sectionNoError + "单晶已绑定");
        }

        //验证晶棒是否存在检验记录
        List<YbInspectData> inspectList = inspectDataBaseService.findBySections(sectionNoList);
        if (inspectList == null || inspectList.size() == 0) {
            throw new RuntimeException("错误,查不到圆棒检验信息");
        }
        //计算拼棒总长
        BigDecimal totalLength = inspectList.stream().map(e -> e.getActualLength() == null ? new BigDecimal(0) : e.getActualLength()).reduce(BigDecimal.ZERO, BigDecimal::add);
        totalLength.add(BigDecimal.valueOf(2 * (sectionNoList.size() - 1)));
        //计算总重量
        BigDecimal totalWeight = inspectList.stream().map(e -> e.getActualWeight() == null ? new BigDecimal(0) : e.getActualWeight()).reduce(BigDecimal.ZERO, BigDecimal::add);
        //计算总理论重量
        BigDecimal theoryWeight = inspectList.stream().map(e -> e.getTheoryWeight() == null ? new BigDecimal(0) : e.getTheoryWeight()).reduce(BigDecimal.ZERO, BigDecimal::add);
        //按顺序拼接单晶编号、单晶编号长度组，计算单晶总长度
        //构造单晶圆棒编号组
        StringBuilder lengthGroup = new StringBuilder();
        StringBuilder weightGroup = new StringBuilder();
        for (String sectionNo : sectionNoList) {
            YbInspectData inspect = inspectList.stream().filter(o -> o.getSectionNo().trim().equalsIgnoreCase(sectionNo.trim())).findAny().orElse(null);
            if (inspect == null) {
                throw new RuntimeException("错误," + sectionNo + "单晶无检验信息");
            } else {
                lengthGroup.append(inspect.getActualLength() == null ? "0" : inspect.getActualLength().toString()).append(",");
                weightGroup.append(inspect.getActualWeight() == null ? "0" : inspect.getActualWeight().toString()).append(",");
            }
        }
        if (lengthGroup.toString().contains(",")) {
            lengthGroup = new StringBuilder(lengthGroup.substring(0, lengthGroup.length() - 1));
        }
        if (weightGroup.toString().contains(",")) {
            weightGroup = new StringBuilder(weightGroup.substring(0, weightGroup.length() - 1));
        }
        YbInspectData inspectFirst = inspectList.stream().filter(o -> o.getSectionNo().trim().equalsIgnoreCase(sectionNoList.get(0).trim())).findAny().orElse(null);
        //晶段类型根据晶段规格、参杂剂、长度判断，圆棒生产管理》检验数据管理》辨准与规则维护》默认值维护》晶棒属性
        assert inspectFirst != null;
        String type = defaultCrystalAttrService.getDefaultCrystalAttrOneTimes(inspectFirst.getDopant(), inspectFirst.getProductTypeSecond(), inspectFirst.getProductLevel(), totalLength);
        // 更改圆棒检验拼棒字段
        // inspectDataBaseService.updateSticksCountFbSectionNoList(sectionNos, sectionNos.size(), totalLength, type, StringUtils.join(sectionNoList, ","));
        inspectList.forEach(inspect -> {
            inspect.setSectionCompose(StringUtils.join(sectionNoList, ","));
            inspect.setSticksCount(sectionNos.size());
            inspect.setSpellBarLength(totalLength);
            inspect.setSectionType(type);
            // 圆棒评级下发
            publishRankResultService.publishRankResult(inspect, totalWeight, theoryWeight);
        });
        //第一个单晶圆棒检验信息
        Section sectionGroup = new Section();
        //第一根晶段的信息（为组号）
        sectionGroup.setSectionNo(inspectFirst.getSectionNo());
        //晶段编号组
        sectionGroup.setSectionNoGroup(StringUtils.join(sectionNoList, ","));
        //晶段长度组
        sectionGroup.setLengthGroup(lengthGroup.toString());
        //晶段重量组
        sectionGroup.setWeightGroup(weightGroup.toString());
        //拼数
        sectionGroup.setStickCount(sectionNoList.size());
        //产品类型
        sectionGroup.setProductType(type);
        //产品等级
        sectionGroup.setProductRank(inspectFirst.getProductLevel());
        //实验等级
        sectionGroup.setProductRankExperiment(inspectFirst.getProductLevelExperiment());
        //重量
        sectionGroup.setActualWeight(totalWeight);
        //总理论重量
        sectionGroup.setTheoryWeight(theoryWeight);
        //导电型号
        sectionGroup.setConductiveType(inspectFirst.getConductiveType());
        //规格
        sectionGroup.setSpecs(inspectFirst.getProductTypeSecond());
        //晶段总长度
        sectionGroup.setTotalLength(totalLength);
        //操作人员id
        sectionGroup.setWorkNo(String.valueOf(BaseContextHandler.getUserID()));
        //操作人员
        sectionGroup.setRecordUser(BaseContextHandler.getUsername());
        //操作时间
        sectionGroup.setOperateTime(new Date());
        sectionGroup.setState(0);
        sectionGroup.setSource(source);
        saveOrUpdate(sectionGroup);
        //创建拼棒中间表
        createSpellInfo(sectionGroup.getId(), sectionGroup.getSectionNoGroup());
        inspectDataBaseService.saveAll(inspectList);
    }


}
