package com.aps.service.Algorithm;

import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.*;
import com.aps.entity.Algorithm.*;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.Algorithm.IDAndChildID.NodeInfo;
import com.aps.entity.basic.*;
import com.aps.service.plan.MachineSchedulerService;
import com.aps.service.plan.PlanResultService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.ScopeMetadata;

import javax.xml.transform.Result;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 作者：佟礼
 * 时间：2025-11-30
 */
public class ScheduleOperationService {

    private MaterialRequirementService materialRequirementService;

    private PlanResultService planResultService;


    public ScheduleOperationService(MaterialRequirementService _materialRequirementService,PlanResultService _planResultService) {
        materialRequirementService=_materialRequirementService;
        planResultService=_planResultService;
    }

    /**
     * 移动工序方法
     * @param chromosome 染色体对象
     * @param opIds 工序ID
     * @param targetopId 目标工序ID
     * @param isfront 目标工序ID的前面
     * @param newMachineId 新设备ID
     */
    public void dragOperation(Chromosome chromosome, List<Integer> opIds, int targetopId,Boolean isfront,
                              Long newMachineId, GlobalParam globalParam) {
        List<Entry> allOperations = chromosome.getAllOperations();

int newStartTime=0;

        List<Integer> ordersIds=new ArrayList<>();
        List<Integer> opsIndexs=new ArrayList<>();
        Map<Integer, Integer> opTimeMap = chromosome.getResult().stream()
                .collect(Collectors.toMap(
                        GAScheduleResult::getOperationId,
                        r ->  r.getStartTime()
                ));
        List<OperationSort> opGroupMap =  allOperations.stream()
                .map(data -> new OperationSort(data.getId(), 0,data.getGroupId(),data.getSequence())) // 再提取字段
                .collect(Collectors.toList());

        Integer newMachineId1=newMachineId.intValue();
        CopyOnWriteArrayList<Integer> OperationSequencing=  chromosome.getOperationSequencing();
        GAScheduleResult targetResult1=null;
        Entry targetOp1=null;
        int targetopIndex1=0;
        if(targetopId!=0) {
            targetResult1 = chromosome.getResult().stream()
                    .filter(r -> r.getOperationId() == targetopId)
                    .findFirst()
                    .orElseThrow(() -> new NoSuchElementException("Operation not found: " + targetopId));
             targetOp1 = allOperations.stream()
                    .filter(o -> o.getId() == targetopId)
                    .findFirst()
                    .orElseThrow(() -> new NoSuchElementException("Operation not found: " + targetopId));
         int GroupId=targetOp1.getGroupId();
            OptionalInt OperationIndex = IntStream.range(0, OperationSequencing.size())
                    .filter(i -> OperationSequencing.get(i).equals(GroupId)) // 过滤出值为1的索引
                    .skip(targetOp1.getSequence()-1) // 跳过第一个匹配项
                    .findFirst(); // 取第二个匹配项
            targetopIndex1=OperationIndex.getAsInt();
            if(isfront)
            {
                newStartTime=targetResult1.getStartTime();
            }else {

                newStartTime=targetResult1.getEndTime();
            }
        }

        for (Integer opId:opIds) {


                // 获取目标结果和工序
            GAScheduleResult targetResult = chromosome.getResult().stream()
                    .filter(r -> r.getOperationId() == opId)
                    .findFirst()
                    .orElseThrow(() -> new NoSuchElementException("Operation not found: " + targetopId));

            Entry targetOp = allOperations.stream()
                        .filter(o -> o.getId() == opId)
                        .findFirst()
                        .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
                if (targetOp.getSequence() > 1) {
                    Entry targetOp2 = allOperations.stream()
                            .filter(o -> o.getGroupId() == targetOp.getGroupId()
                                    && o.getSequence() == targetOp.getSequence() - 1)
                            .findFirst()
                            .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
                    GAScheduleResult targetResult2 = chromosome.getResult().stream()
                            .filter(r -> r.getOperationId() == targetOp2.getId())
                            .findFirst()
                            .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
                    if (targetResult2.getEndTime() > newStartTime) {
                        throw new RuntimeException("不能早于前一工序的结束时间");
                    }
                }



            if(targetopId!=0) {
                OptionalInt OperationIndex = IntStream.range(0, OperationSequencing.size())
                        .filter(i -> OperationSequencing.get(i).equals(targetOp.getGroupId())) // 过滤出值为1的索引
                        .skip(targetOp.getSequence() - 1) // 跳过第一个匹配项
                        .findFirst(); // 取第二个匹配项
                int targetOpIndex = OperationIndex.getAsInt();
                opsIndexs.add(targetOpIndex);
                ordersIds.add(targetOp.getGroupId());
                List<Entry> targetOp2s = allOperations.stream()
                        .filter(o -> o.getGroupId() == targetOp.getGroupId()
                                && o.getSequence() > targetOp.getSequence()).collect(Collectors.toList());

                if(targetOp2s!=null&&targetOp2s.size()>0)
                {
                    for (Entry targetOp4:targetOp2s) {
                        OptionalInt OperationIndex1 = IntStream.range(0, OperationSequencing.size())
                                .filter(i -> OperationSequencing.get(i).equals(targetOp.getGroupId())) // 过滤出值为1的索引
                                .skip(targetOp4.getSequence() - 1) // 跳过第一个匹配项
                                .findFirst(); // 取第二个匹配项
                        int targetOpIndex2 = OperationIndex1.getAsInt();
                        if(targetOpIndex2<targetopIndex1)//后面的工序位置比目标位置靠前
                        {//后面的工序也要往后挪
                            opsIndexs.add(targetOpIndex2);
                            ordersIds.add(targetOp.getGroupId());
                        }
                    }
                }

            }



            if(newMachineId1!=0) {
                int machineOptionIndex = targetOp.getMachineOptions().stream()
                        .map(MachineOption::getMachineId)
                        .collect(Collectors.toList())
                        .indexOf(newMachineId) + 1;

                if (machineOptionIndex == 0) {
                    throw new NoSuchElementException("Machine not found: " + newMachineId);
                }


                // 更新设备选择序列
                int globalOpIndex = chromosome.getGlobalOpList().stream()
                        .filter(g -> g.getOp().getId() == opId)
                        .findFirst()
                        .map(GlobalOperationInfo::getGlobalOpId)
                        .orElseThrow(() -> new NoSuchElementException("Global operation not found: " + opId));


                chromosome.getMachineSelection().set(globalOpIndex, machineOptionIndex);
                targetResult.setForcedMachineId(newMachineId);


            }else {
                newMachineId1=(int)targetResult.getMachineId();
            }
        }
        if(targetopId!=0) {
            opsIndexs.sort(Comparator.reverseOrder());
            for (int i = 0; i < opsIndexs.size(); i++) {
                Integer in = opsIndexs.get(i);
                // 安全校验：防止索引越界
                if (in >= 0 && in < OperationSequencing.size()) {
                    OperationSequencing.remove((int)in);
                }
            }

            int GroupId=targetOp1.getGroupId();
             OptionalInt OperationIndex = IntStream.range(0, OperationSequencing.size())
                    .filter(i -> OperationSequencing.get(i).equals(GroupId)) // 过滤出值为1的索引
                    .skip(targetOp1.getSequence()-1) // 跳过第一个匹配项
                    .findFirst(); // 取第二个匹配项
            int targetOpIndex= OperationIndex.getAsInt();
            if(!isfront)
            {
                targetOpIndex+=1;
            }
            for (Integer orderid:ordersIds) {
                OperationSequencing.add(targetOpIndex, orderid);
                targetOpIndex++;
            }
        }



        chromosome.setOperationSequencing(OperationSequencing);
// 重新解码
        redecode(chromosome, chromosome.getBaseTime(), globalParam);


    }

    /**
     * 移动工序方法
     * @param chromosome 染色体对象
     * @param opIds 工序ID
     * @param newStartTime 新开始时间
     * @param newMachineId 新设备ID
     */
    public void moveOperation(Chromosome chromosome, List<Integer> opIds, int newStartTime,
                              Long newMachineId, GlobalParam globalParam,int lockStartTime) {
        List<Entry> allOperations = chromosome.getAllOperations();

        for (Integer opId:opIds) {
            GAScheduleResult targetResults = chromosome.getResult().stream()
                    .filter(r -> r.getOperationId() == opId).findFirst()
                    .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));

            targetResults.setLockStartTime(1);
            targetResults.setDesignatedStartTime(newStartTime);
            Entry targetOp = allOperations.stream()
                    .filter(o -> o.getId() == opId)
                    .findFirst()
                    .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));

            targetOp.setDesignatedStartTime(chromosome.getBaseTime().plusSeconds(newStartTime));
        }
        redecode(chromosome, chromosome.getBaseTime(), globalParam);
    }


        /**
         * 移动工序方法
         * @param chromosome 染色体对象
         * @param opIds 工序ID
         * @param newStartTime 新开始时间
         * @param newMachineId 新设备ID
         */
    public void moveOperation1(Chromosome chromosome, List<Integer> opIds, int newStartTime,
                              Long newMachineId, GlobalParam globalParam,int lockStartTime) {
        List<Entry> allOperations = chromosome.getAllOperations();
int newStartTime1=newStartTime;



        Map<Integer, Integer> opTimeMap = chromosome.getResult().stream()
                .collect(Collectors.toMap(
                        GAScheduleResult::getOperationId,
                        r ->  r.getStartTime()
                ));
        List<OperationSort> opGroupMap =  allOperations.stream()
                .map(data -> new OperationSort(data.getId(), 0,data.getGroupId(),data.getSequence())) // 再提取字段
                .collect(Collectors.toList());

Integer newMachineId1=newMachineId.intValue();
        for (Integer opId:opIds) {


            // 获取目标结果和工序
            GAScheduleResult targetResult = chromosome.getResult().stream()
                    .filter(r -> r.getOperationId() == opId)
                    .findFirst()
                    .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));

            Entry targetOp = allOperations.stream()
                    .filter(o -> o.getId() == opId)
                    .findFirst()
                    .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
