package com.aps.service.Algorithm;

import com.aps.common.util.RangeSubtractUtil;
import com.aps.entity.*;
import com.aps.entity.Algorithm.DateRange;
import com.aps.entity.Algorithm.DependencyType;
import com.aps.entity.Algorithm.IDAndChildID.GroupResult;
import com.aps.entity.Algorithm.IDAndChildID.NodeInfo;
import com.aps.entity.Algorithm.OperationDependency;
import com.aps.entity.basic.*;
import com.aps.service.*;
import com.aps.service.plan.MachineSchedulerService;
import com.aps.service.plan.SceneService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 作者：佟礼
 * 时间：2025-12-09
 */
@Service
public class RoutingDataService {

    private static final int ORACLE_IN_BATCH_SIZE = 1000;

    @Autowired
    private ProdProcessExecService _prodProcessExecService;


    @Autowired
    private PlanResourceService _PlanResourceService;

    @Autowired
    private ProdOrderProcessService _prodOrderProcessService;

    @Autowired
    private  RoutingDiscreteParamService _routingDiscreteParamService;

    @Autowired
    private ProdEquipSpecialCalService _prodEquipSpecialCalService;

    @Autowired
    private EquipCapacityDefService _equipCapacityDefService;

    @Autowired
    private EquipMaintainTaskService _equipMaintainTaskService;

    @Autowired
    private SpecialCalendarService _specialCalendarService;

    @Autowired
    private SpecialCalendarDetailService _specialCalendarDetailService;

    @Autowired
    private MesShiftWorkSchedService _MesShiftWorkSchedService;
    @Autowired
    private EquipinfoService _equipinfoService;

    public Map<Integer, Object> InitEntrys(String SceneId, List<ProdEquipment> ProdEquipments, List<Order> ProdLaunchOrders)
    {
        return InitEntrys(SceneId, ProdEquipments, ProdLaunchOrders, null);
    }

