package com.sw.mes.yb.production.controller;

import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.GlobalSwitchNamespace;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.core.annotation.Jinko;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.response.ResponsePage;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.*;
import com.sw.mes.production.dto.DecompositionSchemeParam;
import com.sw.mes.production.dto.FormulaSchemeData;
import com.sw.mes.production.entity.FormulaProductScheme;
import com.sw.mes.production.entity.FormulaProductSchemeDetail;
import com.sw.mes.production.entity.FormulaProductSchemeWeightDetail;
import com.sw.mes.production.entity.FormulaWeightScheme;
import com.sw.mes.production.service.*;
import com.sw.mes.yb.plan.entity.ProductionSchedule;
import com.sw.mes.yb.plan.service.ProductionScheduleService;
import com.sw.mes.yb.production.dto.AgainTask.AgainTaskDto;
import com.sw.mes.yb.production.dto.AgainTask.ConfirmWeightDto;
import com.sw.mes.yb.production.dto.AgainTask.ExistingWeightDto;
import com.sw.mes.yb.production.dto.InputFurnaceDetailDto;
import com.sw.mes.yb.production.entity.*;
import com.sw.mes.yb.production.service.*;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/processAgainTask")
@Slf4j
@Api(description = "复投任务接口")
public class AgainTaskController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private AgainTaskService againTaskService;
    @Autowired
    private DictionaryItemService dictionaryItemService;
    @Autowired
    private ProductionCircleWeightDetailService productionCircleWeightDetailService;
    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;
    @Autowired
    private EquipmentService equipmentService;
    @Autowired
    private AgainTaskDetailService againTaskDetailService;
    @Autowired
    private InputFurnaceDetailService inputFurnaceDetailService;
    @Autowired
    private InputFurnaceBurdenService inputFurnaceBurdenService;
    @Autowired
    private LoadingTaskService loadingTaskService;
    @Autowired
    private BlastFurnaceDetailService blastFurnaceDetailService;
    @Autowired
    private OutputRecordService outputRecordService;
    @Autowired
    private FormulaSchemeOutService formulaSchemeOutService;
    @Autowired
    private ProductionFurnaceMaterialSplitService splitService;
    @Autowired
    private FormulaProductSchemeService formulaProductSchemeService;
    @Autowired
    private FormulaWeightSchemeService formulaWeightSchemeService;
    @Autowired
    private ProductionScheduleService scheduleService;
    @Autowired
    private LongCrystalService longCrystalService;
    @Autowired
    private FormulaProductSchemeDetailService productSchemeDetailService;


    @ApiOperation(value = "分页查询复投任务列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),})
    @GetMapping("/listByPage")
    public Result<ResponsePage<AgainTaskDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<AgainTask> specification = DynamicSpecifications.bySearchFilter(request, AgainTask.class);
        /*String[] sort = {"delayedStartTime DESC"};
        Page<AgainTask> page = againTaskService.findByExample(specification, PageUtil.createPageable(requestPage, sort));*/
        Page<AgainTask> page = againTaskService.findByExample(specification, PageUtil.createPageable(requestPage));
        List<AgainTaskDto> dtos = page.getContent().stream().map(entity -> toLazyDto(entity))
                .collect(Collectors.toList());
        // 补充总装锅料
        for (AgainTaskDto dto : dtos) {
            try{
                ProductionSchedule schedule = scheduleService.findByLotNo(dto.getLotNo());
                FormulaProductScheme productScheme = formulaProductSchemeService.findByEquipmentCodeAndProductModeCode(schedule.getDeviceNo(), schedule.getProductModel().getCode());
                FormulaProductSchemeDetail schemeDetail = productSchemeDetailService.findByFpsIdAndAgainNum(productScheme.getId(), dto.getAgainNum());
                FormulaWeightScheme weightScheme = null;
                if (!ObjectUtils.isEmpty(schemeDetail)){
                    weightScheme = formulaWeightSchemeService.get(schemeDetail.getWeightSchemeId());
                }else if (!ObjectUtils.isEmpty(productScheme.getDecompositionSchemeId())){
                    weightScheme = formulaWeightSchemeService.get(productScheme.getDecompositionSchemeId());
                }
                if (ObjectUtils.isEmpty(weightScheme)) continue;
                // 设置满锅重量
                if (dto.getAgainNum() == 1 && !ObjectUtils.isEmpty(weightScheme.getInitFullPotWeight())){
                    dto.setTotalUseWeigth(weightScheme.getInitFullPotWeight().setScale(0, RoundingMode.UP));

                } else if (dto.getAgainNum() >= 2 && !CollectionUtils.isEmpty(weightScheme.getAgainFullPotWeight())
                    && !ObjectUtils.isEmpty(weightScheme.getAgainFullPotWeight().get(dto.getAgainNum().toString()))){
                        dto.setTotalUseWeigth(weightScheme.getAgainFullPotWeight().get(dto.getAgainNum().toString()).setScale(0, RoundingMode.UP));

                }else {
                    dto.setTotalUseWeigth(weightScheme.getFullPotWeight().setScale(0, RoundingMode.UP));
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
        return ResultGenerator.success(responsePage);
    }


    @Jinko(value = "复投重量确认", author = "wxl")
    @ApiOperation(value = "ipc确认重量")
    @GetMapping("/saveWeight")
    public Result saveWeight(@ApiParam(value = "复投任务id") @RequestParam Long id, @ApiParam(value = "重量") @RequestParam BigDecimal weight) {
        if (id == null || weight == null) {
            return ResultGenerator.fail("参数为空！");
        }
        AgainTask againTask = againTaskService.get(id);
        if (againTask == null) {
            return ResultGenerator.fail("复投任务不存在！");
        }
        if (againTask.getRawStatus() != 0) {
            return ResultGenerator.fail("该复投任务不是新建状态！");
        }
        againTask.setAgainWeigth(weight);
        againTaskService.saveOrUpdate(againTask);
        return ResultGenerator.success();
    }


    @ApiOperation(value = "获取完结投料满锅重量")
    @PostMapping("/getEndPotWeight")
    public Result<ExistingWeightDto> getWeight(@RequestBody AgainTaskDto taskDto) {
        ExistingWeightDto dto = new ExistingWeightDto();

        FormulaProductScheme productScheme = formulaProductSchemeService.findByEquipmentCodeAndProductModeCode(taskDto.getEquipmentCode(), taskDto.getProductCode());
        FormulaWeightScheme weightScheme = formulaWeightSchemeService.get(productScheme.getDecompositionSchemeId());
        // 设置满锅重量
        if (!CollectionUtils.isEmpty(weightScheme.getAgainFullPotWeight())
                && !ObjectUtils.isEmpty(weightScheme.getAgainFullPotWeight().get("99"))){
            dto.setFullPotWeight(weightScheme.getAgainFullPotWeight().get("99").setScale(0, RoundingMode.UP));
        }else {
            dto.setFullPotWeight(weightScheme.getFullPotWeight().setScale(0, RoundingMode.UP));
        }

        // 剩料重量
        dto.setSurplusWeight(taskDto.getSurplusWeigth());

        return ResultGenerator.success(dto);
    }


    @SuppressWarnings("rawtypes")
    @ApiOperation(value = "确认重量")
    @PostMapping("/confirmWeight")
    public Result confirmWeight(@RequestBody @Valid @ApiParam(value = "复投任务") ConfirmWeightDto dto,
                                BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto.getSplittings().size() == 0) {
            return ResultGenerator.fail("分解方案不能为空");
        }

        if (dto.getId() == null || dto.getId() == 0) {
            return ResultGenerator.fail("请传入任务编号");
        }

        AgainTask task = againTaskService.get(dto.getId());
        if (task == null || !task.getRawStatus().equals(AgainTaskDto.rawStatus_0)) {
            return ResultGenerator.fail("当前任务不可操作");
        }

        // 查询分解方案
        List<ProductionFurnaceMaterialSplit> materialSplitList = splitService.findByLotNoAndAgainNum(task.getLotNo(), task.getAgainNum());
        if (CollectionUtils.isEmpty(materialSplitList)){
            return ResultGenerator.fail("桶分解方案保存失败，请确认重量，重新点击【分解】按钮");
        }

        //如果已存在该炉次号该次复投的未执行的灌料任务则不再生成
        List<AgainTaskDetail> againTaskDetails = againTaskDetailService.findByLotNoAndAgainNumAndStatus(task.getLotNo(), dto.getAgainNum());
        if (againTaskDetails != null && againTaskDetails.size() > 0) {
            return ResultGenerator.fail("已存在该炉次该复投次数的的灌料任务,请勿重复操作！");
        }

        int weightValue = dto.getAgainWeigth().intValue();

        if (weightValue % 10 != 0) {
            return ResultGenerator.fail("重量必须为10的倍数");
        }

        // 检查上次复投产出状态
        if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "QDJJCheckLastTimeOutPut", false)
                && task.getAgainNum() >= 2
                && task.getOutputCrystal() != null && task.getOutputCrystal()){
            // 获取上次投料产出
            Integer lastAgainNum = task.getAgainNum() - 1;
            List<LongCrystal> LastCrystalList = longCrystalService.findByLotNoAndAgainNum(task.getLotNo(), lastAgainNum);
            if (CollectionUtils.isEmpty(LastCrystalList)) {
                return ResultGenerator.fail("上次（第"+lastAgainNum+"次）加料没有晶棒产出，请确认后再进行报料！");
            }
            boolean isConfirmAll = true;
            for (LongCrystal crystal : LastCrystalList) {
                if(crystal.getCrystalStatus() == EnumValuesFactory.CrystalStatus.待确认.getKey()){
                    isConfirmAll = false;
                    break;
                }
            }
            if (!isConfirmAll) {
                return ResultGenerator.fail("上次（第"+lastAgainNum+"次）加料产出的晶棒有未确认状态，请先确认产出！");
            }
        }

        try {
            OutputRecord topByDeviceNo = outputRecordService.findTopByDeviceNo(task.getEquipmentCode());
            if (null != topByDeviceNo) {
                // 产出后未灌料重置
                outputRecordService.delete(topByDeviceNo.getId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //取出产品绑定的重量分配方案
        Integer againNum = dto.getAgainNum();
        Map<Integer, Integer> splitting = dto.getSplittings();

        //人工维护复投次数
        if (!againNum.equals(task.getAgainNum())) {
            task.setAgainNum(againNum);
            againTaskService.saveOrUpdate(task);
        }
        int tongNum = splitting.size();
        //载具数
        int carrierNum = (int) Math.ceil((float) tongNum / 2);
        try {
            againTaskService.createChildTask(task, dto, tongNum, carrierNum);
            return ResultGenerator.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.toString());
        }

    }

    @ApiOperation(value = "重量卡控")
    @PostMapping("/residualWeight")
    public Result residualWeight(@RequestBody @Valid @ApiParam(value = "复投任务") ConfirmWeightDto dto,
                                 BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        //获取坩埚容量
        List<DictionaryItem> board = dictionaryItemService.findByThemeValueAndEnable("capacity", true);
        Map<String, String> collect = board.stream().collect(Collectors.toMap(DictionaryItem::getName, DictionaryItem::getValue));

        BigDecimal bigDecimal = new BigDecimal(0);

        //人工录入的重量
        int weightValue = dto.getAgainWeigth().intValue();
        //剩料重量
        AgainTask task = againTaskService.get(dto.getId());
        BigDecimal surplusWeight = task.getSurplusWeigth();
        //坩埚名称
        String lotNo = task.getLotNo();
        List<LoadingTask> loadingTasks = loadingTaskService.findByLotNo(lotNo);
        if (null != loadingTasks && loadingTasks.size() > 0) {
            LoadingTask loadingTask = loadingTasks.get(0);
            //通过配料任务查询配料明细
            List<BlastFurnaceDetail> blastFurnaceDetailList = blastFurnaceDetailService.getBlastFurnaceDetailList(loadingTask.getId());
            for (BlastFurnaceDetail blastFurnaceDetail : blastFurnaceDetailList) {
                if (null != blastFurnaceDetail.getMaterialName() && collect.containsKey(blastFurnaceDetail.getMaterialName())) {
                    bigDecimal = new BigDecimal(collect.get(blastFurnaceDetail.getMaterialName()));
                }
            }
            if (new BigDecimal(weightValue).add(surplusWeight).compareTo(bigDecimal) > 0) {
                return ResultGenerator.success201("报料重量【" + weightValue + "】剩料重量【" + surplusWeight + "】已超重量安全上限，修改为安全重量信息后点击确认按钮");
            } else {
                return ResultGenerator.success();
            }
        } else {
            return ResultGenerator.fail("未查询到炉次【" + lotNo + "】的坩埚信息");

        }
    }

    @ApiOperation(value = "取消任务")
    @PostMapping("/cancelTask")
    public Result cancelTask(@ApiParam(value = "复投任务") Long id, @ApiParam(value = "取消原因") @RequestParam String cause) {
        try {
            againTaskService.cancelTask(id, cause);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "人工完成任务")
    @PostMapping("/complete")
    public Result completeTask(@RequestBody @Valid @ApiParam(value = "灌料明细对象") List<InputFurnaceDetailDto> inputFurnaceDetailDto, BindingResult bindingResult, @ApiParam(value = "复投任务") Long id) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        AgainTask entity = againTaskService.get(id);
        if (null != entity && entity.getAgainWeigth() == null) {
            return ResultGenerator.fail("未确认复投重量");
        }
        List<AgainTaskDetail> againTaskDetails = againTaskDetailService.findByAgainTaskId(id);
        //保存灌料记录
        InputFurnaceBurden inputFurnaceBurden = againTaskService.saveInputFurnaceBurden(againTaskDetails);
        if (null != inputFurnaceBurden) {
            inputFurnaceBurdenService.saveOrUpdate(inputFurnaceBurden);
        } else {
            return ResultGenerator.fail("灌料任务为空");
        }

        //保存灌料明细
        Result<Object> objectResult = saveDetail(againTaskDetails, inputFurnaceDetailDto);
        if (null == objectResult || objectResult.getMessage().contains("空")) {
            return objectResult;
        }
        entity.setRawStatus(AgainTaskDto.rawStatus_4);
        for (AgainTaskDetail againTaskDetail : againTaskDetails) {
            againTaskDetail.setRawStatus(AgainTaskDto.rawStatus_4);
            againTaskDetailService.saveOrUpdate(againTaskDetail);
        }
        againTaskService.saveOrUpdate(entity);
        return ResultGenerator.success();

    }


    private Result<Object> saveDetail(List<AgainTaskDetail> byAgainTaskId, List<InputFurnaceDetailDto> inputFurnaceDetailDto) {
        byAgainTaskId.sort(Comparator.comparing(AgainTaskDetail::getAgainTaskId));
        //获取灌料任务ID
        Long againTaskDetailId = byAgainTaskId.get(0).getId();
        if (null != inputFurnaceDetailDto && inputFurnaceDetailDto.size() > 0) {
            for (InputFurnaceDetailDto furnaceDetailDto : inputFurnaceDetailDto) {
                if (furnaceDetailDto.getWeight() == null) {
                    return ResultGenerator.fail("重量为空");
                }
                //通过灌料任务ID获取灌料记录ID
                List<InputFurnaceBurden> byAgainTaskDetailId = inputFurnaceBurdenService.findByAgainTaskDetailId(againTaskDetailId);
                if (null != byAgainTaskDetailId && byAgainTaskDetailId.size() > 0) {
                    furnaceDetailDto.setInputFurnaceId(byAgainTaskDetailId.get(0).getId());
                } else {
                    return ResultGenerator.fail("灌料记录为空");
                }
                furnaceDetailDto.setAgainTaskDetailId(againTaskDetailId);
                InputFurnaceDetail inputFurnaceDetail = fromDto1(furnaceDetailDto);
                inputFurnaceDetailService.saveOrUpdate(inputFurnaceDetail);
            }
            return ResultGenerator.success();
        } else {
            return ResultGenerator.fail("灌料明细为空");
        }
    }

    @ApiOperation(value = "删除灌料明细")
    @PostMapping("/deleteDetail")
    public Result deletaDetail(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids, @ApiParam(value = "复投任务") Long id) {
        AgainTask againTask = againTaskService.get(id);
        if (againTask.getRawStatus().equals(AgainTaskDto.rawStatus_3) || againTask.getRawStatus().equals(AgainTaskDto.rawStatus_4)) {
            for (Long id1 : ids) {
                inputFurnaceDetailService.delete(id1);
            }
        } else {
            return ResultGenerator.fail("非完工状态不能删除数据");
        }
        return ResultGenerator.success("删除成功");
    }

    @ApiOperation(value = "新增灌料明细")
    @PostMapping("/addDetail")
    public Result addDetail(@RequestBody @Valid @ApiParam(value = "灌料明细对象") List<InputFurnaceDetailDto> inputFurnaceDetailDto, @ApiParam(value = "复投任务") Long id, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        AgainTask againTask = againTaskService.get(id);
        if (againTask.getRawStatus().equals(AgainTaskDto.rawStatus_3) || againTask.getRawStatus().equals(AgainTaskDto.rawStatus_4)) {
            //根据复投任务ID查询灌料任务
            List<AgainTaskDetail> byAgainTaskId = againTaskDetailService.findByAgainTaskId(id);
            if (null != byAgainTaskId && byAgainTaskId.size() > 0) {
                Result<Object> objectResult = saveDetail(byAgainTaskId, inputFurnaceDetailDto);
                if (null == objectResult) {
                    return objectResult;
                }
            }
//            InputFurnaceDetail inputFurnaceDetail = fromDto1(inputFurnaceDetailDto);
//            inputFurnaceDetailService.saveOrUpdate(inputFurnaceDetail);
        } else {
            return ResultGenerator.fail("非完工状态不能新增数据");
        }
        return ResultGenerator.success("操作成功");
    }

    @ApiOperation(value = "根据复投任务Id查询所有灌料明细")
    @GetMapping("/getByTaskId")
    public Result<List<InputFurnaceDetailDto>> getByTaskId(@ApiParam(value = "复投任务ID") Long againTaskId) {
        List<InputFurnaceDetail> inputFurnaceDetails = new ArrayList<>();
        //通过复投任务ID查询灌料任务
        List<AgainTaskDetail> againTaskDetailList = againTaskDetailService.findByAgainTaskId(againTaskId);
        if (null != againTaskDetailList && againTaskDetailList.size() > 0) {
            for (AgainTaskDetail againTaskDetail : againTaskDetailList) {
                Long id = againTaskDetail.getId();
                //通过灌料任务ID查询灌料明细
                List<InputFurnaceDetail> inputFurnaceDetail = inputFurnaceDetailService.findByAgainTaskDetailId(id);
                inputFurnaceDetails.addAll(inputFurnaceDetail);
            }
        }
        List<InputFurnaceDetailDto> inputFurnaceDetailDtos = inputFurnaceDetails.stream()
                .map(inputFurnaceDetail -> toLazyDto1(inputFurnaceDetail))
                .collect(Collectors.toList());
        return ResultGenerator.success(inputFurnaceDetailDtos);
    }


    @SuppressWarnings("rawtypes")
    @ApiOperation(value = "重新叫料任务")
    @PostMapping("/repeatOpen")
    public Result repeatOpenTask(@ApiParam(value = "任务ID") @RequestParam Long id) {
        try {
            againTaskService.repeatOpenTask(id);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();

    }

    @ApiOperation(value = "计算复投重量")
    @PostMapping("/calculateWeight")
    public Result calculateWeight(@ApiParam(value = "总装埚料") String total, @ApiParam(value = "剩余重量") String surplus) {
        try {
            double totalDouble = Double.parseDouble(total);
            double surplusDouble = Double.parseDouble(surplus);

            double _tempNum = (totalDouble - surplusDouble) / 10;

            int weightValue = (int) Math.ceil(_tempNum) * 10;

            return ResultGenerator.success(weightValue);
        } catch (Exception e) {
            return ResultGenerator.success(0);
        }
    }

    @ApiOperation(value = "获取桶数分解方案")
    @PostMapping("/getSplitInfo")
    public Result getSplitInfo(@ApiParam(value = "任务Id AgainTask.id") Long taskId,
                               @ApiParam(value = "重量") String weight,
                               @ApiParam(value = "复投次数") Integer againNum,
                               @ApiParam(value = "完结加料（0：否，1：是）") Integer isFillEnd) {
        if (StringUtils.isBlank(weight)) {
            return ResultGenerator.fail("请输入总重量");
        }

        if (!NumberUtil.isNumeric(weight)) {
            return ResultGenerator.fail("重量必须为数字");
        }

        if (taskId == null || taskId == 0) {
            return ResultGenerator.fail("请传入任务编号");
        }

        if (againNum == null) {
            return ResultGenerator.fail("请输入复投次数");
        }

        AgainTask task = againTaskService.get(taskId);
        if (task == null || !task.getRawStatus().equals(AgainTaskDto.rawStatus_0)) {
            return ResultGenerator.fail("当前任务不可操作");
        }

        int weightValue = NumberUtil.String2Integer(weight, 0);

        if (weightValue % 10 != 0) {
            return ResultGenerator.fail("重量必须为10的倍数");
        }

        Map<Integer, Integer> splittings = new LinkedHashMap<Integer, Integer>();

        // 获取桶分解方案
        DecompositionSchemeParam decompositionSchemeParam = new DecompositionSchemeParam();
        decompositionSchemeParam.setEquipmentCode(task.getEquipmentCode());
        decompositionSchemeParam.setProductModeCode(task.getProductCode());
        decompositionSchemeParam.setWeight(new BigDecimal(weight));
        decompositionSchemeParam.setType(1);
        decompositionSchemeParam.setRepeatTimes(againNum);
        decompositionSchemeParam.setIsFillEnd(isFillEnd);
        FormulaSchemeData formulaSchemeData;
        try {
            formulaSchemeData = formulaSchemeOutService.decompositionScheme(decompositionSchemeParam);
        }catch (Exception e){
            log.error("复投获取桶数分解方案：", e);
            return ResultGenerator.fail(e.getMessage());
        }
        if (ObjectUtils.isEmpty(formulaSchemeData)) {
            return ResultGenerator.fail("未获取到桶分解数据！");
        }
        for (FormulaSchemeData.FormulaSchemeDataDetail schemeData : formulaSchemeData.getDetail()) {
            splittings.put(schemeData.getIndex(), schemeData.getWeight().intValue());
        }

        // 保存桶分解数据
        List<ProductionFurnaceMaterialSplit> splitList = new ArrayList<>();
        for (FormulaSchemeData.FormulaSchemeDataDetail schemeData : formulaSchemeData.getDetail()) {
            for (FormulaSchemeData.LoadingDetail detail : schemeData.getLoadingDetails()) {
                ProductionFurnaceMaterialSplit split = new ProductionFurnaceMaterialSplit();
                split.setEquipmentCode(task.getEquipmentCode());
                split.setLotNo(task.getLotNo());
                split.setRawType(task.getRawType());
                split.setAgainNum(againNum);
                split.setProductCode(task.getProductCode());
                split.setTaskId(task.getId());
                split.setSplitInfo(formulaSchemeData, schemeData, detail);
                splitList.add(split);
            }
        }

        // 更新桶分解记录数据
        splitService.deleteByTaskIdAndAgainNum(task.getId(), againNum);
        splitService.saveAll(splitList);

        // 复投任务关联配方方案和重量方案
        task.setRecipeId(formulaSchemeData.getSchemeId());
        task.setWeigthId(formulaSchemeData.getWeightSchemeId());
        againTaskService.saveOrUpdate(task);

        return ResultGenerator.success(splittings);
    }

    private Map<Integer, Integer> drumDismantling(ProductionCircleWeightDetail productionCircleWeightDetail, Map<Integer, Integer> splittings) {

        int i = 1;
        if (null != productionCircleWeightDetail.getFirstBarrel() && productionCircleWeightDetail.getFirstBarrel() > 0) {
            splittings.put(i, productionCircleWeightDetail.getFirstBarrel());
            i++;
        }
        if (null != productionCircleWeightDetail.getSecondBarrel() && productionCircleWeightDetail.getSecondBarrel() > 0) {
            splittings.put(i, productionCircleWeightDetail.getSecondBarrel());
            i++;
        }
        if (null != productionCircleWeightDetail.getThirdBarrel() && productionCircleWeightDetail.getThirdBarrel() > 0) {
            splittings.put(i, productionCircleWeightDetail.getThirdBarrel());
            i++;
        }
        if (null != productionCircleWeightDetail.getFourthBarrel() && productionCircleWeightDetail.getFourthBarrel() > 0) {
            splittings.put(i, productionCircleWeightDetail.getFourthBarrel());
            i++;
        }
        if (null != productionCircleWeightDetail.getFifthBarrel() && productionCircleWeightDetail.getFifthBarrel() > 0) {
            splittings.put(i, productionCircleWeightDetail.getFifthBarrel());
            i++;
        }
        if (null != productionCircleWeightDetail.getSixBarrel() && productionCircleWeightDetail.getSixBarrel() > 0) {
            splittings.put(i, productionCircleWeightDetail.getSixBarrel());
            i++;
        }
        if (null != productionCircleWeightDetail.getSeventhBarrel() && productionCircleWeightDetail.getSeventhBarrel() > 0) {
            splittings.put(i, productionCircleWeightDetail.getSeventhBarrel());
            i++;
        }
        if (null != productionCircleWeightDetail.getEightBarrel() && productionCircleWeightDetail.getEightBarrel() > 0) {
            splittings.put(i, productionCircleWeightDetail.getEightBarrel());
        }

        return splittings;
    }


    @ApiOperation(value = "根据设备号查询炉次号")
    @GetMapping("/getLotno")
    public Result<String> getLotno(@ApiParam(value = "设备号") String equipmentCode) {
        Equipment equipment = equipmentService.findByCode(equipmentCode);
        if (equipment == null) {
            return ResultGenerator.fail("设备号不存在");
        }
        PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByEquipmentIdAndOrderTypeAndStatus(equipment.getId(), EnumValuesFactory.PlanProcessingOrderOrderType.炉次.getKey(), EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey());
        if (planProcessingOrder != null) {
            String code = planProcessingOrder.getCode();
            return ResultGenerator.success(code);
        } else {
            return ResultGenerator.fail(equipmentCode + "设备没有正在运行的炉次");
        }
    }


    @ApiOperation(value = "根据炉次号查询设备号")
    @GetMapping("/getEquipmentCode")
    public Result<String> getEquipmentCode(@ApiParam(value = "炉次号") String code) {
        PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCodeAndOrderTypeAndStatus(code, EnumValuesFactory.PlanProcessingOrderOrderType.炉次.getKey(), EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey());
        if (planProcessingOrder != null) {
            String equipmentCode = planProcessingOrder.getEquipmentCode();
            return ResultGenerator.success(equipmentCode);
        } else {
            return ResultGenerator.fail("炉次号不存在");
        }
    }


    @ApiOperation(value = "获取所有复投任务")
    @GetMapping("/listAll")
    public Result<List<AgainTaskDto>> listAll(ServletRequest request) {
        Specification<AgainTask> specification = DynamicSpecifications.bySearchFilter(request, AgainTask.class);
        List<AgainTask> againTasks = againTaskService.findByExampleSort(specification, null);
        List<AgainTaskDto> againTaskDtos = againTasks.stream().map(againTask -> toLazyDto(againTask))
                .collect(Collectors.toList());
        return ResultGenerator.success(againTaskDtos);
    }

    @ApiOperation(value = "复投任务详细信息")
    @GetMapping("/{id}")
    public Result<AgainTaskDto> get(@PathVariable @ApiParam(value = "复投任务id") Long id) {
        AgainTask againTask = againTaskService.get(id);
        if (null == againTask) {
            return ResultGenerator.fail("该复投任务不存在");
        }
        return ResultGenerator.success(toEagerDto(againTask));
    }

    @ApiOperation(value = "创建复投任务")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "复投任务对象") AgainTaskDto againTaskDto,
                         BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        AgainTask againTask = fromDto(againTaskDto);
        againTaskService.saveOrUpdate(againTask);

        return ResultGenerator.success();
    }

    @ApiOperation(value = "更新复投任务")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "复投任务") AgainTaskDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
        AgainTask entity = againTaskService.get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        try {
            AgainTask entityfromFto = fromDto(dto);
            BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
            againTaskService.saveOrUpdate(entity);

            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "删除复投任务")
    @PostMapping("/delete")
    public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids) {
        for (Long id : ids) {
            againTaskService.delete(id);
        }
        return ResultGenerator.success();
    }


    @ApiOperation(value = "根据炉次号查询最新已完成复投任务")
    @GetMapping("/getLastCompleteTask")
    public Result<Integer> getLastCompleteTask(@ApiParam(value = "设备号") String equipmentCode) {
        AgainTask task = againTaskService.findCompletedTopByEquipmentCode(equipmentCode);
        if (ObjectUtils.isEmpty(task)){
            return ResultGenerator.fail("当前炉次号未查询到最新完成的复投任务");
        }
        return ResultGenerator.success(task.getAgainNum());
    }