if(targetOp.getSequence()>1) {
    Entry targetOp1 = allOperations.stream()
            .filter(o -> o.getGroupId() == targetOp.getGroupId()
                    && o.getSequence() == targetOp.getSequence() - 1)
            .findFirst()
            .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
    GAScheduleResult targetResult1 = chromosome.getResult().stream()
            .filter(r -> r.getOperationId() == targetOp1.getId())
            .findFirst()
            .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
    if (targetResult1.getEndTime() < newStartTime)
    {
        throw new RuntimeException("不能早于前一工序的结束时间");
    }
}

            if(newMachineId1!=0) {
                int machineOptionIndex = targetOp.getMachineOptions().stream()
                        .map(MachineOption::getMachineId)
                        .collect(Collectors.toList())
                        .indexOf(newMachineId) + 1;

                if (machineOptionIndex == 0) {
                    throw new NoSuchElementException("Machine not found: " + newMachineId);
                }


                // 更新设备选择序列
                int globalOpIndex = chromosome.getGlobalOpList().stream()
                        .filter(g -> g.getOp().getId() == opId)
                        .findFirst()
                        .map(GlobalOperationInfo::getGlobalOpId)
                        .orElseThrow(() -> new NoSuchElementException("Global operation not found: " + opId));


                chromosome.getMachineSelection().set(globalOpIndex, machineOptionIndex);
                targetResult.setForcedMachineId(newMachineId);
            }else {
                newMachineId1=(int)targetResult.getMachineId();
            }
            // 设置约束
            targetResult.setDesignatedStartTime(newStartTime);
            targetResult.setLockStartTime(lockStartTime);
            targetOp.setDesignatedStartTime(chromosome.getBaseTime().plusSeconds(newStartTime));


//            if(targetOp.getSequence()==1) {
//                opTimeMap.put(opId, newStartTime);
//            }else {
//                Entry targetOp1 = allOperations.stream()
//                        .filter(o -> o.getGroupId() == targetOp.getGroupId()
//                                &&o.getSequence()==targetOp.getSequence()-1)
//                        .findFirst()
//                        .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
//                GAScheduleResult targetResult1 = chromosome.getResult().stream()
//                        .filter(r -> r.getOperationId() == targetOp1.getId())
//                        .findFirst()
//                        .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));
//                if(targetResult1.getStartTime()<newStartTime)
//                {
//                    opTimeMap.put(opId, newStartTime);
//                }else {
//                    opTimeMap.put(opId, targetResult1.getStartTime()+1);
//                }
//            }
            newStartTime=newStartTime+1;
        }


        Long newMachineId2=newMachineId1.longValue();
            GAScheduleResult FirstMachineResult = chromosome.getResult().stream()
                    .filter(r -> r.getMachineId() ==newMachineId2 && r.getStartTime() >= newStartTime1)
                    .findFirst()
                    .orElse(null);
            if (FirstMachineResult != null) {
                if(opTimeMap.get(FirstMachineResult.getOperationId())<newStartTime)
                {
                    opTimeMap.put(FirstMachineResult.getOperationId(), newStartTime);
                }

            }

        // 生成新的工序顺序





        opGroupMap.forEach(t -> {
            Integer time = opTimeMap.get(t.getId());
            t.setTime(time != null ? time : 0); // 如果映射中没有该ID的时间，则默认设为0
        });

        opGroupMap = opGroupMap.stream()
                .sorted(Comparator.comparingLong(OperationSort::getTime))
                .collect(Collectors.toList());

        opGroupMap = opGroupMap.stream()
                .sorted((op1, op2) -> {
                        return Integer.compare(op2.getTime(), op1.getTime());
                })
                .collect(Collectors.toList());

        Map<Integer, Integer> groupMap=new HashMap<>();
        Map<Integer, Integer> opidMap=new HashMap<>();
        Map<Integer, OperationSort> outtimeMap=new HashMap<>();
        List<OperationSort> newops=new ArrayList<>();
        for (OperationSort op:opGroupMap) {
            if(groupMap.containsKey(op.getGroup()))
            {
                if(groupMap.get(op.getGroup())<=op.getSequence())
                {
                    outtimeMap.put(op.getId(),op);
                }else {
                    opidMap.put(op.getGroup(),op.getSequence());
                    newops.add(op);
                }
            }else {
                groupMap.put(op.getGroup(),op.getSequence());
                opidMap.put(op.getGroup(),op.getId());
                newops.add(op);
            }
        }
        for (OperationSort op:outtimeMap.values()) {


           int opid=(int) opidMap.get(op.getGroup());

            OptionalInt index = IntStream.range(0, newops.size())
                    .filter(j -> opid==newops.get(j).getId())
                    .findFirst();
            int opSeq =index.orElse(0) ;
            newops.add(opSeq,op);
            opidMap.put(op.getGroup(),op.getId());

        }

        CopyOnWriteArrayList<Integer> operationSequencing = newops.stream()
                .map(OperationSort::getGroup)
                .collect(Collectors.toCollection(CopyOnWriteArrayList::new));
        Collections.reverse(operationSequencing);

        chromosome.setOperationSequencing(operationSequencing);