    public Map<Integer, Object> InitEntrys(String SceneId, List<ProdEquipment> ProdEquipments, List<Order> ProdLaunchOrders, Map<String, Order> mergeMap)
    {
        Map<Integer, Object> list=new HashMap<>();
        List<ProdProcessExec> ProdProcessExecs=  _prodProcessExecService.lambdaQuery()
                .eq(ProdProcessExec::getSceneId,SceneId)
                .list();

// 获取op列表中所有的routingDetailId
        List<Long> routingDetailIds = ProdProcessExecs.stream()
                .map(ProdProcessExec::getRoutingDetailId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

// 查询RoutingDiscreteParam中routingDetailId在上述列表中的所有记录
        List<RoutingDiscreteParam> routingDiscreteParams = new ArrayList<>();
        if (!routingDetailIds.isEmpty()) {
            routingDiscreteParams = getRoutingDiscreteParamsByRoutingDetailIds(routingDetailIds);
        }


        List<ProdOrderProcess> ProdOrderProcesss = _prodOrderProcessService.lambdaQuery()
                .eq(ProdOrderProcess::getSceneId,SceneId)
                .list();

       return CreateEntry( SceneId,  ProdEquipments,  ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesss, ProdProcessExecs,null,0 );

    }

    private List<RoutingDiscreteParam> getRoutingDiscreteParamsByRoutingDetailIds(List<Long> routingDetailIds) {
        if (routingDetailIds == null || routingDetailIds.isEmpty()) {
            return new ArrayList<>();
        }

        List<RoutingDiscreteParam> routingDiscreteParams = new ArrayList<>();
        for (int i = 0; i < routingDetailIds.size(); i += ORACLE_IN_BATCH_SIZE) {
            int endIndex = Math.min(i + ORACLE_IN_BATCH_SIZE, routingDetailIds.size());
            List<Long> batchIds = routingDetailIds.subList(i, endIndex);

            List<RoutingDiscreteParam> batchParams = _routingDiscreteParamService.lambdaQuery()
                    .in(RoutingDiscreteParam::getRoutingDetailId, batchIds)
                    .eq(RoutingDiscreteParam::getIsDeleted, 0)
                    .list();
            routingDiscreteParams.addAll(batchParams);
        }
        return routingDiscreteParams;
    }

    public Map<Integer, Object> CreateEntry(String SceneId, List<ProdEquipment> ProdEquipments, List<Order> ProdLaunchOrders, List<RoutingDiscreteParam> routingDiscreteParams, List<ProdOrderProcess> ProdOrderProcesss, List<ProdProcessExec> ProdProcessExecs, List<GroupResult> existingResults,int FinishOpertionID)
    {
        return CreateEntry(SceneId, ProdEquipments, ProdLaunchOrders, routingDiscreteParams, ProdOrderProcesss, ProdProcessExecs, existingResults, FinishOpertionID, null);
    }

    public Map<Integer, Object> CreateEntry(String SceneId, List<ProdEquipment> ProdEquipments, List<Order> ProdLaunchOrders, List<RoutingDiscreteParam> routingDiscreteParams, List<ProdOrderProcess> ProdOrderProcesss, List<ProdProcessExec> ProdProcessExecs, List<GroupResult> existingResults,int FinishOpertionID, Map<String, Order> mergeMap)
    {
        Map<Integer, Object> list=new HashMap<>();
        List<String> soutceExecId = ProdOrderProcesss.stream()
                .map(ProdOrderProcess::getExecId)
               // .distinct() // 提取Exec_ID
                .collect(Collectors.toList());

        List<String> targetExecId = ProdOrderProcesss.stream()
                .map(ProdOrderProcess::getTargetExecId)
             //   .distinct() // 提取TARGET_Exec_ID
                .collect(Collectors.toList());

        List<String> ExecIdNoChild=  ProdProcessExecs.stream()
                .filter(e -> !soutceExecId.contains(e.getExecId())&&!targetExecId.contains(e.getExecId()))  // 过滤条件
                .map(ProdProcessExec::getExecId)
                .distinct()
                .collect(Collectors.toList());

        if(ExecIdNoChild!=null&&ExecIdNoChild.size()>0)
        {
            for (String ExecId : ExecIdNoChild) {
                soutceExecId.add(ExecId);
                targetExecId.add("");
            }
        }
        List<GroupResult> results;
        int index=0;
        if(existingResults==null||existingResults.size()==0) {
            results = IdGroupingWithDualSerial.groupAndOrderIds(soutceExecId, targetExecId);
        }else {
            index=existingResults.size();
            results = IdGroupingWithDualSerial.addNewDataWithIsolatedGroup(existingResults,soutceExecId, targetExecId);
        }

        List<Entry> entrys=new ArrayList<>();
        Map<Long,Double> machineIds=new HashMap<>();
        for (int i = index; i < results.size(); i++) {
            GroupResult groupResult = results.get(i);
            List<NodeInfo> nodeInfoList = groupResult.getNodeInfoList();
            // System.out.println("分组" + (i + 1) + "顺序：" + nodeInfoList);
            for (NodeInfo nodeInfo : nodeInfoList) {
//                System.out.printf("原始ID：%s → 全局序号：%d，分组内序号：%d，新父ID列表：%s，新子ID列表：%s%n",
//                        nodeInfo.getOriginalId(),
//                        nodeInfo.getGlobalSerial(),
//                        nodeInfo.getGroupSerial(),
//                        nodeInfo.getNewParentIds().isEmpty() ? "无" : nodeInfo.getNewParentIds(),
//                        nodeInfo.getNewChildIds());

                Entry entry = new Entry();
                entry.setSceneId(SceneId);
                entry.setId(nodeInfo.getGlobalSerial());
                entry.setGroupId(i + 1);
                entry.setSequence(nodeInfo.getGroupSerial());
                entry.setExecId(nodeInfo.getOriginalId());
                if(FinishOpertionID!=0) {
                    entry.setNewCreate(true);
                    entry.setTargetFinishedOperationId(new ArrayList<>());
                    entry.getTargetFinishedOperationId().add(FinishOpertionID);
                }
                ProdProcessExec op= ProdProcessExecs.stream()
                        .filter(t->t.getExecId().equals(entry.getExecId()))
                        .findFirst().orElse(null);
                if(nodeInfo.getNewParentIds()!=null)
                {

                    List<OperationDependency> OperationDependency=new ArrayList<>();
                    for (int id : nodeInfo.getNewParentIds()) {
                        OperationDependency od=new OperationDependency();
                        od.setPrevOperationId(id);

                        if (op != null) {
                            od.setDependencyType(DependencyType.fromValueSafe(op.getConnectProperty()));
                        } else {
                            od.setDependencyType(DependencyType.FinishToStart);
                        }
                        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);
                        // 记录属性
                        if (op != null) {
                            od.setDependencyType(DependencyType.fromValueSafe(op.getConnectProperty()));
                        } else {
                            od.setDependencyType(DependencyType.FinishToStart);
                        }
                        OperationDependency.add(od);
                    }
                    entry.setNextEntryIds(OperationDependency);
                }



                if(op!=null)
                {
                    entry.setDiscreteParameter(routingDiscreteParams.stream().filter(t -> t.getRoutingDetailId().equals(op.getRoutingDetailId())).collect(Collectors.toList()));
                    entry.setEquipTypeID(op.getMachineId());
                    entry.setEquipTypeName(op.getEquipTypeName());
                    entry.setEquipTypeCode(op.getEquipTypeCode());
                    entry.setRuntime(op.getRuntime());
                    entry.setSingleOut(op.getSingleOut());
                    //生产准备
                    entry.setSetupTime(op.getSetupTime());
                    //后处理
                    entry.setTeardownTime(op.getPostprocessingTime());
                    //前处理
                    entry.setPreTime(op.getPreprocessingTime());
                    entry.setConstTime(op.getConstTime());
                    entry.setOrderId(op.getOrderId());
                    entry.setOrderCode(op.getOrderCode());
                    entry.setQuantity(op.getPlanQty());
                    entry.setRoutingId(op.getRoutingId());
                    entry.setRoutingCode(op.getRoutingCode());
                    entry.setRoutingName(op.getRoutingName());
                    entry.setRoutingDetailId(op.getRoutingDetailId());
                    entry.setTaskSeq(op.getTaskSeq());
                    entry.setRoutingDetailName(op.getRoutingDetailName());
                    if (op.getDepartmentId() != null) {
                        entry.setDepartmentId(op.getDepartmentId());
                    }
                    entry.setIsInterrupt(op.getCanInterrupt());
                    Order order = findOrderByOrderId(ProdLaunchOrders, mergeMap, op.getOrderId());


                    if (order != null) {
                        entry.setOrderCode(order.getOrderCode());
                        entry.setProductId(order.getMaterialId());
                        entry.setProductCode(order.getMaterialCode());
                        entry.setProductName(order.getMaterialName());
                        entry.setPriority(order.getActualPriority());

                        order.setId(entry.getGroupId());
                    }
                    List<ProdEquipment> Equipments = ProdEquipments.stream()
                            .filter(t -> t.getExecId().equals(op.getExecId()))
                            .collect(Collectors.toList());
                    double minProcessingTime=999999999;
                    if (Equipments != null && Equipments.size() > 0) {
                        List<MachineOption> mos = new ArrayList<>();
                        for (ProdEquipment e : Equipments) {

                            Double totalprocessTime=0d;
                            if(op.getConstTime()==1)//常数时间
                            {
                                totalprocessTime=e.getSpeed();
                            }else {
                                totalprocessTime=e.getSpeed()/e.getSingleOut().doubleValue()*entry.getQuantity();

                            }
                            minProcessingTime=Math.min(minProcessingTime,totalprocessTime);
                            if(machineIds.containsKey(e.getEquipId()))
                            {
                               if( machineIds.get(e.getEquipId())<totalprocessTime)
                               {
                                   machineIds.replace(e.getEquipId(),totalprocessTime);
                               }
                            }else {
                                //大概记录要用到的设备的加工时间，用于生成设备日历
                                machineIds.put(e.getEquipId(),totalprocessTime);
                            }



                            MachineOption mo = new MachineOption();
                            mo.setMachineId(e.getEquipId());
                            mo.setRuntime(e.getRuntime());
                            mo.setSingleOut(e.getSingleOut());
                            mo.setEquipCode(e.getEquipCode());
                            mo.setEquipName(e.getEquipName());
                            mo.setResourceCode(e.getResourceCode());
                            mo.setProcessingTime(e.getSpeed());
                          //  mo.setContantTime(op.getConstTime());
                          //  mo.setSetupTime(op.getChangeLineTime());
                           // mo.setTeardownTime(op.getPostprocessingTime());
                           // mo.setPreTime(e.getSetupTime());


                            mos.add(mo);
                        }
entry.setMinProcessingTime(minProcessingTime);
                        entry.setMachineOptions(mos);
                    }
                }
if(entry.getMachineOptions()!=null)
{
    entrys.add(entry);
}

            }


        }
        list.put(1,entrys);
        list.put(2,results);
        list.put(3,machineIds);
        return  list;

    }
    private Order findOrderByOrderId(List<Order> orderList, Map<String, Order> mergeMap, String orderId) {
        if (mergeMap != null && mergeMap.containsKey(orderId)) {
            return mergeMap.get(orderId);
        }
        return orderList.stream()
                .filter(t -> t.getOrderId().equals(orderId))
                .findFirst().orElse(null);
    }
    public List<Machine> InitCalendarToAllMachines(String SceneId, List<ProdEquipment> ProdEquipments, MachineSchedulerService machineScheduler,boolean IsUseCalendar) {
        // 按设备分组

        List<Long> MachineIds = ProdEquipments.stream()
                .map(ProdEquipment::getEquipId)
                .distinct()
                .sorted()
                .collect(Collectors.toList());
        Map<Long, String> capacityTypeNameByEquipId = ProdEquipments.stream()
                .filter(t -> t.getEquipId() != null && t.getCapacityTypeName() != null)
                .collect(Collectors.toMap(
                        ProdEquipment::getEquipId,
                        ProdEquipment::getCapacityTypeName,
                        (existing, replacement) -> existing));

        List<Machine> machines = new ArrayList<>();
        List<PlanResource> PlanResources = _PlanResourceService.lambdaQuery()
                .eq(PlanResource::getIsdeleted, 0)
                .list();
        List<Equipinfo> equipinfoList = _equipinfoService.lambdaQuery()
                .eq(Equipinfo::getIsdeleted, 0)
                .list();
        for (Long id : MachineIds) {

            Machine machine = new Machine();
            machine.setId(id);
            machine.setCapacityTypeName(capacityTypeNameByEquipId.get(id));

            machine.setCode("");
            machine.setName("");
            machines.add(machine);

        }



        //节假日
        //  List<MesHoliday> holidays=  _MesHolidayService.list();
        if (IsUseCalendar) {
            LambdaQueryWrapper<ProdEquipSpecialCal> ProdEquipSpecialCalWrapper = new LambdaQueryWrapper<>();
            ProdEquipSpecialCalWrapper.eq(ProdEquipSpecialCal::getSceneId, SceneId);


            List<ProdEquipSpecialCal> ProdEquipSpecialCals = _prodEquipSpecialCalService.list(ProdEquipSpecialCalWrapper);

            List<MesShiftWorkSched> MesShiftWorkScheds = _MesShiftWorkSchedService.lambdaQuery()
                    .eq(MesShiftWorkSched::getIsdeleted, 0).list();


            if (machines == null) {
                return null;
            }

            for (Machine machine : machines) {
                // 确保维护窗口列表不为null
                if (machine.getMaintenanceWindows() == null) {
                    machine.setMaintenanceWindows(new ArrayList<>());
                }
                List<ProdEquipSpecialCal> machineProdEquipSpecialCals = ProdEquipSpecialCals.stream()
                        .filter(t -> t.getPlanResourceId() != null && t.getPlanResourceId() == machine.getId() && t.getReferenceType() == 1)
                        .collect(Collectors.toList());
                List<Shift> shifts1 = new ArrayList<>();
                for (ProdEquipSpecialCal machineProdEquipSpecialCal : machineProdEquipSpecialCals) {

                    List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
                            .filter(t -> (long) t.getWeekWorkSchedId() == machineProdEquipSpecialCal.getReferenceId())
                            .collect(Collectors.toList());
                    List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
                    for (Shift shift : Shifts) {

                        shift.setMachineId(machine.getId());
                        shift.setStartDate(machineProdEquipSpecialCal.getStartDate());
                        shift.setEndDate(machineProdEquipSpecialCal.getEndDate());
                        shifts1.add(shift);
                    }
                }
                PlanResource PlanResource = PlanResources.stream()
                        .filter(t -> t.getId() == machine.getId())
                        .findFirst().orElse(null);


                if (PlanResource != null) {
                    Equipinfo equipinfo= equipinfoList.stream()
                            .filter(t->t.getId().equals(PlanResource.getReferenceId()))
                            .findFirst().orElse(null);
                    machine.setDepartment(PlanResource.getDepartTitle());
                    if(equipinfo!=null)
                    {
                        machine.setCode(equipinfo.getEquipId());
                        machine.setName(equipinfo.getEquipName());
                        if (machine.getCapacityTypeName() == null) {
                            machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
                        }

                    }else {
                        machine.setCode(PlanResource.getReferenceCode());
                        machine.setName(PlanResource.getTitle());
                    }
                    List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
                            .filter(t -> (long) t.getWeekWorkSchedId() == PlanResource.getWorkSchedId())
                            .collect(Collectors.toList());
                    List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
                    for (Shift shift : Shifts) {

                        shift.setMachineId(machine.getId());

                        shift.setStartDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                        shift.setEndDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                        shifts1.add(shift);
                    }


                } else {
                    machine.setCode(Long.toString(machine.getId()));
                }
                if (shifts1 == null || shifts1.size() == 0) {
                    throw new RuntimeException(String.format("设备%s没有工作日历", machine.getCode().concat("_").concat(machine.getName())));
                }
                machine.setShifts(shifts1);

                List<ProdEquipSpecialCal> Holidays = ProdEquipSpecialCals.stream()
                        .filter(t -> t.getEquipId() == machine.getId() && t.getReferenceType() == 2)
                        .collect(Collectors.toList());
                List<Holiday> Holidays1 = new ArrayList<>();
                for (ProdEquipSpecialCal machineProdEquipSpecialCal : Holidays) {

                    Holiday holiday = new Holiday();
                    holiday.setStart(machineProdEquipSpecialCal.getStartDate());
                    holiday.setEnd(machineProdEquipSpecialCal.getEndDate());
                    Holidays1.add(holiday);
                }
                machine.setHolidays(Holidays1);


            }
        } else {
            for (Machine machine : machines) {

                PlanResource PlanResource = PlanResources.stream()
                        .filter(t -> t.getId() == machine.getId())
                        .findFirst().orElse(null);

                if (PlanResource != null) {
                    Equipinfo equipinfo= equipinfoList.stream()
                            .filter(t->t.getId().equals(PlanResource.getReferenceId()))
                            .findFirst().orElse(null);

                    machine.setDepartment(PlanResource.getDepartTitle());
                    if(equipinfo!=null)
                    {
                        machine.setCode(equipinfo.getEquipId());
                        machine.setName(equipinfo.getEquipName());
                        if (machine.getCapacityTypeName() == null) {
                            machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
                        }
                    }else {
                        machine.setCode(PlanResource.getReferenceCode());
                        machine.setName(PlanResource.getTitle());
                    }
                }




                List<Shift> shifts1 = new ArrayList<>();
                Shift shift=new Shift();
                shift.setMachineId(machine.getId());
                shift.setStartTime(LocalTime.of(0,0,0));
                shift.setEndTime(LocalTime.of(23,59,59));
                HashSet days= new HashSet<>();
                days.add(1);
                days.add(2);
                days.add(3);
                days.add(4);
                days.add(5);
                days.add(6);
                days.add(0);
                shift.setDays(days);
                shift.setStartDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                shift.setEndDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                shifts1.add(shift);
                machine.setShifts(shifts1);
            }
        }

        // 4. 初始化机器时间线
        for (Machine machine : machines) {
            MachineTimeline timeline = machineScheduler.getOrCreateTimeline(machine);
            machine.setAvailability(timeline.getSegments());
        }
        return machines;


    }

