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


import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.store.WarehouseInputRecordBillDetailDto;
import com.sw.mes.core.response.Result;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.production.entity.FormulaScheme;
import com.sw.mes.production.entity.FormulaWeightScheme;
import com.sw.mes.production.service.FormulaSchemeService;
import com.sw.mes.production.service.FormulaWeightSchemeService;
import com.sw.mes.yb.alloy.dto.*;
import com.sw.mes.yb.alloy.entity.FixLogic;
import com.sw.mes.yb.alloy.entity.RawMaterialLevel;
import com.sw.mes.yb.alloy.entity.ResistanceOfThisRod;
import com.sw.mes.yb.alloy.service.*;
import com.sw.mes.yb.plan.entity.ProductionSchedule;
import com.sw.mes.yb.plan.service.ProductionScheduleService;
import com.sw.mes.yb.production.entity.*;
import com.sw.mes.yb.production.service.*;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sw.mes.yb.alloy.entity.AlloyMasterAlloy;
import com.sw.mes.yb.alloy.dao.AlloyMasterAlloyDao;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

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


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class AlloyMasterAlloyServiceImpl extends BaseServiceImpl<AlloyMasterAlloy> implements AlloyMasterAlloyService {
    @Autowired
    private MaterialModelService materialModelService;

    @Autowired
    private AgainTaskService againTaskService;

    @Autowired
    private LoadingTaskService loadingTaskService;

    @Autowired
    private ResistanceOfThisRodService resistanceOfThisRodService;

    @Autowired
    private YbInspectDataService ybInspectDataService;

    @Autowired
    private FixLogicService fixLogicService;

    @Autowired
    private InputFurnaceDetailService inputFurnaceDetailService;

    @Autowired
    private BlastFurnaceDetailService blastFurnaceDetailService;

    @Autowired
    private RawMaterialLevelService rawMaterialLevelService;

    @Autowired
    private AgainTaskDetailService againTaskDetailService;

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private CorrectingRecordService correctingRecordService;

    @Autowired
    private InspectionListService inspectionListService;

    @Autowired
    private ProductionFurnaceMaterialSplitService productionFurnaceMaterialSplitService;

    @Autowired
    private FormulaSchemeService formulaSchemeService;

    @Autowired
    private FormulaWeightSchemeService formulaWeightSchemeService;

    @Autowired
    private ProductionScheduleService productionScheduleService;

    @Autowired
    private StoreFeignClients storeFeignClients;

    @Autowired
    private ProductionMaterialReturnRecordService productionMaterialReturnRecordService;

    @Autowired
    private BlastFurnaceDetailLogService blastFurnaceDetailLogService;


    AlloyMasterAlloyDao dao;

    @Autowired
    public void setDao(AlloyMasterAlloyDao dao) {
        super.setBaseDao(dao);
        this.dao = dao;
    }

    @Override
    public FurnaceBedDto findByCode(String furnaceCode) {
        FurnaceBedDto furnaceBedDto = new FurnaceBedDto();
//                 留锅量
        BigDecimal surplusWeight = null;
//        产品料号
        String materialCode;
//        复投次数
        Integer againNum;
        Long againTaskId = null;
//        工单号
        String sapNo = null;
//        是否完结
        Integer isFillEnd = 0;
        ProductionSchedule productionSchedule = productionScheduleService.findByDeviceNo(furnaceCode);
        Assert.notNull(productionSchedule, "当前炉台未开炉,请先开炉!!!");
        String lotNo = productionSchedule.getLotNo();
//        根据炉次号复投任务查如果没查到去配料任务查
        List<AgainTask> againTaskList = againTaskService.findSuccessByLotNo(lotNo);
        LoadingTask loadingTaskDb = loadingTaskService.findSuccessByLotNo(lotNo);
        if (CollectionUtils.isEmpty(againTaskList) && null == loadingTaskDb) {
            throw new RuntimeException("未查询到复投次数");
        }
        AgainTask againTaskDb = againTaskList.stream()
                .max(Comparator.comparing(AgainTask::getAgainNum))
                .orElse(null);
        if (null == againTaskDb) {
            materialCode = loadingTaskDb.getProductCode();
            againNum = 0;
            sapNo = loadingTaskDb.getSapNo();
        } else {
            materialCode = againTaskDb.getProductCode();
            againNum = againTaskDb.getAgainNum();
            againTaskId = againTaskDb.getId();
            sapNo = againTaskDb.getSapNo();
            AgainTaskDetail againTaskDetailDb = againTaskDetailService.findByAgainTaskIdAndFillEndAndAgainNum(againTaskId,againNum);
            if (Objects.nonNull(againTaskDetailDb)) {
                isFillEnd = againTaskDetailDb.getIsFillEnd();
            }
        }

        MaterialModel materialModel = materialModelService.findByCode(materialCode);
        Assert.notNull(materialModel, "物料主数据信息不存在!!!");
        BigDecimal resistanceOfThisRod = getResistanceOfThisRod(againNum, furnaceCode, furnaceBedDto, isFillEnd);
        buildFurnaceBedDto(furnaceCode, furnaceBedDto, againNum, sapNo, materialModel, resistanceOfThisRod, lotNo);
//        初装和1加上一棒电阻
        if (againNum == 0 || againNum == 1) {
            ResistanceOfThisRod resistanceOfThisRodDb = resistanceOfThisRodService.findByFurnaceCodeAndAddTime(furnaceCode, againNum);
            furnaceBedDto.setUpBarResistance(resistanceOfThisRodDb.getResistanceOfThisRod());
        }
//        二加及二加以上上一棒电阻
        if (againNum >= 2) {
            getUpBarResistance(furnaceCode, furnaceBedDto, materialModel, againNum, lotNo);
        }
        //           计算二加上一棒重量和留过量
        if (againNum == 2) {
            List<LoadingTask> loadingTaskList = loadingTaskService.findRealWeightByLotNo(lotNo);
            loadingTaskList.stream()
                    .max(Comparator.comparingLong(LoadingTask::getId))
                    .ifPresent(loadingTask -> furnaceBedDto.setHeatDimension(loadingTask.getDimension()));
            againTaskList.forEach(item -> {
                if (item.getAgainNum() == 1) {
//                    留锅量
                    BigDecimal upBarWeight = item.getSurplusWeigth();
                    getUpBarWeight(furnaceBedDto, loadingTaskDb, againTaskList, item.getAgainNum(), upBarWeight);
                }
                if (item.getAgainNum() == 2) {
                    furnaceBedDto.setRemainingPotCapacity(item.getSurplusWeigth());
                }
            });
//                计算三加以上上一棒重量、留锅量、上一棒电阻
        } else if (againNum >= 3) {
            Integer againNum1 = againNum - 1;
            for (AgainTask againTask : againTaskList) {
                if (againNum1.equals(againTask.getAgainNum())) {
//                    留锅量
                    surplusWeight = againTask.getSurplusWeigth();
                    getUpBarWeight(furnaceBedDto, loadingTaskDb, againTaskList, againNum1, surplusWeight);
                }
                if (againTask.getAgainNum().equals(againNum)) {
                    furnaceBedDto.setRemainingPotCapacity(againTask.getSurplusWeigth());
                }
            }
        }

        getPolysiliconc(furnaceBedDto, againNum, againTaskId, loadingTaskDb.getId(),lotNo);
        getRecycledMaterials(furnaceBedDto, againNum, againTaskId, loadingTaskDb.getId(),lotNo);
        getInspectionListDto(lotNo, furnaceBedDto, againNum);
        getRecipeInformation(furnaceBedDto, againNum, lotNo);
        return furnaceBedDto;
    }

    /**
     * 计算上一棒重量
     */
    private void getUpBarWeight(FurnaceBedDto furnaceBedDto, LoadingTask loadingTaskDb, List<AgainTask> againTaskDbList, Integer againNum, BigDecimal upBarWeight) {
        furnaceBedDto.setUpBarWeight(upBarWeight);
        furnaceBedDto.setUpBarWeightRemainingPotCapacity(upBarWeight);
//                    配料记录
//        List<BlastFurnaceDetailLog> blastFurnaceDetailLogList = blastFurnaceDetailLogService.findByBlastFurnaceId(loadingTaskDb.getId());
//        if (!CollectionUtils.isEmpty(blastFurnaceDetailLogList)) {
//            List<BlastFurnaceDetailLog> blastFurnaceDetailLogList1 = blastFurnaceDetailLogList.stream()
//                    .filter(blastFurnaceDetailLog -> !new BigDecimal("1").equals(blastFurnaceDetailLog.getWeight()))
//                    .collect(Collectors.toList());
//            if (!CollectionUtils.isEmpty(blastFurnaceDetailLogList1)) {
////                                配料记录重量
//                BigDecimal ingredientWeight = blastFurnaceDetailLogList1.stream()
//                        .map(BlastFurnaceDetailLog::getWeight)
//                        .reduce(BigDecimal.ZERO, BigDecimal::add);
//                if (null == furnaceBedDto.getUpBarWeight()) {
//                    furnaceBedDto.setUpBarWeight(ingredientWeight);
//                } else {
//                    furnaceBedDto.setUpBarWeight(furnaceBedDto.getUpBarWeight().add(ingredientWeight));
//                }
//                blastFurnaceDetailLogList1.forEach(blastFurnaceDetailLog -> {
//                    List<ProductionMaterialReturnRecord> productionMaterialReturnRecordList = productionMaterialReturnRecordService.findByAgainNumAndBatchNo(0, blastFurnaceDetailLog.getBatchNo());
//                    if (!CollectionUtils.isEmpty(productionMaterialReturnRecordList)) {
//                        BigDecimal materialReturnWeight = productionMaterialReturnRecordList.stream()
//                                .map(ProductionMaterialReturnRecord::getWeight)
//                                .reduce(BigDecimal.ZERO, BigDecimal::add);
//                        if (null == furnaceBedDto.getUpBarWeight()) {
//                            furnaceBedDto.setUpBarWeight(materialReturnWeight);
//                        } else {
//                            furnaceBedDto.setUpBarWeight(furnaceBedDto.getUpBarWeight().subtract(materialReturnWeight));
//                        }
//                    }
//                });
//            }
//        }
        List<AgainTask> againTaskList = againTaskDbList.stream()
                .filter(againTask -> againTask.getAgainNum().equals(againNum))
                .collect(Collectors.toList());
        AgainTask againTaskDb = againTaskList.get(0);
        List<AgainTaskDetail> againTaskDetailList = againTaskDetailService.findByAgainTaskId(againTaskDb.getId());
//                    灌料记录
        if (!CollectionUtils.isEmpty(againTaskDetailList)) {
            List<AgainTaskDetail> successAgainTaskDetailList = againTaskDetailList.stream()
                    .filter(againTaskDetail -> againTaskDetail.getRawStatus() == 3 || againTaskDetail.getRawStatus() == 4)
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(successAgainTaskDetailList)) {
                for (AgainTaskDetail againTaskDetail : successAgainTaskDetailList) {
                    List<InputFurnaceDetail> inputFurnaceDetailList = inputFurnaceDetailService.findByAgainTaskDetailId(againTaskDetail.getId());
                    if (!CollectionUtils.isEmpty(inputFurnaceDetailList)) {
//                                灌料重量
                        BigDecimal fillingMaterialWeight = inputFurnaceDetailList.stream()
                                .map(InputFurnaceDetail::getWeight)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        if (null == furnaceBedDto.getUpBarWeight()) {
                            furnaceBedDto.setUpBarWeight(fillingMaterialWeight);
                        } else {
                            furnaceBedDto.setUpBarWeight(furnaceBedDto.getUpBarWeight().add(fillingMaterialWeight));
                        }
                        if (null==furnaceBedDto.getHeadMaterialQuantity()){
                            furnaceBedDto.setHeadMaterialQuantity(fillingMaterialWeight);
                        }else {
                            furnaceBedDto.setHeadMaterialQuantity(furnaceBedDto.getHeadMaterialQuantity().add(fillingMaterialWeight));
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取配方方案名称
     */
    private void getRecipeInformation(FurnaceBedDto furnaceBedDto, Integer againNum, String lotNo) {
        List<ProductionFurnaceMaterialSplit> furnaceMaterialSplitList = productionFurnaceMaterialSplitService.findByLotNoAndAgainNum(lotNo, againNum);
        if (!CollectionUtils.isEmpty(furnaceMaterialSplitList)) {
            Optional<ProductionFurnaceMaterialSplit> productionFurnaceMaterialSplit = furnaceMaterialSplitList
                    .stream()
                    .max(Comparator.comparing(ProductionFurnaceMaterialSplit::getId));
            if (productionFurnaceMaterialSplit.isPresent()) {
                if (null != productionFurnaceMaterialSplit.get().getSchemeId()) {
                    FormulaScheme formulaScheme = formulaSchemeService.get(productionFurnaceMaterialSplit.get().getSchemeId());
                    if (null != formulaScheme) {
                        furnaceBedDto.setRecipeInformation(formulaScheme.getName());
                    }
                }
            }
        }
    }

    /**
     * 获取检验列表
     */
    private void getInspectionListDto(String lotNo, FurnaceBedDto furnaceBedDto, Integer againNum) {
        ArrayList<InspectionListDto> inspectionListDtoList = new ArrayList<>();
        List<YbInspectData> ybInspectDataList = ybInspectDataService.findByLotNo(lotNo);
        List<YbInspectData> ybInspectDataList1 = ybInspectDataList.stream()
                .filter(ybInspectData -> ybInspectData.getPiecewiseNum() == 1 && ybInspectData.getIsCutBack() == 0)
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(ybInspectDataList1)) {
            for (YbInspectData ybInspectData : ybInspectDataList1) {
                InspectionListDto inspectionListDto = new InspectionListDto();
                inspectionListDto.setCrystalNumber(ybInspectData.getSectionNo());
                inspectionListDto.setAddTime(ybInspectData.getAgainNum().toString());
                inspectionListDto.setHeadResistivity(ybInspectData.getTResistivity());
                inspectionListDto.setTailResistivity(ybInspectData.getWResistivity());
                inspectionListDto.setHeadLifeSpan(ybInspectData.getMeanCarrierLifetimeA());
                inspectionListDto.setTailLifeSpan(ybInspectData.getMeanCarrierLifetimeB());
                inspectionListDtoList.add(inspectionListDto);
            }
            furnaceBedDto.setInspectionListDtoList(inspectionListDtoList);
        }
    }

    @Override
    public Float calculationBaseAlloy(AlloyMasterAlloyDto dto) {
        if (null == dto.getUpBarWeight()) {
            dto.setUpBarWeight(new BigDecimal(0));
        }
        if (null == dto.getRemainingPotCapacity()) {
            dto.setRemainingPotCapacity(new BigDecimal(0));
        }
        if (null == dto.getPolysiliconResistance()) {
            dto.setPolysiliconResistance(new BigDecimal(0));
        }
        if (null == dto.getPolysiliconWeight()) {
            dto.setPolysiliconWeight(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialOneResistance()) {
            dto.setRecycledMaterialOneResistance(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialOneWeight()) {
            dto.setRecycledMaterialOneWeight(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialTwoResistance()) {
            dto.setRecycledMaterialTwoResistance(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialTwoWeight()) {
            dto.setRecycledMaterialTwoWeight(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialThreeResistance()) {
            dto.setRecycledMaterialThreeResistance(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialThreeWeight()) {
            dto.setRecycledMaterialThreeWeight(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialFourResistance()) {
            dto.setRecycledMaterialFourResistance(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialFourWeight()) {
            dto.setRecycledMaterialFourWeight(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialFiveResistance()) {
            dto.setRecycledMaterialFiveResistance(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialFiveWeight()) {
            dto.setRecycledMaterialFiveWeight(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialSixResistance()) {
            dto.setRecycledMaterialSixResistance(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialSixWeight()) {
            dto.setRecycledMaterialSixWeight(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialSevenResistance()) {
            dto.setRecycledMaterialSevenResistance(new BigDecimal(0));
        }
        if (null == dto.getRecycledMaterialSevenWeight()) {
            dto.setRecycledMaterialSevenWeight(new BigDecimal(0));
        }

        if (null == dto.getUpBarResistance()) {
            int addTime = Integer.parseInt(dto.getAddTime());
            if (addTime >= 2) {
                addTime = addTime - 1;
            }
            switch (addTime) {
                case 0:
                    dto.setUpBarResistance(new BigDecimal("1.03"));
                    break;
                case 1:
                    dto.setUpBarResistance(new BigDecimal("1.03"));
                    break;
                case 2:
                    dto.setUpBarResistance(new BigDecimal("1.02"));
                    break;
                case 3:
                    dto.setUpBarResistance(new BigDecimal("1.02"));
                    break;
                case 4:
                    dto.setUpBarResistance(new BigDecimal("1.02"));
                    break;
                case 5:
                    dto.setUpBarResistance(new BigDecimal("1.03"));
                    break;
                case 6:
                    dto.setUpBarResistance(new BigDecimal("1.05"));
                    break;
                case 7:
                    dto.setUpBarResistance(new BigDecimal("1.08"));
                    break;
                case 8:
                    dto.setUpBarResistance(new BigDecimal("1.12"));
                    break;
                case 9:
                    dto.setUpBarResistance(new BigDecimal("1.35"));
                    break;
                case 10:
                    dto.setUpBarResistance(new BigDecimal("1.42"));
                    break;
                case 11:
                    dto.setUpBarResistance(new BigDecimal("1.49"));
                    break;
                case 12:
                    dto.setUpBarResistance(new BigDecimal("1.57"));
                    break;
                default:
                    dto.setUpBarResistance(new BigDecimal("1.7"));
            }
        }
        return dao.getComputedMotherAlloyWeight(dto.getUpBarWeight().floatValue(), dto.getRemainingPotCapacity().floatValue(),
                dto.getUpBarResistance().floatValue(), dto.getPolysiliconResistance().floatValue(), dto.getPolysiliconWeight().floatValue(),
                dto.getRecycledMaterialOneResistance().floatValue(), dto.getRecycledMaterialOneWeight().floatValue(),
                dto.getRecycledMaterialTwoResistance().floatValue(), dto.getRecycledMaterialTwoWeight().floatValue(),
                dto.getRecycledMaterialThreeResistance().floatValue(), dto.getRecycledMaterialThreeWeight().floatValue(),
                dto.getRecycledMaterialFourResistance().floatValue(), dto.getRecycledMaterialFourWeight().floatValue(),
                dto.getRecycledMaterialFiveResistance().floatValue(), dto.getRecycledMaterialFiveWeight().floatValue(),
                dto.getRecycledMaterialSixResistance().floatValue(), dto.getRecycledMaterialSixWeight().floatValue(),
                dto.getRecycledMaterialSevenResistance().floatValue(), dto.getRecycledMaterialSevenWeight().floatValue(),
                dto.getResistanceOfThisRod().floatValue(), dto.getMotherAlloyGear().floatValue());
    }

    @Override
    public void save(AlloyMasterAlloyDto alloyMasterAlloyDto) {
        AlloyMasterAlloy alloyMasterAlloyDb = dao.findByLotNoAndAddTime(alloyMasterAlloyDto.getLotNo(), alloyMasterAlloyDto.getAddTime());
        Assert.isNull(alloyMasterAlloyDb, "该炉次号和复投次数已存在");
        List<AgainTask> againTaskList = againTaskService.findSuccessByLotNo(alloyMasterAlloyDto.getLotNo());
        if (!CollectionUtils.isEmpty(againTaskList)) {
            AgainTask againTaskDb = againTaskList.stream()
                    .max(Comparator.comparing(AgainTask::getAgainNum))
                    .orElse(null);
            if (null != againTaskDb) {
                alloyMasterAlloyDto.setEquipmentCode(againTaskDb.getEquipmentCode());
                MaterialModel materialModel = materialModelService.findByCode(againTaskDb.getProductCode());
                if (null != materialModel) {
                    alloyMasterAlloyDto.setProductCode(materialModel.getCode());
                    alloyMasterAlloyDto.setProductShortName(materialModel.getProductName());
                }
                List<ProductionFurnaceMaterialSplit> furnaceMaterialSplitList = productionFurnaceMaterialSplitService.findByLotNoAndAgainNum(againTaskDb.getLotNo(), againTaskDb.getAgainNum());
                if (!CollectionUtils.isEmpty(furnaceMaterialSplitList)) {
                    Optional<ProductionFurnaceMaterialSplit> productionFurnaceMaterialSplit = furnaceMaterialSplitList
                            .stream()
                            .max(Comparator.comparing(ProductionFurnaceMaterialSplit::getId));
                    if (productionFurnaceMaterialSplit.isPresent()) {
                        FormulaScheme formulaScheme = formulaSchemeService.get(productionFurnaceMaterialSplit.get().getSchemeId());
                        FormulaWeightScheme formulaWeightScheme = formulaWeightSchemeService.get(productionFurnaceMaterialSplit.get().getWeightSchemeId());
                        if (null != formulaWeightScheme) {
                            alloyMasterAlloyDto.setWeightSchemeName(formulaWeightScheme.getName());
//                        alloyMasterAlloyDto.setWeightSchemeVersion(productionFurnaceMaterialSplit.getSchemeVersion());
                        }
                        if (null != formulaScheme) {
                            alloyMasterAlloyDto.setRecipeName(formulaScheme.getName());
                            alloyMasterAlloyDto.setRecipeVersion(formulaScheme.getVersion());
                        }
                    }
                }
            }
        }
        BigDecimal feedInWeight = BigDecimal.ZERO;
        if (null != alloyMasterAlloyDto.getPolysiliconWeight()) {
            feedInWeight = feedInWeight.add(alloyMasterAlloyDto.getPolysiliconWeight());
        }
        if (null != alloyMasterAlloyDto.getRecycledMaterialOneWeight()) {
            feedInWeight = feedInWeight.add(alloyMasterAlloyDto.getRecycledMaterialOneWeight());
        }
        if (null != alloyMasterAlloyDto.getRecycledMaterialTwoWeight()) {
            feedInWeight = feedInWeight.add(alloyMasterAlloyDto.getRecycledMaterialTwoWeight());
        }
        if (null != alloyMasterAlloyDto.getRecycledMaterialThreeWeight()) {
            feedInWeight = feedInWeight.add(alloyMasterAlloyDto.getRecycledMaterialThreeWeight());
        }
        if (null != alloyMasterAlloyDto.getRecycledMaterialFourWeight()) {
            feedInWeight = feedInWeight.add(alloyMasterAlloyDto.getRecycledMaterialFourWeight());
        }
        if (null != alloyMasterAlloyDto.getRecycledMaterialFiveWeight()) {
            feedInWeight = feedInWeight.add(alloyMasterAlloyDto.getRecycledMaterialFiveWeight());
        }
        if (null != alloyMasterAlloyDto.getRecycledMaterialSixWeight()) {
            feedInWeight = feedInWeight.add(alloyMasterAlloyDto.getRecycledMaterialSixWeight());
        }
        if (null != alloyMasterAlloyDto.getRecycledMaterialSevenWeight()) {
            feedInWeight = feedInWeight.add(alloyMasterAlloyDto.getRecycledMaterialSevenWeight());
        }
        alloyMasterAlloyDto.setFeedInWeight(feedInWeight);
        AlloyMasterAlloy alloyMasterAlloy = fromDto(alloyMasterAlloyDto);
        alloyMasterAlloy.setCreateUser(BaseContextHandler.getUsername());
        alloyMasterAlloy.setCreateDate(new Date());
        super.saveOrUpdate(alloyMasterAlloy);
        if (!CollectionUtils.isEmpty(alloyMasterAlloyDto.getCorrectingRecordDtoList())) {
            correctingRecordService.save(alloyMasterAlloyDto.getCorrectingRecordDtoList(), alloyMasterAlloy.getId());
            alloyMasterAlloy.setIsCorrecting(0);
        } else {
            alloyMasterAlloy.setIsCorrecting(1);
        }
        if (!CollectionUtils.isEmpty(alloyMasterAlloyDto.getInspectionListDtoList())) {
            inspectionListService.save(alloyMasterAlloyDto.getInspectionListDtoList(), alloyMasterAlloy.getId());
        }
        super.saveOrUpdate(alloyMasterAlloy);
    }

    @Override
    public void deleteById(Integer id) {
        AlloyMasterAlloy alloyMasterAlloy = super.get(id);
        Assert.notNull(alloyMasterAlloy, "母合金信息不存在");
        super.delete(id);
        correctingRecordService.deleteByIds(id);
        inspectionListService.deleteByIds(id);

    }

//    @Override
//    public void feedingConfirmation(FeedingConfirmationDto feedingConfirmationDto) {
//        AlloyMasterAlloy alloyMasterAlloyDb = dao.findByLotNoAndAddTime(feedingConfirmationDto.getLotNo(), feedingConfirmationDto.getAgainNum().toString());
//        String s = alloyMasterAlloyDb.getWorkOrderNumber() + alloyMasterAlloyDb.getFurnaceCode() + alloyMasterAlloyDb.getAddTime();
//        String substring = feedingConfirmationDto.getMotherAlloyCode().substring(0, feedingConfirmationDto.getMotherAlloyCode().length() - 4);
//        if (s.equals(substring)) {
//        }
//    }

//    @Override
//    public FurnaceCodeDto findAgainNumByCode(String furnaceCode) {
//        FurnaceCodeDto furnaceCodeDto = new FurnaceCodeDto();
//        Integer againNum = 0;
//        ProductionSchedule productionSchedule = productionScheduleService.findByDeviceNo(furnaceCode);
//        Assert.notNull(productionSchedule, "炉台号不存在");
//        String lotNo = productionSchedule.getLotNo();
//        //        根据炉次号复投任务查如果没查到去配料任务查
//        List<AgainTask> againTaskList = againTaskService.findSuccessByLotNo(lotNo);
//        LoadingTask loadingTaskDb = loadingTaskService.findSuccessByLotNo(lotNo);
//        if (CollectionUtils.isEmpty(againTaskList) && null == loadingTaskDb) {
//            throw new RuntimeException("未查询到复投次数");
//        }
//        AgainTask againTaskDb = againTaskList.stream()
//                .max(Comparator.comparing(AgainTask::getAgainNum))
//                .orElse(null);
//        if (null != againTaskDb) {
//            againNum = againTaskDb.getAgainNum();
//        }
//        furnaceCodeDto.setFurnaceCode(furnaceCode);
//        furnaceCodeDto.setLotNo(lotNo);
//        furnaceCodeDto.setAgainNum(againNum);
//        return furnaceCodeDto;
//    }

    @Override
    public AlloyMasterAlloy findByLotNoAndAddTime(String lotNo, String addTime) {
        return dao.findByLotNoAndAddTime(lotNo, addTime);
    }


    private AlloyMasterAlloy fromDto(AlloyMasterAlloyDto alloyMasterAlloyDto) {
        return modelMapper.map(alloyMasterAlloyDto, AlloyMasterAlloy.class);
    }

    /**
     * 计算循环料重量和电阻
     */
    private void getRecycledMaterials(FurnaceBedDto furnaceBedDto, Integer againNum, Long againTaskId, Long loadingTaskDbId, String lotNo) {
        String recycledMaterials = "循环料";
        ArrayList<RecycledMaterialDto> arrayList = new ArrayList<>();
        if (againNum == 0) {
            List<BlastFurnaceDetailLog> blastFurnaceDetailLogList = blastFurnaceDetailLogService.findByBlastFurnaceId(loadingTaskDbId);
            if (!CollectionUtils.isEmpty(blastFurnaceDetailLogList)) {
                List<String> productCodeList = blastFurnaceDetailLogList.stream()
                        .filter(blastFurnaceDetailLog -> !new BigDecimal("1").equals(blastFurnaceDetailLog.getWeight()))
                        .map(BlastFurnaceDetailLog::getProductCode)
                        .collect(Collectors.toList());
                List<MaterialModel> materialModelList = materialModelService.findMaterialModelExtra2ByCode(productCodeList, recycledMaterials);

                Map<String, List<BlastFurnaceDetailLog>> listMap = blastFurnaceDetailLogList.stream()
                        .collect(Collectors.groupingBy(BlastFurnaceDetailLog::getProductCode));

                for (MaterialModel materialModel : materialModelList) {
                    RecycledMaterialDto dto = new RecycledMaterialDto();

                    List<BlastFurnaceDetailLog> blastFurnaceDetailLogList1 = listMap.get(materialModel.getCode());
                    BigDecimal recycledMaterialWeight = blastFurnaceDetailLogList1.stream()
                            .map(BlastFurnaceDetailLog::getWeight)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    dto.setRecycledMaterialWeight(recycledMaterialWeight);

//                    blastFurnaceDetailLogList1.forEach(blastFurnaceDetailLog -> {
//                        List<ProductionMaterialReturnRecord> productionMaterialReturnRecordList = productionMaterialReturnRecordService.findByAgainNumAndBatchNoAndLotNo(againNum, blastFurnaceDetailLog.getBatchNo(),lotNo);
//                        if (!CollectionUtils.isEmpty(productionMaterialReturnRecordList)) {
//                            BigDecimal materialReturnWeight = productionMaterialReturnRecordList.stream()
//                                    .map(ProductionMaterialReturnRecord::getWeight)
//                                    .reduce(BigDecimal.ZERO, BigDecimal::add);
//                            dto.setRecycledMaterialWeight(dto.getRecycledMaterialWeight().subtract(materialReturnWeight));
//                        }
//                    });
                    RawMaterialLevel rawMaterialLevelDb = rawMaterialLevelService.findByMaterialCode(materialModel.getCode());
                    if (null != rawMaterialLevelDb) {
                        dto.setRecycledMaterialResistance(rawMaterialLevelDb.getResistanceValue());
                    }
                    arrayList.add(dto);
                }
            }
        } else {
            List<AgainTaskDetail> againTaskDetailList = againTaskDetailService.findByAgainTaskId(againTaskId);

            List<Long> againTaskDetailIds = againTaskDetailList.stream()
                    .filter(againTaskDetail -> againTaskDetail.getRawStatus() == 3 || againTaskDetail.getRawStatus() == 4)
                    .map(AgainTaskDetail::getId)
                    .collect(Collectors.toList());
            List<InputFurnaceDetail> inputFurnaceDetailList = inputFurnaceDetailService.findByAgainTaskDetailIdList(againTaskDetailIds);

            List<String> productCodeList = inputFurnaceDetailList.stream()
                    .map(InputFurnaceDetail::getProductCode)
                    .collect(Collectors.toList());
            List<MaterialModel> materialModelList = materialModelService.findMaterialModelExtra2ByCode(productCodeList, recycledMaterials);
            Map<String, List<InputFurnaceDetail>> listMap = inputFurnaceDetailList.stream()
                    .collect(Collectors.groupingBy(InputFurnaceDetail::getProductCode));

            for (MaterialModel model : materialModelList) {
                RecycledMaterialDto dto = new RecycledMaterialDto();
                List<InputFurnaceDetail> inputFurnaceDetailList1 = listMap.get(model.getCode());
                BigDecimal recycledMaterialWeight = inputFurnaceDetailList1.stream()
                        .map(InputFurnaceDetail::getWeight)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                dto.setRecycledMaterialWeight(recycledMaterialWeight);
                for (InputFurnaceDetail inputFurnaceDetail : inputFurnaceDetailList1) {
                    Result<WarehouseInputRecordBillDetailDto> billDetail = storeFeignClients.getByMaterialCodeAndBatchNo(inputFurnaceDetail.getMaterialCode(), inputFurnaceDetail.getBatchNo());
                    Assert.isTrue(billDetail.getCode() == 200, "调用线边仓接口失败");
                    Assert.isTrue(billDetail.getData().getMaterialGear() != null, "线边仓中未维护物料档位，请先维护");
                    RawMaterialLevel rawMaterialLevelDb = rawMaterialLevelService.findByMaterialCodeAndResistanceGear(model.getCode(), billDetail.getData().getMaterialGear());
                    Assert.notNull(rawMaterialLevelDb, "未在原料档位中维护，请先维护");
                    dto.setRecycledMaterialResistance(rawMaterialLevelDb.getResistanceValue());
                }
                arrayList.add(dto);
            }
        }
        int size = arrayList.size();
        if (size >= 1) {
            furnaceBedDto.setRecycledMaterialOneResistance(arrayList.get(0).getRecycledMaterialResistance());
            furnaceBedDto.setRecycledMaterialOneWeight(arrayList.get(0).getRecycledMaterialWeight());
        }
        if (size >= 2) {
            furnaceBedDto.setRecycledMaterialTwoResistance(arrayList.get(1).getRecycledMaterialResistance());
            furnaceBedDto.setRecycledMaterialTwoWeight(arrayList.get(1).getRecycledMaterialWeight());
        }
        if (size >= 3) {
            furnaceBedDto.setRecycledMaterialThreeResistance(arrayList.get(2).getRecycledMaterialResistance());
            furnaceBedDto.setRecycledMaterialThreeWeight(arrayList.get(2).getRecycledMaterialWeight());
        }
        if (size >= 4) {
            furnaceBedDto.setRecycledMaterialFourResistance(arrayList.get(3).getRecycledMaterialResistance());
            furnaceBedDto.setRecycledMaterialFourWeight(arrayList.get(3).getRecycledMaterialWeight());
        }
        if (size >= 5) {
            furnaceBedDto.setRecycledMaterialFiveResistance(arrayList.get(4).getRecycledMaterialResistance());
            furnaceBedDto.setRecycledMaterialFiveWeight(arrayList.get(4).getRecycledMaterialWeight());
        }
        if (size >= 6) {
            furnaceBedDto.setRecycledMaterialSixResistance(arrayList.get(5).getRecycledMaterialResistance());
            furnaceBedDto.setRecycledMaterialSixWeight(arrayList.get(5).getRecycledMaterialWeight());
        }
        if (size >= 7) {
            furnaceBedDto.setRecycledMaterialSevenResistance(arrayList.get(6).getRecycledMaterialResistance());
            furnaceBedDto.setRecycledMaterialSevenWeight(arrayList.get(6).getRecycledMaterialWeight());
        }
    }

    /**
     * 计算多晶硅重量和电阻
     */
    private void getPolysiliconc(FurnaceBedDto furnaceBedDto, Integer againNum, Long againTaskId, Long loadingTaskDbId, String lotNo) {
        //            多晶硅
        String polysiliconc = "多晶硅";
        if (againNum == 0) {
            List<BlastFurnaceDetailLog> blastFurnaceDetailLogList = blastFurnaceDetailLogService.findByBlastFurnaceId(loadingTaskDbId);
            if (!CollectionUtils.isEmpty(blastFurnaceDetailLogList)) {
                List<String> productCodeList = blastFurnaceDetailLogList.stream()
                        .filter(blastFurnaceDetailLog -> !new BigDecimal("1").equals(blastFurnaceDetailLog.getWeight()))
                        .map(BlastFurnaceDetailLog::getProductCode)
                        .collect(Collectors.toList());
                List<MaterialModel> materialModelList = materialModelService.findMaterialModelExtra2ByCode(productCodeList, polysiliconc);

                Map<String, List<BlastFurnaceDetailLog>> listMap = blastFurnaceDetailLogList.stream()
                        .collect(Collectors.groupingBy(BlastFurnaceDetailLog::getProductCode));
                for (MaterialModel materialModel : materialModelList) {
                    List<BlastFurnaceDetailLog> blastFurnaceDetailLogList1 = listMap.get(materialModel.getCode());
                    BigDecimal recycledMaterialWeight = blastFurnaceDetailLogList1.stream()
                            .map(BlastFurnaceDetailLog::getWeight)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    if (null == furnaceBedDto.getPolysiliconWeight()) {
                        furnaceBedDto.setPolysiliconWeight(recycledMaterialWeight);
                    } else {
                        furnaceBedDto.setPolysiliconWeight(furnaceBedDto.getPolysiliconWeight().add(recycledMaterialWeight));
                    }
//                    blastFurnaceDetailLogList1.forEach(blastFurnaceDetailLog -> {
//                        List<ProductionMaterialReturnRecord> productionMaterialReturnRecordList = productionMaterialReturnRecordService.findByAgainNumAndBatchNoAndLotNo(againNum, blastFurnaceDetailLog.getBatchNo(),lotNo);
//                        if (!CollectionUtils.isEmpty(productionMaterialReturnRecordList)) {
//                            BigDecimal materialReturnWeight = productionMaterialReturnRecordList.stream()
//                                    .map(ProductionMaterialReturnRecord::getWeight)
//                                    .reduce(BigDecimal.ZERO, BigDecimal::add);
//                            if (null == furnaceBedDto.getPolysiliconWeight()) {
//                                furnaceBedDto.setPolysiliconWeight(materialReturnWeight);
//                            } else {
//                                furnaceBedDto.setPolysiliconWeight(furnaceBedDto.getPolysiliconWeight().subtract(materialReturnWeight));
//                            }
//                        }
//                    });
                    RawMaterialLevel rawMaterialLevelDb = rawMaterialLevelService.findByMaterialCode(materialModel.getCode());
                    if (null != rawMaterialLevelDb) {
                        furnaceBedDto.setPolysiliconResistance(rawMaterialLevelDb.getResistanceValue());
                    }
                }
            }
        } else {
            List<AgainTaskDetail> againTaskDetailList = againTaskDetailService.findByAgainTaskId(againTaskId);
            List<Long> againTaskDetailIds = againTaskDetailList.stream()
                    .filter(againTaskDetail -> againTaskDetail.getRawStatus() == 3 || againTaskDetail.getRawStatus() == 4)
                    .map(AgainTaskDetail::getId)
                    .collect(Collectors.toList());
            List<InputFurnaceDetail> inputFurnaceDetailList = inputFurnaceDetailService.findByAgainTaskDetailIdList(againTaskDetailIds);

            List<String> productCodeList = inputFurnaceDetailList.stream()
                    .map(InputFurnaceDetail::getProductCode)
                    .collect(Collectors.toList());
            List<MaterialModel> materialModelList = materialModelService.findMaterialModelExtra2ByCode(productCodeList, polysiliconc);
            Map<String, List<InputFurnaceDetail>> listMap = inputFurnaceDetailList.stream()
                    .collect(Collectors.groupingBy(InputFurnaceDetail::getProductCode));

            for (MaterialModel model : materialModelList) {
                List<InputFurnaceDetail> inputFurnaceDetailList1 = listMap.get(model.getCode());
//                计算多晶硅重量
                BigDecimal recycledMaterialWeight = inputFurnaceDetailList1.stream()
                        .map(InputFurnaceDetail::getWeight)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                if (null == furnaceBedDto.getPolysiliconWeight()) {
                    furnaceBedDto.setPolysiliconWeight(recycledMaterialWeight);
                } else {
                    furnaceBedDto.setPolysiliconWeight(furnaceBedDto.getPolysiliconWeight().add(recycledMaterialWeight));
                }
                for (InputFurnaceDetail inputFurnaceDetail : inputFurnaceDetailList1) {
//            根据物料号查询电阻值
//                    Result<WarehouseInputRecordBillDetailDto> billDetail = storeFeignClients.getByMaterialCodeAndBatchNo(inputFurnaceDetail.getMaterialCode(), inputFurnaceDetail.getBatchNo());
//                    Assert.isTrue(billDetail.getCode() == 200, "调用线边仓接口失败");
//                    Assert.isTrue(billDetail.getData().getMaterialGear() != null, "线边仓中未维护物料档位，请先维护");
                    RawMaterialLevel rawMaterialLevelDb = rawMaterialLevelService.findByMaterialCode(model.getCode());
                    Assert.notNull(rawMaterialLevelDb, "未在原料档位中维护，请先维护");
                    furnaceBedDto.setPolysiliconResistance(rawMaterialLevelDb.getResistanceValue());
                }
            }
        }
    }

    /**
     * 计算二加及二加以上上一棒电阻
     */
    private void getUpBarResistance(String furnaceCode, FurnaceBedDto furnaceBedDto, MaterialModel materialModel, Integer againNum, String lotNo) {
        ArrayList<CorrectingRecordDto> list = new ArrayList<>();
        CorrectingRecordDto dto = new CorrectingRecordDto();
        //                上一棒电阻
        List<YbInspectData> ybInspectDataList1 = ybInspectDataService.findByLotNoAndAgainNum(lotNo, againNum - 2);
//        List<YbInspectData> ybInspectDataList1 = ybInspectDataList.stream()
//                .filter(ybInspectData -> ybInspectData.getPiecewiseNum() == 1 && ybInspectData.getIsCutBack() == 0)
//                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(ybInspectDataList1)) {
            YbInspectData ybInspectData = Collections.max(ybInspectDataList1, Comparator.comparing(YbInspectData::getId));
            if (null != ybInspectData) {
                BigDecimal tResistivity = ybInspectData.getTResistivity();
                furnaceBedDto.setCorrecting(tResistivity);
                dto.setCorrectingValue(tResistivity);
                dto.setAddTime(String.valueOf(againNum));
                FixLogic fixLogicDb = fixLogicService.findByFixUpperLimit(tResistivity);
                if (null != fixLogicDb) {
                    ResistanceOfThisRod resistanceOfThisRodDb2 = resistanceOfThisRodService.findByFurnaceCodeAndAddTime(furnaceCode, againNum - 1);
                    furnaceBedDto.setUpBarResistance(resistanceOfThisRodDb2.getResistanceOfThisRod());
                } else {
                    List<LoadingTask> loadingTaskList = loadingTaskService.findRealWeightByLotNo(lotNo);
                    LoadingTask loadingTask = loadingTaskList.stream()
                            .max(Comparator.comparingLong(LoadingTask::getId)).orElse(null);
                    if (null != loadingTask && null != loadingTask.getDimension()) {
                        FixLogic fixLogic = fixLogicService.findByHeatFieldAndMaterialShortNameAndAddTime(loadingTask.getDimension(), materialModel.getProductName(), againNum - 2);
                        if (null != fixLogic) {
                            BigDecimal fixUpperLimit = fixLogic.getFixUpperLimit();
                            BigDecimal fixLowerLimit = fixLogic.getFixLowerLimit();
                            BigDecimal upperLimitGradient = fixLogic.getUpperLimitGradient();
                            BigDecimal lowerLimitGradient = fixLogic.getLowerLimitGradient();
                            BigDecimal fixUpperLimitConstant = fixLogic.getFixUpperLimitConstant();
                            BigDecimal fixLowerLimitConstant = fixLogic.getFixLowerLimitConstant();
//                            修正上限
                            BigDecimal upperLimit = tResistivity.add(tResistivity.subtract(fixUpperLimit.add(fixLowerLimit))
                                            .divide(new BigDecimal(2), 2, RoundingMode.HALF_UP))
                                    .divide(upperLimitGradient.multiply(fixUpperLimitConstant), 2, RoundingMode.HALF_UP);
//                            修正下限
                            BigDecimal lowerLimit = ((fixUpperLimit.add(fixLowerLimit)).divide(new BigDecimal(2), 2, RoundingMode.HALF_UP)
                                    .subtract(tResistivity))
                                    .divide(lowerLimitGradient.multiply(fixLowerLimitConstant), 2, RoundingMode.HALF_UP);
//                            实测电阻大于等于修正上限
                            if (tResistivity.compareTo(upperLimit) >= 0) {
                                furnaceBedDto.setUpBarResistance(upperLimit);
                                furnaceBedDto.setCorrectingAfterResistance(upperLimit);
                                dto.setCorrectingAfterResistance(upperLimit);
                            }
                            if (tResistivity.compareTo(lowerLimit) <= 0) {
                                furnaceBedDto.setUpBarResistance(lowerLimit);
                                furnaceBedDto.setCorrectingAfterResistance(lowerLimit);
                                dto.setCorrectingAfterResistance(lowerLimit);
                            }
                        }
                    }
                }
                list.add(dto);
            } else {
                ResistanceOfThisRod resistanceOfThisRodDb = resistanceOfThisRodService.findByFurnaceCodeAndAddTime(furnaceCode, againNum - 1);
                furnaceBedDto.setUpBarResistance(resistanceOfThisRodDb.getResistanceOfThisRod());
            }
        } else {
            ResistanceOfThisRod resistanceOfThisRodDb = resistanceOfThisRodService.findByFurnaceCodeAndAddTime(furnaceCode, againNum - 1);
            furnaceBedDto.setUpBarResistance(resistanceOfThisRodDb.getResistanceOfThisRod());
        }

        if (!CollectionUtils.isEmpty(list)) {
            furnaceBedDto.setCorrectingRecordDtoList(list);
        }
    }

    /**
     * 获取本棒电阻
     */
    private BigDecimal getResistanceOfThisRod(Integer againNum, String furnaceCode, FurnaceBedDto furnaceBedDto, Integer isFillEnd) {
        if (isFillEnd == 0) {
            ResistanceOfThisRod resistanceOfThisRodDb2 = resistanceOfThisRodService.findByFurnaceCodeAndAddTime(furnaceCode, againNum);
            Assert.notNull(resistanceOfThisRodDb2, "本棒电阻未维护复投次数为" + againNum + "不存在,炉台号为" + furnaceCode + "请先维护");
            furnaceBedDto.setIsEnd(1);
            return resistanceOfThisRodDb2.getResistanceOfThisRod();
        }
        ResistanceOfThisRod resistanceOfThisRodDb = resistanceOfThisRodService.findByFurnaceCodeAndAddTime(furnaceCode, 99);
        Assert.notNull(resistanceOfThisRodDb, "本棒电阻中未维护复投次数为99的数据，炉台号为" + furnaceCode + "请先维护");
        furnaceBedDto.setIsEnd(0);
        return resistanceOfThisRodDb.getResistanceOfThisRod();
    }

    private static void buildFurnaceBedDto(String furnaceCode, FurnaceBedDto furnaceBedDto, Integer againNum,
                                           String sapNo, MaterialModel materialModel, BigDecimal resistanceOfThisRod,
                                           String lotNo) {
        furnaceBedDto.setWorkNumber(BaseContextHandler.getUserClassNo());
        furnaceBedDto.setUserName(BaseContextHandler.getUsername());
        furnaceBedDto.setFurnaceCode(furnaceCode);
        furnaceBedDto.setLotNo(lotNo);
        furnaceBedDto.setAddTime(againNum);
        if (null != sapNo) {
            furnaceBedDto.setWorkOrderNumber(sapNo);
        }
        furnaceBedDto.setInformationMainProduct(materialModel.getProductName());
        furnaceBedDto.setInformationMessage(lotNo + sapNo + againNum);
        furnaceBedDto.setResistanceOfThisRod(resistanceOfThisRod);
    }
}