// 重新解码
        redecode(chromosome, chromosome.getBaseTime(), globalParam);


    }

    public void UnlockStartTime(Chromosome chromosome, int opId) {
        GAScheduleResult targetResults = chromosome.getResult().stream()
                .filter(r ->r.getOperationId() == opId).findFirst()
                .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));

        targetResults.setLockStartTime(0);
        targetResults.setDesignatedStartTime(0);
    }

        /**
         * 增加设备维修保养
         * @param chromosome 染色体对象

         */
    public void AddMaintenanceWindow(Chromosome chromosome,Long machineId, MaintenanceWindow maintenanceWindow,
                               GlobalParam globalParam) {

       Machine machine= chromosome.getInitMachines().stream().filter(t->t.getId()==machineId)
                .findFirst().orElse(null);
       if(machine!=null)
       {
           // 检查时间是否与现有维护窗口重复
           if (isTimeOverlap(machine.getMaintenanceWindows(), maintenanceWindow)) {
               throw new RuntimeException("维修时间已存在");
           }

           maintenanceWindow.setEquipCode(machine.getCode());
           maintenanceWindow.setEquipName(machine.getName());

           maintenanceWindow.setId(UUID.randomUUID().toString());

           machine.getMaintenanceWindows().add(maintenanceWindow);

           MachineSchedulerService machineScheduler = new MachineSchedulerService(
                   chromosome.getBaseTime());

           machineScheduler.ClearMachineCache(machineId);
           MachineTimeline machineTimeline = machineScheduler.getOrCreateTimeline(machine);
           machine.setAvailability(machineTimeline.getSegments());
       }else {

           throw new RuntimeException("未找到设备");
       }

        redecode(chromosome, chromosome.getBaseTime(), globalParam);

    }

    /**
     * 检查新维护窗口是否与现有维护窗口时间重叠
     * @param existingWindows 现有维护窗口列表
     * @param newWindow 新维护窗口
     * @return 如果时间重叠返回true，否则返回false
     */
    private boolean isTimeOverlap(List<MaintenanceWindow> existingWindows, MaintenanceWindow newWindow) {
        if (existingWindows == null || existingWindows.isEmpty()) {
            return false;
        }

        for (MaintenanceWindow existingWindow : existingWindows) {
            // 检查时间是否重叠：新窗口开始时间 < 现有窗口结束时间 && 新窗口结束时间 > 现有窗口开始时间
            if (newWindow.getStartTime().isEqual(existingWindow.getEndTime()) &&
                newWindow.getEndTime().isEqual(existingWindow.getStartTime())) {
                return true;
            }
        }
        return false;
    }

    public List<MaintenanceWindow> GetMaintenanceWindow(Chromosome chromosome,Long machineId) {

        if(machineId==0)
        {
            return chromosome.getMachines().stream()
                    // 过滤掉null的机器对象
                    .filter(machine -> machine != null)
                    // 过滤掉维护窗口为null的机器（避免后续空指针）
                    .filter(machine -> machine.getMaintenanceWindows() != null)
                    // 提取维护窗口列表（此时流是 Stream<List<MaintenanceWindow>>）
                    .map(Machine::getMaintenanceWindows)
                    // 扁平化为 Stream<MaintenanceWindow>（核心：将嵌套列表“拍平”）
                    .flatMap(List::stream)
                    // 收集为最终的List结果
                    .collect(Collectors.toList());
        }

        Machine machine= chromosome.getMachines().stream().filter(t->t.getId()==machineId)
                .findFirst().orElse(null);
        if(machine!=null)
        {
           return machine.getMaintenanceWindows();
        }else {

            throw new RuntimeException("未找到设备");
        }
    }

    public void DelMaintenanceWindow(Chromosome chromosome,Long machineId,String maintenanceId,GlobalParam globalParam) {

        Machine machine= chromosome.getInitMachines().stream().filter(t->t.getId()==machineId)
                .findFirst().orElse(null);
        if(machine!=null)
        {
            List<MaintenanceWindow> maintenanceWindows= machine.getMaintenanceWindows();
            OptionalInt index = IntStream.range(0, maintenanceWindows.size())
                    .filter(i -> maintenanceId.equals(maintenanceWindows.get(i).getId()))
                    .findFirst();

            if (index.isPresent()) {
                machine.getMaintenanceWindows().remove((int)index.getAsInt());
                MachineSchedulerService machineScheduler = new MachineSchedulerService(
                        chromosome.getBaseTime());
                machineScheduler.ClearMachineCache(machineId);
                MachineTimeline machineTimeline = machineScheduler.getOrCreateTimeline(machine);
                machine.setAvailability(machineTimeline.getSegments());
            } else {
                throw new RuntimeException("未找到维护窗口");
            }

        }else {

            throw new RuntimeException("未找到设备");
        }

        redecode(chromosome, chromosome.getBaseTime(), globalParam);

    }

    /**
     * 批量删除维护窗口
     * @param chromosome 染色体对象
     * @param machineId 机器ID
     * @param maintenanceIds 要删除的维护窗口ID列表
     * @param globalParam 全局参数
     */
    public void DelMaintenanceWindowBatch(Chromosome chromosome, Long machineId, List<String> maintenanceIds, GlobalParam globalParam) {
        Machine machine = chromosome.getInitMachines().stream().filter(t -> t.getId() == machineId)
                .findFirst().orElse(null);
        if (machine != null) {
            List<MaintenanceWindow> maintenanceWindows = machine.getMaintenanceWindows();
            if (maintenanceWindows != null && maintenanceIds != null && !maintenanceIds.isEmpty()) {
                // 过滤出存在的维护窗口ID
                List<String> existingIds = maintenanceIds.stream()
                        .filter(id -> maintenanceWindows.stream().anyMatch(window -> id.equals(window.getId())))
                        .collect(Collectors.toList());
                
                if (existingIds.size() != maintenanceIds.size()) {
                    throw new RuntimeException("部分维护窗口未找到");
                }
                
                // 根据ID批量删除维护窗口
                maintenanceWindows.removeIf(window -> maintenanceIds.contains(window.getId()));
                
                MachineSchedulerService machineScheduler = new MachineSchedulerService(
                        chromosome.getBaseTime());
                MachineTimeline machineTimeline = machineScheduler.getOrCreateTimeline(machine);
                machine.setAvailability(machineTimeline.getSegments());
            }
        } else {
            throw new RuntimeException("未找到设备");
        }

        redecode(chromosome, chromosome.getBaseTime(), globalParam);
    }

        public void SpiltOperation(Chromosome chromosome, int opId,Double[] splitCounts, GlobalParam globalParam)
    {
        List<Entry> allOperations = chromosome.getAllOperations();

        List<GroupResult> OperatRels = chromosome.getOperatRel();

        Entry targetOp = allOperations.stream()
                .filter(o -> o.getId() == opId)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));

        GAScheduleResult targetSr = chromosome.getResult().stream()
                .filter(o -> o.getOperationId() == opId)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));

        // 找到原来的组和父子级
        GroupResult groupResult = OperatRels.get(targetOp.getGroupId()-1);
        List<NodeInfo> nodeInfoList = groupResult.getNodeInfoList();

        NodeInfo Oprel = nodeInfoList.stream()
                .filter(o -> o.getGlobalSerial() == opId)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));


        int targetGroupIndex = targetOp.getGroupId() - 1;
        List<Integer> newParentIds = Oprel.getNewParentIds();
        List<Integer> newChildIds = Oprel.getNewChildIds();
        //记录新的工序ID和数量
        Map<String,Double> newids=new HashMap<>();
        String MainId = UUID.randomUUID().toString().replace("-", "");

        for (int i=0;i<splitCounts.length;i++) {

            String newId = UUID.randomUUID().toString().replace("-", "");
            if (i == 0) {
                newids.put(targetOp.getExecId(), splitCounts[i]);
            } else {
                newids.put(newId, splitCounts[i]);
                // 添加新节点
                OperatRels = IdGroupingWithDualSerial.addNode(OperatRels, targetGroupIndex, newId, newParentIds, newChildIds,targetOp.getExecId());
            }
         }
        chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels) );
        //当前组的
         groupResult = OperatRels.get(targetGroupIndex);

         nodeInfoList = groupResult.getNodeInfoList();
         //全局ID
        int globalOpId = chromosome.getGlobalOpList().stream()
                .mapToInt(GlobalOperationInfo::getGlobalOpId)
                .max()
                .orElse(0)+1;

        //找到原工序用的设备序号
        List<MachineOption> optionalMachines = targetOp.getMachineOptions();
        OptionalInt index = IntStream.range(0, optionalMachines.size())
                .filter(i -> targetSr.getMachineId()==optionalMachines.get(i).getMachineId())
                .findFirst();
        int machineSeq =index.orElse(0)+1 ;
        List<Integer> OperationSequencing=  chromosome.getOperationSequencing();
        OptionalInt OperationIndex = IntStream.range(0, OperationSequencing.size())
                .filter(i -> OperationSequencing.get(i).equals(targetOp.getGroupId())) // 过滤出值为1的索引
                .skip(targetOp.getSequence()-1) // 跳过第一个匹配项
                .findFirst(); // 取第二个匹配项
       int targetOpIndex= OperationIndex.getAsInt()+1;
        for (NodeInfo nodeInfo : nodeInfoList) {
            Entry entry = allOperations.stream()
                    .filter(o -> o.getId() == nodeInfo.getGlobalSerial())
                    .findFirst()
                    .orElse(null);
            if(entry!=null)
            {
                //存在则修改顺和前后序
                entry.setSequence(nodeInfo.getGroupSerial());
               // entry.setPrevEntryIds(nodeInfo.getNewParentIds());
              //  entry.setNextEntryIds(nodeInfo.getNewChildIds());
                if(nodeInfo.getNewParentIds()!=null)
                {
                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : nodeInfo.getNewParentIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setPrevOperationId(id);
                        OperationDependency.add(od);
                    }
                    entry.setPrevEntryIds(OperationDependency);
                }
                if(nodeInfo.getNewChildIds()!=null)
                {
                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : nodeInfo.getNewChildIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setNextOperationId(id);
                        OperationDependency.add(od);
                    }
                    entry.setNextEntryIds(OperationDependency);
                }
                GlobalOperationInfo info= chromosome.getGlobalOpList().stream()
                        .filter(t->t.getOp().getId()==entry.getId())
                        .findFirst()
                        .orElse(null);

                if(info!=null) {
                    info.setSequence(nodeInfo.getGroupSerial());
                }
                if(entry.getId()==targetOp.getId())
                {
                    entry.setMainId(MainId);
                    entry.setState(1);
                    entry.setQuantity(newids.get(nodeInfo.getOriginalId()));
                }
            }else {
                //不存在创建新的
                Entry newOp = ProductionDeepCopyUtil.deepCopy(targetOp,Entry.class);
                newOp.setId(nodeInfo.getGlobalSerial());
                newOp.setSequence(nodeInfo.getGroupSerial());
                newOp.setExecId(nodeInfo.getOriginalId());
                newOp.setNewCreate(true);
               // newOp.setPrevEntryIds(nodeInfo.getNewParentIds());
               // newOp.setNextEntryIds(nodeInfo.getNewChildIds());
                if(nodeInfo.getNewParentIds()!=null)
                {
                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : nodeInfo.getNewParentIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setPrevOperationId(id);
                        OperationDependency.add(od);
                    }
                    newOp.setPrevEntryIds(OperationDependency);
                }
                if(nodeInfo.getNewChildIds()!=null)
                {
                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : nodeInfo.getNewChildIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setNextOperationId(id);
                        OperationDependency.add(od);
                    }
                    newOp.setNextEntryIds(OperationDependency);
                }
                newOp.setQuantity(newids.get(nodeInfo.getOriginalId()));
                newOp.setMainId(MainId);
                newOp.setState(2);
                //工序基本信息
                chromosome.getAllOperations().add(newOp);
                // 运算的全局变量
                GlobalOperationInfo info = new GlobalOperationInfo();
                info.setGlobalOpId(globalOpId);
                info.setGroupId(newOp.getGroupId());
                info.setSequence(newOp.getSequence());
                info.setOp(newOp);
                chromosome.getGlobalOpList().add(info);
                globalOpId++;
                //排产的机器选择部分
                chromosome.getMachineSelection().add(machineSeq);
                chromosome.getOperationSequencing().add(targetOpIndex,newOp.getGroupId());
                targetOpIndex++;
            }
        }

        // 工序拆分会改 allOperations 和 operationSequencing，重解码前先规整，避免同一订单排超次数。
        normalizeOperationSequencing(chromosome);
        redecode(chromosome, chromosome.getBaseTime(), globalParam);

    }

    /**
     * 按真实工序数规整工序排序序列。
     * operationSequencing 存的是订单 groupId，每出现一次代表调度该订单的下一道工序。
     * 如果某个 groupId 出现次数超过该订单实际工序数，解码时会出现“工序已全部调度”的异常。
     */
    private void normalizeOperationSequencing(Chromosome chromosome) {
        List<Entry> allOperations = chromosome.getAllOperations();
        List<Integer> operationSequencing = chromosome.getOperationSequencing();
        if (allOperations == null || operationSequencing == null) {
            return;
        }

        Map<Integer, Long> expectedCounts = allOperations.stream()
                .collect(Collectors.groupingBy(Entry::getGroupId, Collectors.counting()));
        Map<Integer, Integer> actualCounts = new HashMap<>();
        CopyOnWriteArrayList<Integer> normalized = new CopyOnWriteArrayList<>();

        // 先保留原序列中的合法次数，超过真实工序数的重复 groupId 丢弃。
        for (Integer groupId : operationSequencing) {
            if (groupId == null) {
                continue;
            }
            long expected = expectedCounts.getOrDefault(groupId, 0L);
            int actual = actualCounts.getOrDefault(groupId, 0);
            if (actual < expected) {
                normalized.add(groupId);
                actualCounts.put(groupId, actual + 1);
            }
        }

        // 如果序列缺少某些工序，再按 groupId + sequence 补齐，保证每道工序都有一次调度机会。
        allOperations.stream()
                .sorted(Comparator.comparing(Entry::getGroupId).thenComparing(Entry::getSequence))
                .forEach(op -> {
                    int groupId = op.getGroupId();
                    long expected = expectedCounts.getOrDefault(groupId, 0L);
                    int actual = actualCounts.getOrDefault(groupId, 0);
                    if (actual < expected) {
                        normalized.add(groupId);
                        actualCounts.put(groupId, actual + 1);
                    }
                });

        chromosome.setOperationSequencing(normalized);
    }
    public void SpiltOrder(Chromosome chromosome, String orderId,Double[] splitCounts, GlobalParam globalParam)
    {
        List<Entry> allOperations = chromosome.getAllOperations();

        List<Order> orders = chromosome.getOrders();

        List<GroupResult> OperatRels = chromosome.getOperatRel();

        List<Entry> targetOps = allOperations.stream()
                .filter(o -> o.getOrderId().equals(orderId) )
                .sorted(Comparator.comparing(Entry::getSequence))
                .collect(Collectors.toList());

        List<GAScheduleResult> targetSrs = chromosome.getResult().stream()
                .filter(o -> o.getOrderId().equals(orderId))
                .collect(Collectors.toList());

        Order order=orders.stream()
                .filter(o -> o.getOrderId().equals(orderId)  )
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Order not found: " + orderId));

        int maxorderId =OperatRels.size() ;

        int maxgroupId =maxorderId ;

        //记录新的工序ID和数量
        List<Entry> newEntrys=new ArrayList<>();

        List<String> newIdList = new ArrayList<>();
        List<String> newChildIdList = new ArrayList<>();
        for (int i = 1; i < splitCounts.length; i++) {
            maxorderId++;
            Order neworder = ProductionDeepCopyUtil.deepCopy(order,Order.class);
            neworder.setOrderId(UUID.randomUUID().toString().replace("-", ""));
            if(splitCounts[0]!=0&&i==1) {// 数组第一个是0，为复制
                order.setQuantity(splitCounts[0]);
            }else {
                order.setQuantity(splitCounts[i]);
            }
            neworder.setMainId(order.getOrderId());
            neworder.setNewCreate(true);
            orders.add(neworder);
            for (Entry entry : targetOps) {
                if(splitCounts[0]!=0&&i==1) {// 数组第一个是0，为复制
                    entry.setQuantity(splitCounts[0]);
                }

                String newId = UUID.randomUUID().toString().replace("-", "");
                Entry newOp = ProductionDeepCopyUtil.deepCopy(entry,Entry.class);
                newOp.setExecId(newId);
                newOp.setOrderId(neworder.getOrderId());
                newOp.setOrderCode(neworder.getOrderCode());
                newOp.setGroupId(maxorderId);
                newOp.setQuantity(splitCounts[i]);
                newOp.setNewCreate(true);
                newEntrys.add(newOp);
            }
        }
        for (Entry entry : newEntrys) {
            if(entry.getNextEntryIds().size()>0)
            {
                for (OperationDependency od : entry.getNextEntryIds()) {

                    Entry nextentry=  newEntrys.stream()
                            .filter(t->t.getGroupId()==entry.getGroupId()&&t.getId()==od.getNextOperationId())
                            .findFirst()
                            .orElse(null);
                    if(nextentry!=null) {
                        newIdList.add(entry.getExecId());
                        newChildIdList.add(nextentry.getExecId());
                    }
                }
            }else if(entry.getSequence()==1)
            {
                newIdList.add(entry.getExecId());
                newChildIdList.add("");
            }
        }

        // 添加新数据
        OperatRels = IdGroupingWithDualSerial.addNewDataWithIsolatedGroup(OperatRels, newIdList, newChildIdList);
        chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels) );
        //全局ID
        int globalOpId = chromosome.getGlobalOpList().stream()
                .mapToInt(GlobalOperationInfo::getGlobalOpId)
                .max()
                .orElse(0)+1;
        for (int i = maxgroupId; i < OperatRels.size(); i++) {
            GroupResult groupResult = OperatRels.get(i);
            List<NodeInfo> nodeInfoList = groupResult.getNodeInfoList();
            // System.out.println("分组" + (i + 1) + "顺序：" + nodeInfoList);
            for (NodeInfo nodeInfo : nodeInfoList) {
                Entry entry=  newEntrys.stream()
                        .filter(t->t.getExecId().equals(nodeInfo.getOriginalId()))
                        .findFirst()
                        .orElse(null);
                GAScheduleResult targetSr=  targetSrs.stream()
                        .filter(t->t.getOperationId()==entry.getId())
                        .findFirst()
                        .orElse(null);

                entry.setId(nodeInfo.getGlobalSerial());
                entry.setGroupId(i+1);
                entry.setSequence(nodeInfo.getGroupSerial());
                entry.setExecId(nodeInfo.getOriginalId());
               // entry.setPrevEntryIds(nodeInfo.getNewParentIds());
               // entry.setNextEntryIds(nodeInfo.getNewChildIds());
                if(nodeInfo.getNewParentIds()!=null)
                {
                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : nodeInfo.getNewParentIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setPrevOperationId(id);
                        OperationDependency.add(od);
                    }
                    entry.setPrevEntryIds(OperationDependency);
                }
                if(nodeInfo.getNewChildIds()!=null)
                {
                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : nodeInfo.getNewChildIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setNextOperationId(id);
                        OperationDependency.add(od);
                    }
                    entry.setNextEntryIds(OperationDependency);
                }
                entry.setMainId("");
                entry.setState(2);
                //工序基本信息
                chromosome.getAllOperations().add(entry);

                // 运算的全局变量
                GlobalOperationInfo info = new GlobalOperationInfo();
                info.setGlobalOpId(globalOpId);
                info.setGroupId(entry.getGroupId());
                info.setSequence(entry.getSequence());
                info.setOp(entry);
                chromosome.getGlobalOpList().add(info);
                globalOpId++;
                List<MachineOption> optionalMachines = entry.getMachineOptions();
                OptionalInt index = IntStream.range(0, optionalMachines.size())
                        .filter(h -> targetSr.getMachineId()==optionalMachines.get(h).getMachineId())
                        .findFirst();
                int machineSeq =index.orElse(0)+1 ;
                chromosome.getMachineSelection().add(machineSeq);

            }
        }


        for (Entry entry : targetOps) {
            List<Integer> OperationSequencing=  chromosome.getOperationSequencing();

            OptionalInt OperationIndex = IntStream.range(0, OperationSequencing.size())
                    .filter(i -> OperationSequencing.get(i).equals(entry.getGroupId())) // 过滤出值为1的索引
                    .skip(entry.getSequence()-1) // 跳过第一个匹配项
                    .findFirst();
            int targetOpIndex= OperationIndex.getAsInt()+1;
            for (int i = maxgroupId; i < OperatRels.size(); i++) {
                chromosome.getOperationSequencing().add(targetOpIndex, i+1);
                targetOpIndex++;
            }

        }
        chromosome.setOrders(new CopyOnWriteArrayList<>(orders));
        redecode(chromosome, chromosome.getBaseTime(), globalParam);

    }

    /**
     * 插入新订单到排产中
     * 将新订单排在指定订单后面
     *
     * @param chromosome 染色体对象
     * @param afterOrderId 插入位置订单ID（新订单将排在此订单后面）
     * @param newOrderId 新订单ID
     * @param newLaunchOrder 新订单对象
     * @param newProcessExecs 新订单的工序列表
     * @param globalParam 全局参数
     */
    public void InsertOrder(Chromosome chromosome, String afterOrderId, String newOrderId,
                            ProdLaunchOrder newLaunchOrder, List<ProdProcessExec> newProcessExecs,
                            GlobalParam globalParam) {

        List<Entry> allOperations = chromosome.getAllOperations();
        List<Order> orders = chromosome.getOrders();
        List<GroupResult> OperatRels = chromosome.getOperatRel();

        // 1. 创建新的Order对象
        Order newOrder = new Order();
        newOrder.setOrderId(newOrderId);
        newOrder.setOrderCode(newLaunchOrder.getOrderCode());
        newOrder.setQuantity(newLaunchOrder.getQuantity());
        newOrder.setPriority(newLaunchOrder.getOrderPriority() != null ? newLaunchOrder.getOrderPriority() : 1);
        newOrder.setMaterialId(newLaunchOrder.getMaterialId());
        newOrder.setMaterialCode(newLaunchOrder.getMaterialCode());
        newOrder.setMaterialName(newLaunchOrder.getMaterialName());
        newOrder.setStartDate(newLaunchOrder.getStartDate());
        newOrder.setDueDate(newLaunchOrder.getEndDate());
        newOrder.setRoutingId(newLaunchOrder.getRoutingId());
        newOrder.setRoutingCode(newLaunchOrder.getRoutingCode());
        newOrder.setSerie(newLaunchOrder.getSerie());


        // 获取当前最大的Order ID
        int maxOrderId = orders.stream()
                .mapToInt(Order::getId)
                .max()
                .orElse(0) + 1;
        newOrder.setId(maxOrderId);

        orders.add(newOrder);

        // 2. 创建新订单的Entry对象
        int maxGroupId = OperatRels.size();
        int newGroupId = maxGroupId + 1;

        List<Entry> newEntrys = new ArrayList<>();
        List<String> newIdList = new ArrayList<>();
        List<String> newChildIdList = new ArrayList<>();

        // 从ProdProcessExec创建Entry
        for (ProdProcessExec processExec : newProcessExecs) {
            Entry newEntry = new Entry();
            newEntry.setExecId(processExec.getExecId());
            newEntry.setOrderId(newOrderId);
            newEntry.setOrderCode(newLaunchOrder.getOrderCode());
            newEntry.setGroupId(newGroupId);
            newEntry.setQuantity(newLaunchOrder.getQuantity());
            newEntry.setSequence(processExec.getTaskSeq() != null ? processExec.getTaskSeq().intValue() : 1);
            newEntry.setTaskSeq(processExec.getTaskSeq()); // 设置taskSeq字段
            newEntry.setState(2);

            // 设置工序相关信息
            newEntry.setRoutingDetailId(processExec.getRoutingDetailId());
            newEntry.setRoutingId(processExec.getRoutingId());
            newEntry.setRoutingCode(processExec.getRoutingCode());
            newEntry.setRoutingName(processExec.getRoutingName());
            newEntry.setRoutingDetailName(processExec.getRoutingDetailName());

            // 设置产品相关信息
            newEntry.setProductId(newLaunchOrder.getMaterialId());
            newEntry.setProductCode(newLaunchOrder.getMaterialCode());
            newEntry.setProductName(newLaunchOrder.getMaterialName());

            // 设置部门信息
            if (processExec.getDepartmentId() != null) {
                newEntry.setDepartmentId(processExec.getDepartmentId());
            }

            // 设置中断属性
            newEntry.setIsInterrupt(processExec.getCanInterrupt());

            // 设置设备类型信息
            newEntry.setEquipTypeID(processExec.getMachineId());

            // 使用runtime字段
            if (processExec.getRuntime() != null) {
                newEntry.setRuntime(processExec.getRuntime());
            }
            newEntry.setPriority(newLaunchOrder.getOrderPriority() != null ? newLaunchOrder.getOrderPriority() : 1);

            // 设置其他时间相关字段
            if (processExec.getSetupTime() != null) {
                newEntry.setSetupTime(processExec.getSetupTime());
            }
            newEntry.setChangeLineTime(processExec.getChangeLineTime());
            newEntry.setConstTime(processExec.getConstTime());
            newEntry.setPreTime(processExec.getPreprocessingTime());
            newEntry.setTeardownTime(processExec.getPostprocessingTime());

            // 设置设备相关信息
            newEntry.setEquipTypeName(processExec.getEquipTypeName());
            newEntry.setEquipTypeCode(processExec.getEquipTypeCode());

            // 设备配置将在后面从插入位置的订单复制，这里先设置为空列表
            newEntry.setMachineOptions(new ArrayList<>());

            // 设置默认选中的设备ID（将在后面从插入位置订单复制）
            newEntry.setSelectMachineID(null);

            newEntrys.add(newEntry);
        }

        // 3. 建立工序之间的依赖关系
        for (int i = 0; i < newEntrys.size(); i++) {
            Entry entry = newEntrys.get(i);

            if (i == 0) {
                // 第一道工序，没有前置工序
                newIdList.add(entry.getExecId());
                newChildIdList.add(i + 1 < newEntrys.size() ? newEntrys.get(i + 1).getExecId() : "");
            } else if (i == newEntrys.size() - 1) {
                // 最后一道工序，没有后续工序
                newIdList.add(entry.getExecId());
                newChildIdList.add("");
            } else {
                // 中间工序
                newIdList.add(entry.getExecId());
                newChildIdList.add(newEntrys.get(i + 1).getExecId());
            }
        }

        // 4. 添加新数据到OperatRels
        OperatRels = IdGroupingWithDualSerial.addNewDataWithIsolatedGroup(OperatRels, newIdList, newChildIdList);
        chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels));

        // 5. 更新全局ID和Entry信息
        int globalOpId = chromosome.getGlobalOpList().stream()
                .mapToInt(GlobalOperationInfo::getGlobalOpId)
                .max()
                .orElse(0) + 1;

        GroupResult newGroupResult = OperatRels.get(OperatRels.size() - 1);
        List<NodeInfo> nodeInfoList = newGroupResult.getNodeInfoList();

        for (NodeInfo nodeInfo : nodeInfoList) {
            Entry entry = newEntrys.stream()
                    .filter(t -> t.getExecId().equals(nodeInfo.getOriginalId()))
                    .findFirst()
                    .orElse(null);

            if (entry != null) {
                entry.setId(nodeInfo.getGlobalSerial());
                entry.setGroupId(newGroupId);
                entry.setSequence(nodeInfo.getGroupSerial());

                // 设置前置和后续工序依赖
                if (nodeInfo.getNewParentIds() != null) {
                    List<OperationDependency> dependencies = new ArrayList<>();
                    for (int id : nodeInfo.getNewParentIds()) {
                        OperationDependency od = new OperationDependency();
                        od.setPrevOperationId(id);
                        dependencies.add(od);
                    }
                    entry.setPrevEntryIds(dependencies);
                }

                if (nodeInfo.getNewChildIds() != null) {
                    List<OperationDependency> dependencies = new ArrayList<>();
                    for (int id : nodeInfo.getNewChildIds()) {
                        OperationDependency od = new OperationDependency();
                        od.setNextOperationId(id);
                        dependencies.add(od);
                    }
                    entry.setNextEntryIds(dependencies);
                }

                // 添加到allOperations
                chromosome.getAllOperations().add(entry);

                // 添加到全局操作列表
                GlobalOperationInfo info = new GlobalOperationInfo();
                info.setGlobalOpId(globalOpId);
                info.setGroupId(entry.getGroupId());
                info.setSequence(entry.getSequence());
                info.setOp(entry);
                chromosome.getGlobalOpList().add(info);
                globalOpId++;

                // 添加默认的机器选择（第一个可选设备）
                chromosome.getMachineSelection().add(1);
            }
        }

        // 6. 将新订单插入到指定订单后面的位置，并使用相同的设备配置
        List<Entry> afterOrderOps = allOperations.stream()
                .filter(o -> o.getOrderId().equals(afterOrderId))
                .sorted(Comparator.comparing(Entry::getSequence))
                .collect(Collectors.toList());

        if (!afterOrderOps.isEmpty()) {
            Entry lastOpOfAfterOrder = afterOrderOps.get(afterOrderOps.size() - 1);
            List<Integer> operationSequencing = chromosome.getOperationSequencing();

            // 找到afterOrder最后一道工序在operationSequencing中的位置
            OptionalInt operationIndex = IntStream.range(0, operationSequencing.size())
                    .filter(i -> operationSequencing.get(i).equals(lastOpOfAfterOrder.getGroupId()))
                    .findFirst();

            if (operationIndex.isPresent()) {
                int insertPosition = operationIndex.getAsInt() + 1;

                // 在该位置后插入新订单的所有工序
                for (int i = 0; i < newEntrys.size(); i++) {
                    chromosome.getOperationSequencing().add(insertPosition + i, newGroupId);
                }
            } else {
                // 如果找不到位置，就添加到末尾
                for (int i = 0; i < newEntrys.size(); i++) {
                    chromosome.getOperationSequencing().add(newGroupId);
                }
            }

            // 使用插入位置订单的设备配置来更新新订单的工序
            // 这样可以确保新订单使用相同的生产线和设备
            for (int i = 0; i < newEntrys.size() && i < afterOrderOps.size(); i++) {
                Entry newEntry = newEntrys.get(i);
                Entry referenceEntry = afterOrderOps.get(i);

                // 复制设备配置
                if (referenceEntry.getMachineOptions() != null && !referenceEntry.getMachineOptions().isEmpty()) {
                    newEntry.setMachineOptions(new ArrayList<>(referenceEntry.getMachineOptions()));
                    newEntry.setSelectMachineID(referenceEntry.getSelectMachineID());
                    newEntry.setEquipCode(referenceEntry.getEquipCode());
                    newEntry.setEquipName(referenceEntry.getEquipName());
                }
            }
        } else {
            // 如果找不到afterOrder，就添加到末尾
            for (int i = 0; i < newEntrys.size(); i++) {
                chromosome.getOperationSequencing().add(newGroupId);
            }
        }


        // 临时设置isCheckSf为false，避免CreateNewOpSequence重新生成operationSequencing
        boolean originalIsCheckSf = globalParam.isIsCheckSf();
        globalParam.setIsCheckSf(false);

        // 7. 重新解码，重新计算排产结果
        redecode(chromosome, chromosome.getBaseTime(), globalParam);

        // 恢复isCheckSf的原始值
        globalParam.setIsCheckSf(originalIsCheckSf);
    }


    public void InsertOrderAuto(Chromosome chromosome, String newOrderId,
                                ProdLaunchOrder newLaunchOrder, List<ProdProcessExec> newProcessExecs,
                                List<ProdEquipment> newProdEquipments,
                                LocalDateTime anchorTime, GlobalParam globalParam) {
        pinFrozenResults(chromosome, anchorTime);
        List<Order> orders = chromosome.getOrders();
        List<GroupResult> OperatRels = chromosome.getOperatRel();

        Order newOrder = new Order();
        newOrder.setOrderId(newOrderId);
        newOrder.setOrderCode(newLaunchOrder.getOrderCode());
        newOrder.setQuantity(newLaunchOrder.getQuantity());
        newOrder.setPriority(newLaunchOrder.getOrderPriority() != null ? newLaunchOrder.getOrderPriority() : 1);
        newOrder.setMaterialId(newLaunchOrder.getMaterialId());
        newOrder.setMaterialCode(newLaunchOrder.getMaterialCode());
        newOrder.setMaterialName(newLaunchOrder.getMaterialName());
        newOrder.setStartDate(newLaunchOrder.getStartDate());
        newOrder.setDueDate(newLaunchOrder.getEndDate());
        newOrder.setRoutingId(newLaunchOrder.getRoutingId());
        newOrder.setRoutingCode(newLaunchOrder.getRoutingCode());
        newOrder.setSerie(newLaunchOrder.getSerie());

        int newGroupId = resolveNextAutoInsertGroupId(chromosome);
        newOrder.setId(newGroupId);
        orders.add(newOrder);

        padOperationRelations(OperatRels, newGroupId);

        List<Entry> newEntrys = new ArrayList<>();
        List<String> newIdList = new ArrayList<>();
        List<String> newChildIdList = new ArrayList<>();

        for (ProdProcessExec processExec : newProcessExecs) {
            Entry newEntry = new Entry();
            newEntry.setExecId(processExec.getExecId());
            newEntry.setOrderId(newOrderId);
            newEntry.setOrderCode(newLaunchOrder.getOrderCode());
            newEntry.setGroupId(newGroupId);
            newEntry.setQuantity(newLaunchOrder.getQuantity());
            newEntry.setSequence(processExec.getTaskSeq() != null ? processExec.getTaskSeq().intValue() : 1);
            newEntry.setTaskSeq(processExec.getTaskSeq());
            newEntry.setState(2);

            newEntry.setRoutingDetailId(processExec.getRoutingDetailId());
            newEntry.setRoutingId(processExec.getRoutingId());
            newEntry.setRoutingCode(processExec.getRoutingCode());
            newEntry.setRoutingName(processExec.getRoutingName());
            newEntry.setRoutingDetailName(processExec.getRoutingDetailName());

            newEntry.setProductId(newLaunchOrder.getMaterialId());
            newEntry.setProductCode(newLaunchOrder.getMaterialCode());
            newEntry.setProductName(newLaunchOrder.getMaterialName());

            if (processExec.getDepartmentId() != null) {
                newEntry.setDepartmentId(processExec.getDepartmentId());
            }

            newEntry.setIsInterrupt(processExec.getCanInterrupt());
            newEntry.setEquipTypeID(processExec.getMachineId());

            if (processExec.getRuntime() != null) {
                newEntry.setRuntime(processExec.getRuntime());
            }
            if (processExec.getSingleOut() != null) {
                newEntry.setSingleOut(processExec.getSingleOut());
            }

            newEntry.setPriority(newLaunchOrder.getOrderPriority() != null ? newLaunchOrder.getOrderPriority() : 1);

            if (processExec.getSetupTime() != null) {
                newEntry.setSetupTime(processExec.getSetupTime());
            }
            newEntry.setChangeLineTime(processExec.getChangeLineTime());
            newEntry.setConstTime(processExec.getConstTime());
            newEntry.setPreTime(processExec.getPreprocessingTime());
            newEntry.setTeardownTime(processExec.getPostprocessingTime());

            newEntry.setEquipTypeName(processExec.getEquipTypeName());
            newEntry.setEquipTypeCode(processExec.getEquipTypeCode());

            // 与 InitEntrys 对齐：设备来源于 prod_equipment（真实设备ID）
            List<MachineOption> machineOptions = newProdEquipments.stream()
                    .filter(pe -> pe.getExecId() != null && pe.getExecId().equals(processExec.getExecId()))
                    .map(pe -> {
                        MachineOption mo = new MachineOption();
                        mo.setMachineId(pe.getEquipId());
                        mo.setRuntime(pe.getRuntime() != null ? pe.getRuntime() : BigDecimal.ZERO);
                        mo.setSingleOut(pe.getSingleOut() != null ? pe.getSingleOut() : BigDecimal.ONE);
                        mo.setEquipCode(pe.getEquipCode());
                        mo.setEquipName(pe.getEquipName());
                        mo.setResourceCode(pe.getResourceCode());
                        mo.setProcessingTime(pe.getSpeed() != null ? pe.getSpeed() : 0d);
                        return mo;
                    })
                    .collect(Collectors.toList());

            if (machineOptions.isEmpty()) {
                throw new RuntimeException("自动插单失败：工序[" + processExec.getExecId() + "]没有可用设备");
            }

            newEntry.setMachineOptions(machineOptions);
            newEntry.setSelectMachineID(null); // 后面按最优序号回填

            newEntrys.add(newEntry);
        }

        // 建工序链
        for (int i = 0; i < newEntrys.size(); i++) {
            Entry entry = newEntrys.get(i);
            if (i == 0) {
                newIdList.add(entry.getExecId());
                newChildIdList.add(i + 1 < newEntrys.size() ? newEntrys.get(i + 1).getExecId() : "");
            } else if (i == newEntrys.size() - 1) {
                newIdList.add(entry.getExecId());
                newChildIdList.add("");
            } else {
                newIdList.add(entry.getExecId());
                newChildIdList.add(newEntrys.get(i + 1).getExecId());
            }
        }

        int nextOperationId = chromosome.getAllOperations().stream()
                .mapToInt(Entry::getId)
                .max()
                .orElse(0) + 1;
        OperatRels = IdGroupingWithDualSerial.addNewDataWithIsolatedGroup(
                OperatRels, newIdList, newChildIdList, nextOperationId);
        chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels));

        int globalOpId = chromosome.getGlobalOpList().stream()
                .mapToInt(GlobalOperationInfo::getGlobalOpId)
                .max()
                .orElse(0) + 1;

        GroupResult newGroupResult = OperatRels.get(OperatRels.size() - 1);
        List<NodeInfo> nodeInfoList = newGroupResult.getNodeInfoList();

        Entry firstEntry = null;

        for (NodeInfo nodeInfo : nodeInfoList) {
            Entry entry = newEntrys.stream()
                    .filter(t -> t.getExecId().equals(nodeInfo.getOriginalId()))
                    .findFirst()
                    .orElse(null);

            if (entry != null) {
                entry.setId(nodeInfo.getGlobalSerial());
                entry.setGroupId(newGroupId);
                entry.setSequence(nodeInfo.getGroupSerial());

                if (nodeInfo.getNewParentIds() != null) {
                    List<OperationDependency> dependencies = new ArrayList<>();
                    for (int id : nodeInfo.getNewParentIds()) {
                        OperationDependency od = new OperationDependency();
                        od.setPrevOperationId(id);
                        dependencies.add(od);
                    }
                    entry.setPrevEntryIds(dependencies);
                }

                if (nodeInfo.getNewChildIds() != null) {
                    List<OperationDependency> dependencies = new ArrayList<>();
                    for (int id : nodeInfo.getNewChildIds()) {
                        OperationDependency od = new OperationDependency();
                        od.setNextOperationId(id);
                        dependencies.add(od);
                    }
                    entry.setNextEntryIds(dependencies);
                }

                chromosome.getAllOperations().add(entry);

                GlobalOperationInfo info = new GlobalOperationInfo();
                info.setGlobalOpId(globalOpId);
                info.setGroupId(entry.getGroupId());
                info.setSequence(entry.getSequence());
                info.setOp(entry);
                chromosome.getGlobalOpList().add(info);

                int bestSeq = calcBestMachineSeq(entry, chromosome, anchorTime);
                chromosome.getMachineSelection().add(bestSeq);
                entry.setSelectMachineID(entry.getMachineOptions().get(bestSeq - 1).getMachineId());

                if (entry.getSequence() == 1) {
                    firstEntry = entry;
                }

                globalOpId++;
            }
        }

        for (int i = 0; i < newEntrys.size(); i++) {
            chromosome.getOperationSequencing().add(newGroupId);
        }

        int firstOperationId = firstEntry != null ? firstEntry.getId() : -1;

        boolean originalIsCheckSf = globalParam.isIsCheckSf();
        globalParam.setIsCheckSf(false);

        // 第一次解码：先拿到首工序所在设备
        if (anchorTime != null && firstEntry != null) {
            firstEntry.setDesignatedStartTime(anchorTime);
        }
        redecode(chromosome, chromosome.getBaseTime(), globalParam);

        // 第二次调整：按冻结锚点插位
        if (anchorTime != null && firstOperationId > 0) {
            GAScheduleResult firstResult = chromosome.getResult().stream()
                    .filter(r -> r.getOperationId() == firstOperationId)
                    .findFirst()
                    .orElse(null);

            if (firstResult != null) {
                long machineId = firstResult.getMachineId();
                int anchorSeconds = (int) java.time.temporal.ChronoUnit.SECONDS.between(chromosome.getBaseTime(), anchorTime);
                int firstDuration = Math.max(1, firstResult.getEndTime() - firstResult.getStartTime());

                // 该设备老任务（不含新工单）
                List<GAScheduleResult> machineOldResults = chromosome.getResult().stream()
                        .filter(r -> r.getMachineId() == machineId)
                        .filter(r -> r.getGroupId() != firstResult.getGroupId())
                        .sorted(Comparator.comparingInt(GAScheduleResult::getStartTime))
                        .collect(Collectors.toList());

                // 锚点处占位任务（跨锚点）
                GAScheduleResult pivot = machineOldResults.stream()
                        .filter(r -> r.getStartTime() <= anchorSeconds && r.getEndTime() > anchorSeconds)
                        .findFirst()
                        .orElse(null);

                // 若锚点没被跨，则取锚点后第一任务
                if (pivot == null) {
                    pivot = machineOldResults.stream()
                            .filter(r -> r.getStartTime() >= anchorSeconds)
                            .findFirst()
                            .orElse(null);
                }

                // 锚点前最后一单
                GAScheduleResult prev = machineOldResults.stream()
                        .filter(r -> r.getEndTime() <= anchorSeconds)
                        .reduce((a, b) -> b)
                        .orElse(null);

                int newDesignatedStart;
                if (pivot != null) {
                    if (pivot.getStartTime() <= anchorSeconds && pivot.getEndTime() > anchorSeconds) {
                        // 锚点被占：应从占位任务结束后开始
                        newDesignatedStart = pivot.getEndTime();
                    } else {
                        // 锚点后有任务：插到该任务前
                        newDesignatedStart = pivot.getStartTime();
                    }
                } else {
                    // 锚点后无任务：从锚点或锚点前最后一单结束后开始
                    newDesignatedStart = prev != null ? Math.max(anchorSeconds, prev.getEndTime()) : anchorSeconds;
                }

                // 不能早于冻结边界
                if (newDesignatedStart < anchorSeconds) {
                    newDesignatedStart = anchorSeconds;
                }

                // 锁新工单首工序起点
                Entry firstEntryRef = chromosome.getAllOperations().stream()
                        .filter(e -> e.getId() == firstOperationId)
                        .findFirst()
                        .orElse(null);
                if (firstEntryRef != null) {
                    firstEntryRef.setDesignatedStartTime(chromosome.getBaseTime().plusSeconds(newDesignatedStart));
                }

                GAScheduleResult firstLock = chromosome.getResult().stream()
                        .filter(r -> r.getOperationId() == firstOperationId)
                        .findFirst()
                        .orElse(null);
                if (firstLock != null) {
                    firstLock.setDesignatedStartTime(newDesignatedStart);
                    firstLock.setLockStartTime(1);
                }

                // 仅后移 newDesignatedStart 及其后的老任务
                int finalNewDesignatedStart = newDesignatedStart;
                List<GAScheduleResult> needShift = machineOldResults.stream()
                        .filter(r -> r.getStartTime() >= finalNewDesignatedStart)
                        .collect(Collectors.toList());

                for (GAScheduleResult oldResult : needShift) {
                    oldResult.setDesignatedStartTime(oldResult.getStartTime() + firstDuration);
                    oldResult.setLockStartTime(1);
                }

                redecode(chromosome, chromosome.getBaseTime(), globalParam);
            }
        }

        globalParam.setIsCheckSf(originalIsCheckSf);
    }

    private void pinFrozenResults(Chromosome chromosome, LocalDateTime anchorTime) {
        if (chromosome == null || chromosome.getBaseTime() == null || anchorTime == null
                || chromosome.getResult() == null || chromosome.getResult().isEmpty()) {
            return;
        }

        int anchorSeconds = (int) java.time.temporal.ChronoUnit.SECONDS.between(
                chromosome.getBaseTime(), anchorTime);
        Map<Integer, Entry> entriesById = chromosome.getAllOperations() == null
                ? Collections.emptyMap()
                : chromosome.getAllOperations().stream()
                .collect(Collectors.toMap(Entry::getId, entry -> entry, (left, right) -> left));

        int pinnedCount = 0;
        for (GAScheduleResult result : chromosome.getResult()) {
            if (result == null || result.getStartTime() >= anchorSeconds) {
                continue;
            }
            result.setLockStartTime(1);
            result.setDesignatedStartTime(result.getStartTime());
            result.setForcedMachineId(result.getMachineId());

            Entry entry = entriesById.get(result.getOperationId());
            if (entry != null) {
                entry.setDesignatedStartTime(chromosome.getBaseTime().plusSeconds(result.getStartTime()));
            }
            pinnedCount++;
        }
    }

    private int resolveNextAutoInsertGroupId(Chromosome chromosome) {
        int maxOrderId = chromosome.getOrders() == null
                ? 0
                : chromosome.getOrders().stream().mapToInt(Order::getId).max().orElse(0);
        int maxEntryGroupId = chromosome.getAllOperations() == null
                ? 0
                : chromosome.getAllOperations().stream().mapToInt(Entry::getGroupId).max().orElse(0);
        int maxResultGroupId = chromosome.getResult() == null
                ? 0
                : chromosome.getResult().stream().mapToInt(GAScheduleResult::getGroupId).max().orElse(0);
        int relationCount = chromosome.getOperatRel() == null ? 0 : chromosome.getOperatRel().size();
        return Math.max(Math.max(maxOrderId, maxEntryGroupId), Math.max(maxResultGroupId, relationCount)) + 1;
    }

    private void padOperationRelations(List<GroupResult> operationRelations, int newGroupId) {
        while (operationRelations.size() < newGroupId - 1) {
            operationRelations.add(new GroupResult(new ArrayList<>(), new HashMap<>()));
        }
    }

    private int calcBestMachineSeq(Entry entry, Chromosome chromosome, LocalDateTime anchorTime) {
        List<MachineOption> rawOptions = entry.getMachineOptions();
        if (rawOptions == null || rawOptions.isEmpty()) {
            throw new RuntimeException("工序无可选设备: " + entry.getExecId());
        }

        // 只保留当前排产设备池中的设备
        Set<Long> availableMachineIds = chromosome.getMachines().stream()
                .map(Machine::getId)
                .collect(Collectors.toSet());

        List<MachineOption> options = rawOptions.stream()
                .filter(o -> availableMachineIds.contains(o.getMachineId()))
                .collect(Collectors.toList());

        if (options.isEmpty()) {
            throw new RuntimeException("工序无可用设备(不在当前排产设备池): " + entry.getExecId());
        }

        Map<Long, Integer> machineEnd = chromosome.getResult().stream()
                .collect(Collectors.groupingBy(
                        GAScheduleResult::getMachineId,
                        Collectors.collectingAndThen(
                                Collectors.maxBy(Comparator.comparingInt(GAScheduleResult::getEndTime)),
                                o -> o.map(GAScheduleResult::getEndTime).orElse(0)
                        )
                ));

        int anchorSec = 0;
        if (anchorTime != null && chromosome.getBaseTime() != null) {
            anchorSec = (int) java.time.temporal.ChronoUnit.SECONDS.between(chromosome.getBaseTime(), anchorTime);
            if (anchorSec < 0) {
                anchorSec = 0;
            }
        }

        int bestIdx = 0;
        double bestScore = Double.MAX_VALUE;

        for (int i = 0; i < options.size(); i++) {
            MachineOption op = options.get(i);
            int ready = Math.max(anchorSec, machineEnd.getOrDefault(op.getMachineId(), 0));

            double duration;
            if (entry.getConstTime() == 1) {
                duration = Math.max(0d, op.getProcessingTime());
            } else {
                double runtime = op.getRuntime() != null ? op.getRuntime().doubleValue() : 0d;
                double singleOut = op.getSingleOut() != null ? op.getSingleOut().doubleValue() : 1d;
                if (singleOut <= 0) {
                    singleOut = 1d;
                }
                duration = runtime / singleOut * entry.getQuantity();
            }

            double score = ready + duration;
            if (score < bestScore) {
                bestScore = score;
                bestIdx = i;
            }
        }

        // 注意：这里返回的是在rawOptions中的序号（machineSelection要求按entry.machineOptions顺序）
        Long bestMachineId = options.get(bestIdx).getMachineId();
        int rawIndex = IntStream.range(0, rawOptions.size())
                .filter(i -> rawOptions.get(i).getMachineId() == bestMachineId)
                .findFirst()
                .orElse(0);

        return rawIndex + 1;
    }




    public void MergeOrder(Chromosome chromosome, String sourceorderId,String targetorderId, GlobalParam globalParam) {
        List<Entry> allOperations = chromosome.getAllOperations();
        List<GlobalOperationInfo> globalOpList=  chromosome.getGlobalOpList();
        List<Order> orders = chromosome.getOrders();
        List<Integer> OperationSequencing=  chromosome.getOperationSequencing();
        List<GAScheduleResult> ScheduleResults = chromosome.getResult();

        Order sourceorder=orders.stream()
                .filter(o -> o.getOrderId().equals(sourceorderId)  )
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Order not found: " + sourceorderId));

        Order targetorder=orders.stream()
                .filter(o -> o.getOrderId().equals(targetorderId)  )
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Order not found: " + targetorderId));

        targetorder.setQuantity(targetorder.getQuantity()+sourceorder.getQuantity());
        List<Entry> targetOps = allOperations.stream()
                .filter(o -> o.getOrderId().equals(targetorderId) )
                .sorted(Comparator.comparing(Entry::getSequence))
                .collect(Collectors.toList());

        for (Entry entry : targetOps) {

            entry.setQuantity(entry.getQuantity()+sourceorder.getQuantity());


        }
        List<Entry> sourceOps = allOperations.stream()
                .filter(o -> o.getOrderId().equals(sourceorderId) )
                .sorted(Comparator.comparing(Entry::getSequence))
                .collect(Collectors.toList());
       int GroupId=0;
        for (Entry entry : sourceOps) {
            GroupId= entry.getGroupId();
            OptionalInt index = IntStream.range(0, allOperations.size())
                    .filter(h -> entry.getId()==allOperations.get(h).getId())
                    .findFirst();
            allOperations.remove((int)index.orElse(0));

            OptionalInt index1 = IntStream.range(0, globalOpList.size())
                    .filter(h -> entry.getId()==globalOpList.get(h).getOp().getId())
                    .findFirst();
            globalOpList.remove((int)index1.orElse(0));

            chromosome.getMachineSelection().remove((int)index1.orElse(0));

            OptionalInt OperationIndex = IntStream.range(0, OperationSequencing.size())
                    .filter(i -> OperationSequencing.get(i).equals(entry.getGroupId())) // 过滤出值为1的索引
                    .findFirst();
            int targetOpIndex= OperationIndex.getAsInt();
            OperationSequencing.remove((int)targetOpIndex);

            OptionalInt OperationIndex1 = IntStream.range(0, ScheduleResults.size())
                    .filter(i -> ScheduleResults.get(i).getOperationId()==entry.getId()) // 过滤出值为1的索引
                    .findFirst();

//锁定需要删除
            ScheduleResults.remove((int)OperationIndex1.getAsInt());

        }
        AtomicInteger globalOpId = new AtomicInteger(0);
        globalOpList.forEach(t-> {

            t.setGlobalOpId(globalOpId.getAndIncrement());

        });
        // chromosome.getOperatRel().remove(GroupId-1);
        orders.remove(sourceorder);
        redecode(chromosome, chromosome.getBaseTime(), globalParam);
    }
    public void LockOperation(Chromosome chromosome,int opId, boolean isLocked, GlobalParam globalParam)
    {
        Entry targetOp = chromosome.getAllOperations().stream()
                .filter(o -> o.getId() == opId)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));


        List<GAScheduleResult> targetResults = chromosome.getResult().stream()
                .filter(r ->r.getGroupId()== targetOp.getGroupId()&&r.getOperationId() <= opId).collect(Collectors.toList());

        targetResults.forEach(t->t.setIsLocked(isLocked));

        // 若解锁，重新解码受影响工序