    public List<Machine> InitCalendarToAllMachines(MachineSchedulerService machineScheduler,LocalDateTime baseTime) {
        // 按设备分组



        List<Machine> machines = new ArrayList<>();
        List<PlanResource> PlanResources = _PlanResourceService.lambdaQuery()
                .eq(PlanResource::getIsdeleted, 0)
                .list();

        List<MesShiftWorkSched> MesShiftWorkScheds = _MesShiftWorkSchedService.lambdaQuery()
                .eq(MesShiftWorkSched::getIsdeleted, 0).list();

        //设备能力
        LambdaQueryWrapper<EquipCapacityDef> EquipSpecialCalWrapper = new LambdaQueryWrapper<>();
        EquipSpecialCalWrapper.eq(EquipCapacityDef::getIsDeleted, 0);


        List<EquipCapacityDef> ProdEquipSpecialCals = _equipCapacityDefService.list(EquipSpecialCalWrapper);

        //维修记录
        LambdaQueryWrapper<EquipMaintainTask> EquipMaintainTaskWrapper = new LambdaQueryWrapper<>();
        EquipMaintainTaskWrapper.eq(EquipMaintainTask::getIsdeleted, 0);
        EquipMaintainTaskWrapper.eq(EquipMaintainTask::getStatus, 0);
        EquipMaintainTaskWrapper.ge(EquipMaintainTask::getPlanFinishTime, baseTime);
        List<EquipMaintainTask> EquipMaintainTasks = _equipMaintainTaskService.list(EquipMaintainTaskWrapper);

        //特殊日历
        LambdaQueryWrapper<SpecialCalendar> SpecialCalendarWrapper = new LambdaQueryWrapper<>();
        SpecialCalendarWrapper.eq(SpecialCalendar::getIsDeleted, 0);

        List<SpecialCalendar> SpecialCalendars = _specialCalendarService.list(SpecialCalendarWrapper);

        //特殊日历
        LambdaQueryWrapper<SpecialCalendarDetail> SpecialCalendarDetailWrapper = new LambdaQueryWrapper<>();
        SpecialCalendarDetailWrapper.eq(SpecialCalendarDetail::getIsDeleted, 0);
       // SpecialCalendarDetailWrapper.ge(SpecialCalendarDetail::getEndTime, baseTime);

        List<SpecialCalendarDetail> SpecialCalendarDetails = _specialCalendarDetailService.list(SpecialCalendarDetailWrapper);
        List<Equipinfo> equipinfoList = _equipinfoService.lambdaQuery()
                .eq(Equipinfo::getIsdeleted, 0)
                .list();

        for (PlanResource resource : PlanResources) {
            Machine machine = new Machine();
            machine.setId(resource.getId());
            Equipinfo equipinfo= equipinfoList.stream()
                        .filter(t->t.getId().equals(resource.getReferenceId()))
                        .findFirst().orElse(null);
            machine.setDepartment(resource.getDepartTitle());
            if(equipinfo!=null)
            {
                machine.setCode(equipinfo.getEquipId());
                machine.setName(equipinfo.getEquipName());
                machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
            }else {
            machine.setCode(resource.getReferenceCode());
            machine.setName(resource.getTitle());
            }

                List<EquipCapacityDef> machineProdEquipSpecialCals = ProdEquipSpecialCals.stream()
                        .filter(t -> t.getPlanResourceId() != null &&t.getReferenceId() != null && t.getPlanResourceId() == machine.getId() && t.getReferenceType() == 1)
                        .collect(Collectors.toList());
                List<Shift> shifts1 = new ArrayList<>();
                for (EquipCapacityDef machineProdEquipSpecialCal : machineProdEquipSpecialCals) {

                    List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
                            .filter(t -> (long) t.getWeekWorkSchedId() == machineProdEquipSpecialCal.getReferenceId())
                            .collect(Collectors.toList());
                    List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
                    for (Shift shift : Shifts) {

                        shift.setMachineId(machine.getId());
                        shift.setStartDate(machineProdEquipSpecialCal.getEffectiveStartTime());
                        shift.setEndDate(machineProdEquipSpecialCal.getEffectiveEndTime());
                     if(machineProdEquipSpecialCal.getEfficiencyCoeff()!=null) {
                         shift.setEfficiency(machineProdEquipSpecialCal.getEfficiencyCoeff());
                     }
                        shifts1.add(shift);

                    }
                }



                if(resource.getWorkSchedId()!=null) {
                    List<MesShiftWorkSched> ShiftWorkScheds = MesShiftWorkScheds.stream()
                            .filter(t -> (long) t.getWeekWorkSchedId() == resource.getWorkSchedId())
                            .collect(Collectors.toList());
                    List<Shift> Shifts = mergeShiftData(ShiftWorkScheds);
                    for (Shift shift : Shifts) {

                        shift.setMachineId(machine.getId());

                        shift.setStartDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                        shift.setEndDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                        shifts1.add(shift);
                    }
                }else {
                    Shift shift=new Shift();
                    shift.setMachineId(machine.getId());
                    shift.setStartTime(LocalTime.of(0,0,0));
                    shift.setEndTime(LocalTime.of(23,59,59));
                    HashSet days= new HashSet<>();
                    days.add(1);
                    days.add(2);
                    days.add(3);
                    days.add(4);
                    days.add(5);
                    days.add(6);
                    days.add(0);
                    shift.setDays(days);
                    shift.setStartDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                    shift.setEndDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                    shifts1.add(shift);
                }
                machine.setShifts(shifts1);

                //加班
                List<EquipCapacityDef> machineProdEquipSpecialCals2 = ProdEquipSpecialCals.stream()
                        .filter(t -> t.getPlanResourceId() != null && t.getPlanResourceId() == machine.getId() && t.getReferenceType() == 3)
                        .collect(Collectors.toList());
                List<DateRange> shifts2 = new ArrayList<>();
                for (EquipCapacityDef machineProdEquipSpecialCal : machineProdEquipSpecialCals2) {
                        List<SpecialCalendarDetail> SpecialCalendarDetails1 = SpecialCalendarDetails.stream()
                                .filter(t -> (long) t.getSpecialCalendarId() == machineProdEquipSpecialCal.getReferenceId())
                                .collect(Collectors.toList());
                        for (SpecialCalendarDetail cald : SpecialCalendarDetails1) {
                            DateRange shift = new DateRange(cald.getStartTime(),cald.getEndTime());
                            shifts2.add(shift);
                        }

                }

                List<EquipCapacityDef> Holidays = ProdEquipSpecialCals.stream()
                        .filter(t -> t.getPlanResourceId() != null && t.getPlanResourceId() == machine.getId() && t.getReferenceType() == 2)
                        .collect(Collectors.toList());
                List<DateRange> shifts3 = new ArrayList<>();
                for (EquipCapacityDef machineProdEquipSpecialCal : Holidays) {

                    DateRange shift = new DateRange(machineProdEquipSpecialCal.getEffectiveStartTime(),machineProdEquipSpecialCal.getEffectiveEndTime());

                    shifts3.add(shift);
                }

                List<DateRange>  Holidaysn=  RangeSubtractUtil.getNonOverlappingRanges(shifts3,shifts2);

                List<Holiday> Holidays1 = new ArrayList<>();
                for (DateRange cal : Holidaysn) {

                    Holiday holiday = new Holiday();
                    holiday.setStart(cal.getStartDate());
                    holiday.setEnd(cal.getEndDate());
                    Holidays1.add(holiday);
                }
                machine.setHolidays(Holidays1);

                List<MaintenanceWindow> maintenanceWindows=new ArrayList<>();

                List<EquipMaintainTask> EquipMaintainTasks1 = EquipMaintainTasks.stream()
                        .filter(t -> t.getEquipId().equals(resource.getReferenceId()) )
                        .collect(Collectors.toList());
                for (EquipMaintainTask equipMaintainTask : EquipMaintainTasks1) {
                    MaintenanceWindow maintenanceWindow=new MaintenanceWindow();
//                    maintenanceWindow.setId(equipMaintainTask.getId().toString());
                    maintenanceWindow.setId(UUID.randomUUID().toString());
                    maintenanceWindow.setStartTime(equipMaintainTask.getPlanStartTime());
                    maintenanceWindow.setEndTime(equipMaintainTask.getPlanFinishTime());
                    maintenanceWindow.setEquipCode(equipMaintainTask.getEquipCode());
                    maintenanceWindow.setEquipName(equipMaintainTask.getEquipName());
                    maintenanceWindow.setReason("");
                    maintenanceWindows.add(maintenanceWindow);
                }

                machine.setMaintenanceWindows(maintenanceWindows);


            machines.add(machine);
        }



        // 4. 初始化机器时间线
        for (Machine machine : machines) {

            MachineTimeline timeline = machineScheduler.getOrCreateTimeline(machine,false);
            machine.setAvailability(timeline.getSegments());
        }


        return machines;


    }