//    @ApiOperation(value = "提前开启灌料任务(测试用)")
//    @GetMapping("/glTask")
//    public Result<AgainTaskDetailDto> get(@ApiParam(value = "炉次号") String lotno, @ApiParam(value = "灌料任务ID") Long id) {
//        try {
//            delayStartService.glTask(lotno, id);
//            return ResultGenerator.success();
//        }catch (Exception e) {
//            return ResultGenerator.fail(e.getMessage());
//        }
//    }

    public AgainTaskDto toLazyDto(AgainTask entity) {
        return modelMapper.map(entity, AgainTaskDto.class);
    }

    public InputFurnaceDetailDto toLazyDto1(InputFurnaceDetail entity) {
        return modelMapper.map(entity, InputFurnaceDetailDto.class);
    }

    public AgainTaskDto toEagerDto(AgainTask entity) {
        AgainTaskDto dto = modelMapper.map(entity, AgainTaskDto.class);
        return dto;
    }

    public AgainTask fromDto(AgainTaskDto dto) {
        return modelMapper.map(dto, AgainTask.class);
    }

    private List<DictionaryItem> getDicItems(String themeValue) {
        return dictionaryItemService.findByThemeValueAndEnable(themeValue, true);
    }

    public InputFurnaceDetail fromDto1(InputFurnaceDetailDto dto) {
        return modelMapper.map(dto, InputFurnaceDetail.class);
    }


    private List<Integer> convertIntArrToList(Object[] arrs) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < arrs.length; i++) {
            list.add(Integer.valueOf(arrs[i].toString()));
        }
        return list;
    }


}