//        if (!isLocked)
//        {
//            redecode(chromosome, chromosome.getBaseTime(), globalParam);
//        }
    }

    public void DelOperation(Chromosome chromosome, int opId, GlobalParam globalParam) {

        List<Entry> allOperations = chromosome.getAllOperations();

        List<GroupResult> OperatRels = chromosome.getOperatRel();

        OperatRels = IdGroupingWithDualSerial.deleteNodeByGlobalSerial(OperatRels, opId);
        chromosome.setOperatRel(new CopyOnWriteArrayList<>(OperatRels) );
        Entry targetOp = allOperations.stream()
                .filter(o -> o.getId() == opId)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));


        List<Entry> entrys = allOperations.stream()
                .filter(o -> o.getGroupId() == targetOp.getGroupId())
                .collect(Collectors.toList());
        //当前组的
        GroupResult groupResult = OperatRels.get(targetOp.getGroupId()-1);
        List<NodeInfo> nodeInfoList = groupResult.getNodeInfoList();

        List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();

        nodeInfoList = groupResult.getNodeInfoList();
        for (Entry entry : entrys) {
            NodeInfo node = nodeInfoList.stream()
                    .filter(o -> o.getGlobalSerial() == entry.getId())
                    .findFirst()
                    .orElse(null);
            if(node!=null)
            {
                entry.setSequence(node.getGroupSerial());
              //  entry.setPrevEntryIds(node.getNewParentIds());
              //  entry.setNextEntryIds(node.getNewChildIds());
                if(node.getNewParentIds()!=null)
                {
                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : node.getNewParentIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setPrevOperationId(id);
                        OperationDependency.add(od);
                    }
                    entry.setPrevEntryIds(OperationDependency);
                }
                if(node.getNewChildIds()!=null)
                {
                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : node.getNewChildIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setNextOperationId(id);
                        OperationDependency.add(od);
                    }
                    entry.setNextEntryIds(OperationDependency);
                }
                GlobalOperationInfo info= chromosome.getGlobalOpList().stream()
                        .filter(t->t.getOp().getId()==entry.getId())
                        .findFirst()
                        .orElse(null);

                if(info!=null) {
                    info.setSequence(node.getGroupSerial());
                    info.setOp(entry);
                }



            }else {
                if(entry.getMainId()!=null&&!entry.getMainId().equals("")) {
                    //拆分的工序数量补齐到其他的

                    Entry main = entrys.stream().
                            filter(t -> t.getMainId().equals(entry.getMainId()) &&t.getId()!=entry.getId())
                            .findFirst()
                            .orElse(null);
                    if (main != null) {
                        main.setQuantity(main.getQuantity() + entry.getQuantity());

                        GlobalOperationInfo operationInfo= globalOpList.stream()
                                .filter(i -> i.getOp().getId() == main.getId())
                                .findFirst()
                                .orElseThrow(() -> new NoSuchElementException("Global operation not found: " + entry.getId()));
                        operationInfo.setOp(main);
                    }
                }

            }
        }
        List<Integer> OperationSequencing=  chromosome.getOperationSequencing();

        OptionalInt OperationIndex = IntStream.range(0, OperationSequencing.size())
                .filter(i -> OperationSequencing.get(i).equals(targetOp.getGroupId())) // 过滤出值为1的索引
                .skip(targetOp.getSequence()-1) // 跳过第一个匹配项
                .findFirst();
        chromosome.getOperationSequencing().remove((int)OperationIndex.getAsInt());



        int globalOpIndex = IntStream.range(0, globalOpList.size())
                .filter(i -> globalOpList.get(i).getOp().getId() == opId)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Global operation not found: " + opId));


        // MachineSelection 与 globalOpList 按 globalOpId 一一对应，删除工序时必须同步删除同索引的机器选择。
        chromosome.getMachineSelection().remove((int)globalOpIndex);
        globalOpList.remove((int)globalOpIndex);


        AtomicInteger globalOpId = new AtomicInteger(0);
        globalOpList.forEach(t-> {

        t.setGlobalOpId(globalOpId.getAndIncrement());

        });


        List<Entry> operations = chromosome.getAllOperations();

        IntStream.range(0, operations.size())
                .filter(i -> operations.get(i).getId() == opId)
                .findFirst()
                .ifPresent(operations::remove);

        List<GAScheduleResult> results = chromosome.getResult();

        IntStream.range(0, results.size())
                .filter(i -> results.get(i).getOperationId() == opId)
                .findFirst()
                .ifPresent(results::remove);

        redecode(chromosome, chromosome.getBaseTime(), globalParam);

    }

    public void DelOrder(Chromosome chromosome, String orderId, GlobalParam globalParam) {
        List<Entry> allOperations = chromosome.getAllOperations();
        List<GlobalOperationInfo> globalOpList=  chromosome.getGlobalOpList();
        List<Order> orders = chromosome.getOrders();
        List<Integer> OperationSequencing=  chromosome.getOperationSequencing();
        List<GAScheduleResult> ScheduleResults = chromosome.getResult();
        Order sourceorder=orders.stream()
                .filter(o -> o.getOrderId().equals(orderId)  )
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Order not found: " + orderId));

        List<Entry> sourceOps = allOperations.stream()
                .filter(o -> o.getOrderId().equals(orderId) )
                .sorted(Comparator.comparing(Entry::getSequence))
                .collect(Collectors.toList());
        int GroupId=0;
        for (Entry entry : sourceOps) {
            GroupId= entry.getGroupId();
            OptionalInt index = IntStream.range(0, allOperations.size())
                    .filter(h -> entry.getId()==allOperations.get(h).getId())
                    .findFirst();
            allOperations.remove((int)index.orElse(0));

            OptionalInt index1 = IntStream.range(0, globalOpList.size())
                    .filter(h -> entry.getId()==globalOpList.get(h).getOp().getId())
                    .findFirst();
            globalOpList.remove((int)index1.orElse(0));

            chromosome.getMachineSelection().remove((int)index1.orElse(0));

            OptionalInt OperationIndex = IntStream.range(0, OperationSequencing.size())
                    .filter(i -> OperationSequencing.get(i).equals(entry.getGroupId())) // 过滤出值为1的索引
                    .findFirst();
            int targetOpIndex= OperationIndex.getAsInt();
            OperationSequencing.remove((int)targetOpIndex);

            OptionalInt OperationIndex1 = IntStream.range(0, ScheduleResults.size())
                    .filter(i -> ScheduleResults.get(i).getOperationId()==entry.getId()) // 过滤出值为1的索引
                    .findFirst();

//锁定需要删除
            ScheduleResults.remove((int)OperationIndex1.getAsInt());

        }


        AtomicInteger globalOpId = new AtomicInteger(0);
        globalOpList.forEach(t-> {

            t.setGlobalOpId(globalOpId.getAndIncrement());

        });

        // chromosome.getOperatRel().remove(GroupId-1);
        orders.remove(sourceorder);
        redecode(chromosome, chromosome.getBaseTime(), globalParam);

    }


    /**
     * 重新解码
     * @param chromosome 原方案
     * @param baseTime 基础时间
     * @param globalParam 全局参数
     */
    public void redecode(Chromosome chromosome,LocalDateTime baseTime, GlobalParam globalParam)
    {
        TreeMap<String, Material> baseMaterialsSnapshot = resolveDecodeMaterials(chromosome);
        chromosome.setResultOld(ProductionDeepCopyUtil.deepCopyList(chromosome.getResult(),GAScheduleResult.class));

        GeneticDecoder decoder = prepareDecodePass(chromosome, baseTime, globalParam, baseMaterialsSnapshot, true);
        decoder.decode(chromosome,false);

        KpiCalculator kpiCalculator=new KpiCalculator(chromosome);
        kpiCalculator.calculatekpi();

//        if(chromosome.getWeightedObjective()==0) {
//
//            double[] normalized = objectiveWeights.normalizeObjectives(chromosome.getObjectives(), null, null);
//            if (objectiveWeights.isPureNSGAIIMode()) {
//                chromosome.setWeightedObjective(objectiveWeights.calculateObjective(normalized));
//            } else {
//                chromosome.setWeightedObjective(objectiveWeights.calculateWeightedObjective(normalized));
//            }
//        }

//        if(chromosome.getFitness()==0) {
//            FitnessCalculator fitnessCalc = new FitnessCalculator();
//            chromosome.setFitness(fitnessCalc.calculateFitness(chromosome));
//        }

    }

    private GeneticDecoder prepareDecodePass(Chromosome chromosome, LocalDateTime baseTime, GlobalParam globalParam,
                                             TreeMap<String, Material> baseMaterialsSnapshot, boolean removeGeneratedOrders) {
        if (removeGeneratedOrders) {
            DelOrder(chromosome);
        }
        if (chromosome.getOrders() != null) {
            chromosome.getOrders().forEach(order -> order.setCreateBom(false));
        }

        resetDecodeMaterials(chromosome, baseMaterialsSnapshot);
        // 重解码前重新初始化物料需求缓存，同时给MaterialRequirementService设置本次排产基准时间。
        List<Material> decodeMaterials = chromosome.getMaterials() == null
                ? new ArrayList<>()
                : new ArrayList<>(chromosome.getMaterials().values());
        materialRequirementService.preloadRoutingCache(
                chromosome.getScenarioID(),
                baseTime,
                chromosome.getOrders(),
                decodeMaterials,
                chromosome.getAllOperations(),
                globalParam != null && globalParam.isIsCheckSf()
        );

        MachineSchedulerService machineScheduler = new MachineSchedulerService(baseTime);
        chromosome.setMachines(ProductionDeepCopyUtil.deepCopyList(chromosome.getInitMachines(),Machine.class) );

        chromosome.getResult().clear();
        chromosome.setResult(new CopyOnWriteArrayList<>());

        // BOM计算会使用decoder里的materials，自动插单重排也必须传入当前物料快照。
        return new GeneticDecoder(globalParam,baseTime, chromosome.getMachines(),
                chromosome.getOrders(), chromosome.getMaterials(), machineScheduler,materialRequirementService,chromosome.getScenarioID());
    }

    private TreeMap<String, Material> resolveDecodeMaterials(Chromosome chromosome) {
        TreeMap<String, Material> useMaterials = materialRequirementService.GetMaterials(chromosome.getScenarioID());
        if (useMaterials == null && chromosome.getMaterialIds() != null && chromosome.getMaterialIds().size() > 0) {
            List<Material> materials = planResultService.InitMaterial();

            useMaterials=  materialRequirementService.GetMaterialListToMap(materials);


        }
        if (useMaterials == null) {
            useMaterials = new TreeMap<>();
        }
        return ProductionDeepCopyUtil.deepCopyTreeMap(useMaterials, String.class, Material.class);
    }

    private void resetDecodeMaterials(Chromosome chromosome, TreeMap<String, Material> baseMaterialsSnapshot) {
        TreeMap<String, Material> materialsForDecode = ProductionDeepCopyUtil.deepCopyTreeMap(baseMaterialsSnapshot, String.class, Material.class);
        chromosome.setMaterials(materialsForDecode);
        materialRequirementService.SetMaterials(chromosome.getScenarioID(), materialsForDecode.entrySet().stream().map(Map.Entry::getValue)
                .collect(Collectors.toList()));
    }

    public void DelOrder(Chromosome chromosome) {
        List<Entry> allOperations = chromosome.getAllOperations();
        List<GlobalOperationInfo> globalOpList=  chromosome.getGlobalOpList();
        List<Order> orders = chromosome.getOrders();
        List<Integer> OperationSequencing=  chromosome.getOperationSequencing();
        List<GAScheduleResult> ScheduleResults = chromosome.getResult();
        List<Integer> newoorderids= orders.stream()
                .filter(t -> t.isNewCreate() || t.isNewSfCreate())
                .map(Order::getId)
                .sorted(Comparator.reverseOrder())
                .collect(Collectors.toList());
        if(newoorderids!=null&&newoorderids.size()>0) {
            for (Integer id : newoorderids) {


                List<Entry> sourceOps = allOperations.stream()
                        .filter(o -> o.getGroupId()==id)
                        .sorted(Comparator.comparing(Entry::getSequence))
                        .collect(Collectors.toList());

                for (Entry entry : sourceOps) {
                    OptionalInt index1 = IntStream.range(0, globalOpList.size())
                            .filter(h -> entry.getId()==globalOpList.get(h).getOp().getId())
                            .findFirst();
                    globalOpList.remove((int)index1.orElse(0));

                    chromosome.getMachineSelection().remove((int)index1.orElse(0));
                }

                chromosome.getOperatRel().remove(id-1);

            }
            allOperations.removeIf(t ->newoorderids.contains(t.getGroupId()));
            OperationSequencing.removeIf(t ->newoorderids.contains(t));
            AtomicInteger globalOpId = new AtomicInteger(0);
            globalOpList.forEach(t-> {

                t.setGlobalOpId(globalOpId.getAndIncrement());

            });
            orders.removeIf(t ->newoorderids.contains(t.getId()));
        }
    }

    public void editMachineOption(Chromosome chromosome,Entry operation,
                                  Long newMachineId, GlobalParam globalParam) {
        List<Entry> allOperations = chromosome.getAllOperations();

        Map<Integer, Integer> opTimeMap = chromosome.getResult().stream()
                .collect(Collectors.toMap(
                        GAScheduleResult::getOperationId,
                        r ->  r.getStartTime()
                ));
        Integer newMachineId1=newMachineId.intValue();

        int opId = operation.getId();
        // 获取目标结果和工序
        GAScheduleResult targetResult = chromosome.getResult().stream()
                .filter(r -> r.getOperationId() == opId)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));

        Entry targetOp = allOperations.stream()
                .filter(o -> o.getId() == opId)
                .findFirst()
                .orElseThrow(() -> new NoSuchElementException("Operation not found: " + opId));

        if(newMachineId1!=0) {
            int machineOptionIndex = targetOp.getMachineOptions().stream()
                    .map(MachineOption::getMachineId)
                    .collect(Collectors.toList())
                    .indexOf(newMachineId) + 1;

            if (machineOptionIndex == 0) {
                throw new NoSuchElementException("Machine not found: " + newMachineId);
            }


            // 更新设备选择序列
            int globalOpIndex = chromosome.getGlobalOpList().stream()
                    .filter(g -> g.getOp().getId() == opId)
                    .findFirst()
                    .map(GlobalOperationInfo::getGlobalOpId)
                    .orElseThrow(() -> new NoSuchElementException("Global operation not found: " + opId));


            chromosome.getMachineSelection().set(globalOpIndex, machineOptionIndex);
            targetResult.setForcedMachineId(newMachineId);
        }






        CopyOnWriteArrayList<Integer> operationSequencing = allOperations.stream()
                .sorted((op1, op2) -> {
                    int time1 = opTimeMap.getOrDefault(op1.getId(), Integer.MAX_VALUE);
                    int time2 = opTimeMap.getOrDefault(op2.getId(), Integer.MAX_VALUE);
                    if (time1 != time2) {
                        return Integer.compare(time1, time2);
                    } else {
                        return Integer.compare(op1.getSequence(), op2.getSequence());
                    }
                })
                .map(Entry::getGroupId)
                .collect(Collectors.toCollection(CopyOnWriteArrayList::new));

        chromosome.setOperationSequencing(operationSequencing);
// 重新解码
        redecode(chromosome, chromosome.getBaseTime(), globalParam);


    }


}