    public List<Machine> InitNoCalendarToAllMachines(MachineSchedulerService machineScheduler,LocalDateTime baseTime) {
        // 按设备分组



        List<Machine> machines = new ArrayList<>();
        List<PlanResource> PlanResources = _PlanResourceService.lambdaQuery()
                .eq(PlanResource::getIsdeleted, 0)
                .list();

        //设备能力
        //维修记录
        LambdaQueryWrapper<EquipMaintainTask> EquipMaintainTaskWrapper = new LambdaQueryWrapper<>();
        EquipMaintainTaskWrapper.eq(EquipMaintainTask::getIsdeleted, 0);
        EquipMaintainTaskWrapper.eq(EquipMaintainTask::getStatus, 0);
        EquipMaintainTaskWrapper.ge(EquipMaintainTask::getPlanFinishTime, baseTime);
        List<EquipMaintainTask> EquipMaintainTasks = _equipMaintainTaskService.list(EquipMaintainTaskWrapper);


        for (PlanResource resource : PlanResources) {
            Machine machine = new Machine();
            machine.setId(resource.getId());
            machine.setCode(resource.getReferenceCode());
            machine.setName(resource.getTitle());
            Equipinfo equipinfo = _equipinfoService.lambdaQuery()
                    .eq(Equipinfo::getId, resource.getReferenceId())
                    .eq(Equipinfo::getIsdeleted, 0)
                    .one();
            if (equipinfo != null) {
                machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
            }


                List<Shift> shifts1 = new ArrayList<>();
                Shift shift=new Shift();
                shift.setMachineId(machine.getId());
                shift.setStartTime(LocalTime.of(0,0,0));
                shift.setEndTime(LocalTime.of(23,59,59));
                HashSet days= new HashSet<>();
                days.add(1);
                days.add(2);
                days.add(3);
                days.add(4);
                days.add(5);
                days.add(6);
                days.add(0);
                shift.setDays(days);

                shift.setStartDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                shift.setEndDate(LocalDateTime.of(2000, 1, 1, 0, 0, 0));
                shifts1.add(shift);
                machine.setShifts(shifts1);

            List<MaintenanceWindow> maintenanceWindows=new ArrayList<>();

            List<EquipMaintainTask> EquipMaintainTasks1 = EquipMaintainTasks.stream()
                    .filter(t -> t.getEquipId().equals(resource.getReferenceId()) )
                    .collect(Collectors.toList());
            for (EquipMaintainTask equipMaintainTask : EquipMaintainTasks1) {
                MaintenanceWindow maintenanceWindow=new MaintenanceWindow();

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

//                maintenanceWindow.setId(equipMaintainTask.getId().toString());
                maintenanceWindow.setStartTime(equipMaintainTask.getPlanStartTime());
                maintenanceWindow.setEndTime(equipMaintainTask.getPlanFinishTime());
                maintenanceWindow.setEquipCode(equipMaintainTask.getEquipCode());
                maintenanceWindow.setEquipName(equipMaintainTask.getEquipName());
                maintenanceWindow.setReason("");
                maintenanceWindows.add(maintenanceWindow);
            }

            machine.setMaintenanceWindows(maintenanceWindows);


            machines.add(machine);
        }



        // 4. 初始化机器时间线
        for (Machine machine : machines) {
            MachineTimeline timeline = machineScheduler.getOrCreateTimeline(machine);
            machine.setAvailability(timeline.getSegments());
        }
        return machines;


    }



    /**
     * 合并重复的ShiftData，将serialNumber收集为列表
     * @param originalList 原始数据列表
     * @return 合并后的MergedShiftData列表
     */
    public static List<Shift> mergeShiftData(List<MesShiftWorkSched> originalList) {
        // 按shiftStart和shiftEnd分组
        Map<String, Shift> groupMap = new HashMap<>();

        for (MesShiftWorkSched data : originalList) {
            // 用shiftStart+shiftEnd作为分组key
            String groupKey = data.getShiftStart().toString() + "_" + data.getShiftEnd().toString();
            // 将中文的星期几转换为英文格式（周日是0，周一到周日依次为0-6）
            // 假设数据库中startWeekDay是1-7（周一到周日），需要转换为0-6（周日到周六）
            int engDay = (data.getStartWeekDay() % 7); // 将1-7转换为0-6，其中周日为0

            if (groupMap.containsKey(groupKey)) {
                // 已存在分组：添加serialNumber到列表
                Shift merged = groupMap.get(groupKey);
                merged.getDays().add(engDay);
            } else {
                // 新分组：创建MergedShiftData并初始化
                Shift merged = new Shift();

                merged.setStartTime(data.getShiftStart().toLocalTime());
                merged.setEndTime(data.getShiftEnd().toLocalTime());
                merged.setStatus(0);

                // 初始化序号列表
                Set<Integer> serials =new HashSet<>();
                serials.add(engDay);
                merged.setDays(serials);
                groupMap.put(groupKey, merged);
            }
        }

        // 转换为列表返回
        return new ArrayList<>(groupMap.values());
    }

}
