package com.aps.controller.gantt;


import cn.hutool.core.bean.BeanUtil;
import com.aps.common.util.ParamValidator;
import com.aps.common.util.R;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.basic.ScheduleChromosome;
import com.aps.entity.Gantt.ProductGanttVO;
import com.aps.entity.Gantt.ResourceGanttVO;
import com.aps.entity.Gantt.SupplyRelationResponse;
import com.aps.entity.Gantt.TaskVO;
import com.aps.entity.basic.*;
import com.aps.entity.common.Paged;
import com.aps.entity.common.ConditionEntity;
import com.aps.service.plan.PlanResultService;
import com.aps.service.plan.PlanSchedulerService;
import com.aps.service.plan.SceneService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


import java.time.LocalDateTime;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/Gantt")
@Tag(name = "甘特图管理", description = "甘特图管理")
public class ResourceGanttController {

    @Autowired
    private PlanResultService planResultService;

    @Autowired
    private SceneService sceneService;



    @GetMapping("/resourceGantt1")
    @Operation(summary = "获取资源甘特图数据", description = "获取资源甘特图数据")
    public List<ResourceGanttVO> getResourceGantt1(@RequestParam(required = false, defaultValue = "1") Long sceneId) {
        // 从PlanResultService获取ScheduleChromosome列表
        List<ScheduleChromosome> scheduleChromosomes = planResultService.execute();

        // 根据sceneId查找对应的ScheduleChromosome
        ScheduleChromosome targetChromosome = null;
        for (ScheduleChromosome chromosome : scheduleChromosomes) {
            if (chromosome.getSceneId() == sceneId) {
                targetChromosome = chromosome;
                break;
            }
        }

        // 如果找不到对应的场景，返回空列表
        if (targetChromosome == null) {
            return new ArrayList<>();
        }

        // 转换为 ResourceGanttVO 格式
        List<ResourceGanttVO> resourceGanttVOList = new ArrayList<>();
        List<ResourceGanttVO> resourceGanttVOs = convertToResourceGanttVO(targetChromosome);
        resourceGanttVOList.addAll(resourceGanttVOs);

        return resourceGanttVOList;
    }

    @GetMapping("/productGantt1")
    @Operation(summary = "获取产品甘特图数据", description = "获取产品甘特图数据")
    public List<ProductGanttVO> getProductGantt1(@RequestParam String sceneId) {
        // 从PlanResultService获取ScheduleChromosome列表
        List<ScheduleChromosome> scheduleChromosomes = planResultService.execute();

        // 根据sceneId查找对应的ScheduleChromosome
        ScheduleChromosome targetChromosome = null;
        for (ScheduleChromosome chromosome : scheduleChromosomes) {
            if (chromosome.getSceneId() == 1)  {
                targetChromosome = chromosome;
                break;
            }
        }

        // 如果找不到对应的场景，返回空列表
        if (targetChromosome == null) {
            return new ArrayList<>();
        }

        // 转换为 ProductGanttVO 格式
        List<ProductGanttVO> productGanttVOList = new ArrayList<>();
        List<ProductGanttVO> productGanttVOs = convertToProductGanttVO(targetChromosome);
        productGanttVOList.addAll(productGanttVOs);

        return productGanttVOList;
    }

    @GetMapping("/sceneIds")
    @Operation(summary = "获取所有场景ID", description = "获取所有场景ID")
    public List<String> getSceneIds() {
//        // 调用 PlanResultService 获取 ScheduleChromosome 列表
//        List<ScheduleChromosome> scheduleChromosomes = planResultService.execute();
//
//
//
//        // 提取所有场景ID
//        return scheduleChromosomes.stream()
//                .map(ScheduleChromosome::getSceneId)
//                .collect(Collectors.toList());

        ArrayList<String> strings = new ArrayList<>();
        strings.add("B571EF6682DB463AB2977B1055A74112");
        return strings;

    }





    @GetMapping("/SyncMaterials")
    @Operation(summary = "更新物料信息缓存", description = "更新物料信息缓存")
    public void SyncMaterials() {
        // 调用 PlanResultService 获取 ScheduleChromosome 列表
        planResultService.getMaterials();

    }

    @GetMapping("/SyncMachine")
    @Operation(summary = "更新设备信息缓存", description = "更新设备信息缓存")
    public void SyncMachines() {
        // 调用 PlanResultService 获取 ScheduleChromosome 列表
        planResultService.InitCalendarToAllMachines();

    }




    @PostMapping("/editOrder")
    @Operation(summary = "修改订单", description = "编辑场景中的订单信息",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "编辑订单参数",
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "编辑订单示例",
                                    value = "{\n  \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n  \"order\": {  }\n}"
                            )
                    )
            )
    )
    public R<Chromosome> editOrder(@RequestBody Map<String, Object> params) {
        log.info("editOrder 请求参数: {}", params);

            String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
            ParamValidator.validateSceneExists(sceneService, sceneId);

            // 使用BeanUtil转换LinkedHashMap为Order对象
            Order order = BeanUtil.toBean(params.get("order"), Order.class);

            Chromosome result = planResultService.EditOrder(sceneId, order);
            return R.ok(result);


    }





    @PostMapping("/operationMove")
    @Operation(summary = "操作移动", description = "操作移动")
    public R<String> operationMove(@RequestBody Map<String, Object> params) {

        // 1. 提取参数
        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        Integer opid = ParamValidator.getInteger(params, "id", "操作ID");
        LocalDateTime newStartTime = ParamValidator.getDateTime(params, "newStartTime", "新的开始时间");
        Long newMachineId = ParamValidator.getLong(params, "newMachineId", "新机器ID");

        // 2. 验证场景
        ParamValidator.validateSceneExists(sceneService, sceneId);

        // 将单个opid放入List中
        List<Integer> opids = new ArrayList<>();
        opids.add(opid);

        // 3. 执行业务
        Chromosome result = planResultService.Move(sceneId, opids, newStartTime, newMachineId,0);

        return R.ok("移动成功");
    }

    @PostMapping("/operationBlockMove")
    @Operation(summary = "移动工作块", description = "移动工作块")
    public R<String> operationBlockMove(@RequestBody Map<String, Object> params) {

        // 1. 提取参数
        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        List opid = ParamValidator.getList(params, "id", "操作ID");
        LocalDateTime newStartTime = ParamValidator.getDateTime(params, "newStartTime", "新的开始时间");
        Long newMachineId = ParamValidator.getLong(params, "newMachineId", "新机器ID");

        // 2. 验证场景
        ParamValidator.validateSceneExists(sceneService, sceneId);

       List<Integer> opids = ParamValidator.convertToIntArray(opid, "操作IDS");


        // 3. 执行业务
        Chromosome result = planResultService.Move(sceneId, opids, newStartTime, newMachineId,0);

        return R.ok("移动成功");
    }



    @PostMapping("/fixStartDate")
    @Operation(summary = "固定开始日期", description = "固定开始日期")
    public R<String> fixStartDate(@RequestBody Map<String, Object> params) {

        // 1. 提取参数
        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        Integer opid = ParamValidator.getInteger(params, "id", "操作ID");
        LocalDateTime newStartTime = ParamValidator.getDateTime(params, "newStartTime", "新的开始时间");


        // 2. 验证场景
        ParamValidator.validateSceneExists(sceneService, sceneId);

//        List<Integer> opids = ParamValidator.convertToIntArray(opid, "操作IDS");

        List<Integer> opids = new ArrayList<>();
        opids.add(opid);

        // 3. 执行业务
        Chromosome result = planResultService.Move(sceneId, opids, newStartTime, 0L,1);

        return R.ok("固定开始日期成功");
    }



    @PostMapping("/editOperation")
    @Operation(summary = "修改工单", description = "修改工单")
    public R<Chromosome> operationEdit(@RequestBody Map<String, Object> params) {
        log.info("operationEdit 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        // 使用BeanUtil转换LinkedHashMap为Entry对象
        Entry entry = BeanUtil.toBean(params.get("entry"), Entry.class);

        Chromosome result = planResultService.EditOperation(sceneId, entry);
        return R.ok(result);
    }

    @PostMapping("/editMachineOption")
    @Operation(summary = "修改机器选项", description = "修改工序的机器选项",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "修改机器选项参数",
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "修改机器选项示例",
                                    value = "{\n  \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n  \"entry\": {\n    \"id\": 1,\n    \"groupId\": 1,\n    \"sequence\": 1,\n    \"orderId\": \"ORDER001\",\n    \"orderCode\": \"订单编号\",\n    \"productId\": 1,\n    \"productName\": \"产品名称\",\n    \"productCode\": \"产品编号\",\n    \"routingId\": 1,\n    \"routingDetailId\": 1,\n    \"execId\": \"EXEC001\",\n    \"orderId\": \"ORDER001\",\n    \"orderCode\": \"订单编号\",\n    \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n    \"mainId\": \"MAIN001\",\n    \"priority\": 1,\n    \"quantity\": 100,\n    \"sequence\": 1,\n    \"machineOptions\": [],\n    \"selectMachineID\": 1,\n    \"prevEntryIds\": [],\n    \"nextEntryIds\": [],\n    \"state\": 1,\n    \"isInterrupt\": 1,\n    \"materialRequirements\": []\n  },\n  \"newMachineId\": 123\n}"
                            )
                    )
            )
    )
    public R<Chromosome> editMachineOption(@RequestBody Map<String, Object> params) {
        log.info("editMachineOption 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        // 使用BeanUtil转换LinkedHashMap为Entry对象
        Entry entry = BeanUtil.toBean(params.get("entry"), Entry.class);
        Long newMachineId = ParamValidator.getLong(params, "newMachineId", "新机器ID");

        Chromosome result = planResultService.editMachineOption(sceneId, entry, newMachineId);
        return R.ok(result);
    }

    @PostMapping("/changebasetime")
    @Operation(summary = "修改基础时间", description = "修改基础时间")
    public R<String> changeBaseTime(@RequestBody Map<String, Object> params) {
        log.info("changeBaseTime 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        LocalDateTime baseTime = ParamValidator.getDateTime(params, "baseTime", "基础时间");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.ChangeBaseTime(sceneId, baseTime);
        return R.ok("保存成功");
    }

    @PostMapping("/operationspilt")
    @Operation(summary = "工单拆分", description = "工单拆分")
    public R<String> spiltOperation(@RequestBody Map<String, Object> params) {
        log.info("spiltOperation 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        Integer opid = ParamValidator.getInteger(params, "id", "操作ID");
        List<?> splitCounts = ParamValidator.getList(params, "splitCounts", "拆分数量");

        // 类型转换
        Double[] splitCountsArray = ParamValidator.convertToDoubleArray(splitCounts, "拆分数量");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.SpiltOperation(sceneId, opid, splitCountsArray);
        return R.ok("拆分成功");
    }




    @PostMapping("/operationdel")
    @Operation(summary = "删除工单", description = "删除工单")
    public R<String> delOperation(@RequestBody Map<String, Object> params) {
        log.info("delOperation 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        Integer opid = ParamValidator.getInteger(params, "id", "操作ID");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.DelOperation(sceneId, opid);
        return R.ok("删除成功");
    }

    @PostMapping("/orderDel")
    @Operation(summary = "删除订单", description = "删除订单")
    public R<Chromosome> delOrder(@RequestBody Map<String, Object> params) {
        log.info("delOperation 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        String orderid = ParamValidator.getString(params, "orderId", "订单ID");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.DelOrder(sceneId, orderid);
        return R.ok(result);
    }

    @PostMapping("/operationlocked")
    @Operation(summary = "工单锁定", description = "订工单锁定")
    public R<String> lockedOperation(@RequestBody Map<String, Object> params) {
        log.info("lockedOperation 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        Integer opid = ParamValidator.getInteger(params, "id", "操作ID");
        Boolean isLocked = ParamValidator.getBoolean(params, "locked", "锁定状态");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.LockOperation(sceneId, opid, isLocked);
        return R.ok("锁定成功");
    }

    @PostMapping("/orderspilt")
    @Operation(summary = "订单拆分", description = "订单拆分")
    public R<String> spiltOrder(@RequestBody Map<String, Object> params) {
        log.info("spiltOrder 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        String orderid = ParamValidator.getString(params, "orderId", "订单ID");
        List<?> splitCounts = ParamValidator.getList(params, "splitCounts", "拆分数量");

        Double[] splitCountsArray = ParamValidator.convertToDoubleArray(splitCounts, "拆分数量");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.SpiltOrder(sceneId, orderid, splitCountsArray);
        return R.ok("拆分成功");
    }



    @PostMapping("/orderCopy")
    @Operation(summary = "订单复制", description = "订单复制")
    public R<String> copyOrder(@RequestBody Map<String, Object> params) {
        log.info("copyOrder 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        String orderid = ParamValidator.getString(params, "orderId", "订单ID");
        Double copyCount = ParamValidator.getDouble(params, "copyCount", "复制数量");

        Double[] splitCountsArray = new Double[2]; // 创建一个空的Double数组，可以根据实际需求调整大小或初始化值
        splitCountsArray[0] = 0.0;
        splitCountsArray[1] = copyCount;

        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.SpiltOrder(sceneId, orderid, splitCountsArray);
        return R.ok("复制成功");
    }

    @PostMapping("/orderInsert")
    @Operation(summary = "订单插单", description = "在指定订单后插入新订单")
    public R<String> insertOrder(@RequestBody Map<String, Object> params) {
        log.info("insertOrder 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        String afterOrderId = ParamValidator.getString(params, "afterOrderId", "插入位置订单ID");
        
        // 获取新订单信息
        @SuppressWarnings("unchecked")
        Map<String, Object> newOrderData = (Map<String, Object>) params.get("newOrder");

        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.InsertOrder(sceneId, afterOrderId, newOrderData);
        return R.ok("插单成功");
    }

    @PostMapping("/orderInsertAuto")
    @Operation(
            summary = "自动插单",
            description = "按neworder数据结构自动插入新订单",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "订单插单参数",
                    required = true,
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "neworder示例",
                                    value = "{\n" +
                                            "  \"sceneId\": \"C4EF4B6DC74E43F78D2EA4102B12066D\",\n" +
                                            "  \"neworder\": {\n" +
                                            "    \"zoneid\": \"36\",\n" +
                                            "    \"isconsume\": 0,\n" +
                                            "    \"settle\": 0,\n" +
                                            "    \"delay\": 0,\n" +
                                            "    \"part\": 0,\n" +
                                            "    \"islock\": 0,\n" +
                                            "    \"isinsert\": 0,\n" +
                                            "    \"mmid\": \"fff9efd4-8fc3-495f-acfe-dbefee3dc9cc\",\n" +
                                            "    \"mmname\": \"0.9%氯化钠注射液\",\n" +
                                            "    \"mmcode\": \"153004_ZHJ24046\",\n" +
                                            "    \"unit\": \"万袋\",\n" +
                                            "    \"unitId\": 12,\n" +
                                            "    \"series\": \"153004_ZHJ24046\",\n" +
                                            "    \"seriesId\": 648,\n" +
                                            "    \"seriesName\": \"153004_ZHJ24046\",\n" +
                                            "    \"code\": \"DDBH_20260522_2\",\n" +
                                            "    \"zone\": \"33331\",\n" +
                                            "    \"customerid\": 41,\n" +
                                            "    \"customer\": \"远景\",\n" +
                                            "    \"deliverytime\": \"2026-05-05T00:00:00.00+08:00\",\n" +
                                            "    \"prioritry\": \"5\",\n" +
                                            "    \"stockid\": 617,\n" +
                                            "    \"stock\": \"测试\",\n" +
                                            "    \"price\": 5,\n" +
                                            "    \"quantity\": 55,\n" +
                                            "    \"begintime\": \"2026-05-01T00:00:00.00+08:00\"\n" +
                                            "  }\n" +
                                            "}"
                            )
                    )
            )
    )
    public R<String> insertOrderAuto(@RequestBody Map<String, Object> params) {
        log.info("insertOrderAuto 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        @SuppressWarnings("unchecked")
        Map<String, Object> newOrderData = (Map<String, Object>) params.get("neworder");
        if (newOrderData == null) {
            @SuppressWarnings("unchecked")
            Map<String, Object> fallbackNewOrderData = (Map<String, Object>) params.get("newOrder");
            newOrderData = fallbackNewOrderData;
        }
        if (newOrderData == null) {
            throw new IllegalArgumentException("neworder 不能为空");
        }

        ParamValidator.validateSceneExists(sceneService, sceneId);

        planResultService.InsertOrderAuto(sceneId, convertNewOrderPayload(newOrderData));
        return R.ok("插单成功");
    }

    @PostMapping("/orderInsertAutoOld")
    @Operation(
            summary = "自动插单旧接口",
            description = "创建新工单并按基准时间+冻结期自动排程。若锚点被占用，则占位工单及后续工单后移；若前面有空挡，新工单自动前移到设备最早可用时间",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "自动插单参数",
                    required = true,
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = {
                                    @io.swagger.v3.oas.annotations.media.ExampleObject(
                                            name = "自动插单示例",
                                            summary = "基础示例",
                                            value = "{\n" +
                                                    "  \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
                                                    "  \"newOrder\": {\n" +
                                                    "    \"orderCode\": \"AUTO_20260326_001\",\n" +
                                                    "    \"materialId\": \"d5d0dd08-cfb5-2b45-85e9-aba470895423\",\n" +
                                                    "    \"quantity\": 610000\n" +
                                                    "  }\n" +
                                                    "}"
                                    ),
                                    @io.swagger.v3.oas.annotations.media.ExampleObject(
                                            name = "大批量示例",
                                            summary = "大批量订单",
                                            value = "{\n" +
                                                    "  \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n" +
                                                    "  \"newOrder\": {\n" +
                                                    "    \"orderCode\": \"AUTO_20260326_002\",\n" +
                                                    "    \"materialId\": \"cbd0dd08-49b1-0146-83bd-ec6185316c16\",\n" +
                                                    "    \"quantity\": 1200000\n" +
                                                    "  }\n" +
                                                    "}"
                                    )
                            }
                    )
            )
    )
    public R<String> insertOrderAutoOld(@RequestBody Map<String, Object> params) {
        log.info("insertOrderAutoOld 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        @SuppressWarnings("unchecked")
        Map<String, Object> newOrderData = (Map<String, Object>) params.get("newOrder");

        ParamValidator.validateSceneExists(sceneService, sceneId);

      //  planResultService.InsertOrderAuto(sceneId, newOrderData);
        return R.ok("自动插单成功");
    }


    @PostMapping("/ordermerge")
    @Operation(summary = "订单合并", description = "订单合并")
    public R<String> orderMerge(@RequestBody Map<String, Object> params) {
        log.info("orderMerge 请求参数: {}", params);

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        String sourceorderid = ParamValidator.getString(params, "sourceorderid", "源订单ID");
        String targetorderid = ParamValidator.getString(params, "targetorderid", "目标订单ID");
        ParamValidator.validateSceneExists(sceneService, sceneId);

        Chromosome result = planResultService.MergeOrder(sceneId, sourceorderid, targetorderid);
        return R.ok("合并成功");
    }

    /**
     * 将 ScheduleChromosome 转换为 ResourceGanttVO 列表
     * @param scheduleChromosome 调度结果
     * @return 转换后的数据
     */
    private List<ResourceGanttVO> convertToResourceGanttVO(ScheduleChromosome scheduleChromosome) {
        List<ResourceGanttVO> resourceGanttVOList = new ArrayList<>();

        // 遍历所有机器资源
        if (scheduleChromosome.getMachines() != null) {
            for (int i = 0; i < scheduleChromosome.getMachines().size(); i++) {
                Machine machine = scheduleChromosome.getMachines().get(i);

                ResourceGanttVO resourceGanttVO = new ResourceGanttVO();
                resourceGanttVO.setId(machine.getId());
                resourceGanttVO.setName(machine.getName() != null ? machine.getName() : "设备-" + machine.getId());
                resourceGanttVO.setType("设备类型"+machine.getId()); // 需要从原始数据获取
                resourceGanttVO.setChange(0); // 默认值
                resourceGanttVO.setSplit(0); // 默认值
                resourceGanttVO.setDepartmentId(machine.getId()); // 默认值
                resourceGanttVO.setDepartmentName(machine.getId()+"号线"); // 默认值
                resourceGanttVO.setShopName(machine.getId()+"车间"); // 默认值
                resourceGanttVO.setShopId(machine.getId()); // 默认值
                resourceGanttVO.setCode("设备编码-" + machine.getId()); // 默认值
                resourceGanttVO.setShift(convertToVO(machine));
                // 转换任务列表
                List<TaskVO> taskVOList = new ArrayList<>();
                if (scheduleChromosome.getGenes() != null) {
                    // 筛选出属于当前设备的任务
                    List<Gene> machineGenes = scheduleChromosome.getGenes().stream()
                            .filter(gene -> gene.getMachineId()==(machine.getId()))
                            .collect(Collectors.toList());

                    // 按开始时间排序
                    machineGenes.sort((g1, g2) -> Integer.compare(g1.getStartTime(), g2.getStartTime()));

                    for (Gene gene : machineGenes) {
                        TaskVO taskVO = new TaskVO();
                        taskVO.setId(String.valueOf(gene.getId())); // 临时处理
                        taskVO.setPlanId(String.valueOf(gene.getOrderId())); // 默认值
                        taskVO.setProductType(0); // 默认值
                        taskVO.setProductName("产品"+gene.getProductId());
                        taskVO.setProductId(String.valueOf(gene.getProductId())); // 默认值
                        taskVO.setQuantity(gene.getBatchSize());
                        taskVO.setStart(scheduleChromosome.getBaseTime().plusMinutes(gene.getAbsoluteStartTime()));
                        taskVO.setEnd(scheduleChromosome.getBaseTime().plusMinutes(gene.getAbsoluteEndTime()));
                        taskVO.setSetup(gene.getAbsolutePreparationTime()*60); // 默认值
                        taskVO.setTeardown(gene.getAbsoluteTeardownTime()*60); // 默认值
                        taskVO.setEquipChange(gene.getSetupTime()*60); // 默认值
                        taskVO.setEquipCooling(0); // 默认值
                        taskVO.setEquipType(resourceGanttVO.getType());
                        taskVO.setEquipName(resourceGanttVO.getName());
//                        taskVO.setDuration(calculateDuration(
//                                scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()),
//                                scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime()))); // 计算持续时间

                        taskVO.setDuration(0); //
                        taskVO.setEquipId(machine.getId());
                        taskVO.setShopId(machine.getId());
                        taskVO.setShopName(resourceGanttVO.getShopName());
                        taskVO.setStatus(0); // 默认值

                        taskVO.setDetailId((long) gene.getProductId() * 1000 + gene.getOperationId()); // 将productId和operationID组合为detailId
                        taskVO.setHeaderId(gene.getProductId()); // 默认值
                        taskVO.setHeaderName("工艺"+gene.getProductId()); // 默认值
                        taskVO.setSeq(gene.getSequenceId()); // 使用工序ID
                        taskVO.setSeqName( "工序名称"+gene.getSequenceId());
                        taskVO.setProcessingTime((int)gene.getProcessingTime()*60);
                        taskVO.setAbsoluteStart(scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()));
                        taskVO.setAbsoluteEnd(scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime()));
                        taskVOList.add(taskVO);

                        // 调试：检查machine中的shifts状态
//                        if (machine.getShifts() != null) {
//                            for (Shift shift : machine.getShifts()) {
//                                System.out.println("Before setting shifts - Shift status: " + shift.getStatus());
//                            }
//                        }

                        taskVO.setAbsolutePreparationTime(gene.getTeardownTime());



                    }
                }

                resourceGanttVO.setList(taskVOList);
                resourceGanttVOList.add(resourceGanttVO);
            }
        }

        return resourceGanttVOList;
    }

    /**
     * 将 ScheduleChromosome 转换为 ProductGanttVO 列表
     * @param scheduleChromosome 调度结果
     * @return 转换后的数据
     */
    private List<ProductGanttVO> convertToProductGanttVO(ScheduleChromosome scheduleChromosome) {
        List<ProductGanttVO> productGanttVOList = new ArrayList<>();

        // 按产品ID和工单ID分组基因
        if (scheduleChromosome.getGenes() != null) {
            // 按工单ID分组
            scheduleChromosome.getGenes().stream()
                    .collect(Collectors.groupingBy(Gene::getOrderId))
                    .forEach((orderId, genes) -> {
                        if (!genes.isEmpty()) {
                            ProductGanttVO productGanttVO = new ProductGanttVO();
                            Gene firstGene = genes.get(0);
                            productGanttVO.setId(String.valueOf(firstGene.getId()));
                            productGanttVO.setProductName("产品"+firstGene.getProductId()); // 默认值，实际应从订单数据获取
                            productGanttVO.setProductType(0);
                            productGanttVO.setProductId(String.valueOf(firstGene.getProductId()));
                            // 计算总数量（假设同一批次）
                            productGanttVO.setQuantity(firstGene.getBatchSize());
                            productGanttVO.setCode("编号"+firstGene.getProductId()); // 默认值
                            productGanttVO.setShopId(firstGene.getMachineId()); // 默认值
                            productGanttVO.setShopName(firstGene.getMachineId()+"号线"); // 默认值
                            productGanttVO.setStatus("已发布");
                            productGanttVO.setHeaderId(firstGene.getProductId());
                            productGanttVO.setHeaderName("工艺"+firstGene.getProductId()); // 默认值

                            // 计算开始和结束时间
                            int minStartTime = genes.stream()
                                    .mapToInt(Gene::getStartTime)
                                    .min()
                                    .orElse(0);
                            int maxEndTime = genes.stream()
                                    .mapToInt(Gene::getEndTime)
                                    .max()
                                    .orElse(0);

                            productGanttVO.setStartDate(scheduleChromosome.getBaseTime().plusMinutes(minStartTime));
                            productGanttVO.setEndDate(scheduleChromosome.getBaseTime().plusMinutes(maxEndTime));

                            // 转换任务列表
                            List<TaskVO> taskVOList = new ArrayList<>();
                            // 按工序顺序排序
                            genes.sort((g1, g2) -> Integer.compare(g1.getSequenceId(), g2.getSequenceId()));

                            for (int i = 0; i < genes.size(); i++) {
                                Gene gene = genes.get(i);
                                TaskVO taskVO = new TaskVO();
                                taskVO.setId(String.valueOf(gene.getId())); // 生成唯一ID
                                taskVO.setPlanId(String.valueOf(orderId));
                                taskVO.setProductType(0);
                                taskVO.setProductName("产品"+gene.getProductId());
                                taskVO.setProductId(String.valueOf(gene.getProductId()));
                                taskVO.setQuantity(gene.getBatchSize());
                                taskVO.setStart(scheduleChromosome.getBaseTime().plusMinutes(gene.getAbsoluteStartTime()));
                                taskVO.setEnd(scheduleChromosome.getBaseTime().plusMinutes(gene.getAbsoluteEndTime()));
                                taskVO.setSetup(gene.getAbsolutePreparationTime()*60); // 默认值
                                taskVO.setTeardown(gene.getAbsoluteTeardownTime()*60); // 默认값
                                taskVO.setEquipChange(gene.getSetupTime()*60); // 默认값
                                taskVO.setEquipCooling(0); // 默认值
//                            taskVO.setEquipType("PTT-" + (i+1) + "-" + gene.getOperationName().toUpperCase().substring(0, Math.min(3, gene.getOperationName().length())));
//                            taskVO.setEquipName(gene.getOperationName());
                                taskVO.setDuration(calculateDuration(
                                        scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()),
                                        scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime())));
                                taskVO.setEquipId(gene.getMachineId()); // 生成设备ID
                                taskVO.setShopId(gene.getMachineId());
                                taskVO.setShopName(gene.getMachineId()+"车间");
                                taskVO.setStatus(0);
                                taskVO.setDetailId((long) gene.getProductId() * 1000 + gene.getOperationId());
                                taskVO.setHeaderId(gene.getProductId());
                                taskVO.setHeaderName("工艺"+gene.getProductId());
                                taskVO.setSeq(gene.getSequenceId());
                                taskVO.setSeqName("工序名称"+gene.getSequenceId());
                                taskVO.setAbsoluteStart(scheduleChromosome.getBaseTime().plusMinutes(gene.getStartTime()));
                                taskVO.setAbsoluteEnd(scheduleChromosome.getBaseTime().plusMinutes(gene.getEndTime()));

                                taskVOList.add(taskVO);
                            }

                            productGanttVO.setList(taskVOList);
                            productGanttVOList.add(productGanttVO);
                        }
                    });
        }

        return productGanttVOList;
    }

    /**
     * 计算任务持续时间（分钟）
     * @param start 开始时间
     * @param end 结束时间
     * @return 持续时间（分钟）
     */
    private Integer calculateDuration(LocalDateTime start, LocalDateTime end) {
        if (start == null || end == null) {
            return 0;
        }
        return Math.toIntExact(java.time.Duration.between(start, end).toMinutes());
    }


    private ShiftVO convertToVO(Machine machine) {
        ShiftVO shiftVO= new ShiftVO();
        shiftVO.setId(machine.getId());
        shiftVO.setName(machine.getName());
        shiftVO.setShifts(machine.getShifts());
        shiftVO.setMaintenanceWindows(machine.getMaintenanceWindows());
        // 注意：tasks 字段需要在其他地方设置，因为 Machine 类中没有任务信息
        return shiftVO;
    }





    @GetMapping("/productGantt")
    @Operation(summary = "获取工单甘特图数据", description = "获取工单甘特图数据")
    public List<ProductGanttVO> productGantt(@RequestParam String sceneId) {
        // 从PlanResultService获取ScheduleChromosome列表
        Chromosome schedule = sceneService.loadChromosomeFromFile(sceneId);
        if ( schedule == null) {
            return new ArrayList<>();
        }

        // 转换为 ProductGanttVO 格式
        List<ProductGanttVO> productGanttVOList= new ArrayList<>();
        List<ProductGanttVO> resourceGanttVOs = planResultService.convertToProductGanttVO1(schedule);
        productGanttVOList.addAll(resourceGanttVOs);

        return productGanttVOList;
    }


    @GetMapping("/resourceGantt")
    @Operation(summary = "获取资源甘特图数据", description = "获取资源甘特图数据")
    public List<ResourceGanttVO> resourceGantt(@RequestParam String sceneId) {
        // 从PlanResultService获取ScheduleChromosome列表
        Chromosome schedule = sceneService.loadChromosomeFromFile(sceneId);
        // 如果找不到对应的场景，返回空列表
        if ( schedule == null) {
            return new ArrayList<>();
        }

        List<Machine> machineList = planResultService.InitCalendarToAllMachines3(schedule);

        // 转换为 ResourceGanttVO 格式
        List<ResourceGanttVO> resourceGanttVOList = new ArrayList<>();
        List<ResourceGanttVO> resourceGanttVOs = planResultService.convertToResourceGanttVO1(schedule, machineList);
        resourceGanttVOList.addAll(resourceGanttVOs);

        return resourceGanttVOList;
    }



    @PostMapping("/getResourceGantt")
    @Operation(summary = "获取资源甘特图数据", description = "获取资源甘特图数据")
    public R<List<ResourceGanttVO>> getResourceGantt(@RequestBody Map<String, Object> params) {
        // 从参数中获取sceneId
        String sceneId = (String) params.get("sceneId");

        // 校验sceneId是否存在
        if (sceneId == null || sceneId.isEmpty()) {
            throw new IllegalArgumentException("场景ID不能为空");
        }

        // 校验能否获取对应的文件
        Chromosome schedule = sceneService.loadChromosomeFromFile(sceneId);
        if (schedule == null) {
            throw new RuntimeException("未找到对应的场景文件");
        }

        List<Machine> machineList = planResultService.InitCalendarToAllMachines2(sceneId);

        // 转换为 ResourceGanttVO 格式
        List<ResourceGanttVO> resourceGanttVOList = new ArrayList<>();
        List<ResourceGanttVO> resourceGanttVOs = planResultService.convertToResourceGanttVO1(schedule, machineList);
        resourceGanttVOList.addAll(resourceGanttVOs);

        System.out.println("完成甘特图请求");
        return R.ok(resourceGanttVOList);
    }

    @PostMapping("/getResourceGantt/page")
    @Operation(summary = "获取资源甘特图分页数据", description = "获取资源甘特图分页数据，设备全部返回，工单需要分页并按时间顺序排序")
    public R<Map<String, Object>> getResourceGanttPage(@RequestBody Paged paged) {
        // 从Paged对象中获取sceneId
        String sceneId = null;
        ConditionEntity sceneIdCondition = paged.getCondition("sceneId");
        if (sceneIdCondition != null) {
            sceneId = sceneIdCondition.getFieldValue();
        }

        // 校验参数
        if (sceneId == null || sceneId.isEmpty()) {
            throw new IllegalArgumentException("场景ID不能为空");
        }

        // 获取分页参数
        Integer pageindex = paged.getPageIndex() != null ? Math.max(1, paged.getPageIndex()) : 1;
        Integer pagesize = paged.getPageSize() != null ? paged.getPageSize() : 1000;

        // 校验能否获取对应的文件
        Chromosome schedule = sceneService.loadChromosomeFromFile(sceneId);
        if (schedule == null) {
            throw new RuntimeException("未找到对应的场景文件");
        }

        List<Machine> machineList = planResultService.InitCalendarToAllMachines2(sceneId);

        // 转换为 ResourceGanttVO 格式
        List<ResourceGanttVO> resourceGanttVOList = new ArrayList<>();
        List<ResourceGanttVO> resourceGanttVOs = planResultService.convertToResourceGanttVO1(schedule, machineList);
        resourceGanttVOList.addAll(resourceGanttVOs);

        // 分离设备和工单数据
        List<ResourceGanttVO> equipmentList = new ArrayList<>();
        List<TaskVO> orderList = new ArrayList<>();

        for (ResourceGanttVO resourceGanttVO : resourceGanttVOList) {
            equipmentList.add(resourceGanttVO);
            // 收集所有工单数据
            if (resourceGanttVO.getList() != null && !resourceGanttVO.getList().isEmpty()) {
                orderList.addAll(resourceGanttVO.getList());
            }
        }

        // 工单按开始时间排序（时间早的在前）
        orderList.sort((o1, o2) -> {
            if (o1.getStart() == null) return 1;
            if (o2.getStart() == null) return -1;
            return o1.getStart().compareTo(o2.getStart());
        });

        // 计算工单总数
        int totalOrders = orderList.size();

        // 执行工单分页
        int startIndex = (pageindex - 1) * pagesize;
        int endIndex = Math.min(startIndex + pagesize, totalOrders);
        List<TaskVO> pageOrders;
        if (startIndex < totalOrders) {
            pageOrders = orderList.subList(startIndex, endIndex);
        } else {
            pageOrders = new ArrayList<>();
        }

        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("equipment", equipmentList); // 设备全部返回
        result.put("orders", pageOrders); // 工单分页返回
        result.put("totalOrders", totalOrders); // 工单总数
        result.put("pageindex", pageindex); // 当前页码
        result.put("pagesize", pagesize); // 每页大小

        System.out.println("完成资源甘特图分页请求");
        return R.ok(result);
    }




    @PostMapping("/getProductGantt")
    @Operation(summary = "获取产品甘特图数据", description = "获取产品甘特图数据")
    public R<List<ProductGanttVO>> getProductGantt(@RequestBody Map<String, Object> params) {
        // 从参数中获取sceneId
        String sceneId = (String) params.get("sceneId");

        // 校验sceneId是否存在
        if (sceneId == null || sceneId.isEmpty()) {
            throw new IllegalArgumentException("场景ID不能为空");
        }

        // 校验能否获取对应的文件
        Chromosome schedule = sceneService.loadChromosomeFromFile(sceneId);
        if (schedule == null) {
            throw new RuntimeException("未找到对应的场景文件");
        }

        // 转换为 ProductGanttVO 格式
        List<ProductGanttVO> productGanttVOList= new ArrayList<>();
        List<ProductGanttVO> resourceGanttVOs = planResultService.convertToProductGanttVO1(schedule);
        productGanttVOList.addAll(resourceGanttVOs);

        return R.ok(productGanttVOList);
    }

    @PostMapping("/getProductGantt/page")
    @Operation(summary = "获取工单分页数据", description = "获取工单分页数据，pagesize为每页工单个数，pageindex为当前页码")
    public R<Map<String, Object>> getProductGanttPage(@RequestBody Paged paged) {
        // 从Paged对象中获取sceneId
        String sceneId = null;
        ConditionEntity sceneIdCondition = paged.getCondition("sceneId");
        if (sceneIdCondition != null) {
            sceneId = sceneIdCondition.getFieldValue();
        }

        // 校验参数
        if (sceneId == null || sceneId.isEmpty()) {
            throw new IllegalArgumentException("场景ID不能为空");
        }

        // 获取分页参数
        Integer pageindex = paged.getPageIndex() != null ? Math.max(1, paged.getPageIndex()) : 1;
        Integer pagesize = paged.getPageSize() != null ? paged.getPageSize() : 1000;

        // 校验能否获取对应的文件
        Chromosome schedule = sceneService.loadChromosomeFromFile(sceneId);
        if (schedule == null) {
            throw new RuntimeException("未找到对应的场景文件");
        }

        // 转换为 ProductGanttVO 格式
        List<ProductGanttVO> productGanttVOs = planResultService.convertToProductGanttVO1(schedule);

        // 计算总记录数
        int total = productGanttVOs.size();

        // 计算分页参数
        int startIndex = (pageindex - 1) * pagesize;
        int endIndex = Math.min(startIndex + pagesize, total);

        // 执行分页
        List<ProductGanttVO> pageData = new ArrayList<>();
        if (startIndex < total) {
            pageData = productGanttVOs.subList(startIndex, endIndex);
        }

        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("total", total);
        result.put("pageindex", pageindex);
        result.put("pagesize", pagesize);
        result.put("data", pageData);

        return R.ok(result);
    }



    /**
     * 移动染色体到指定版本
     *
     * @param params 参数Map
     * @return 染色体对象
     */
    @PostMapping("/revert")
    @Operation(summary = "撤销操作", description = "撤销操作")
    public R<String> revert(@RequestBody Map<String, Object> params) {

            String sceneId = ParamValidator.getString(params, "sceneId", "场景ID不能为空");
            if (sceneId == null ) {
                return R.failed("场景ID和版本号不能为空");
            }

            Chromosome result = planResultService.moveChromosome(sceneId, 0);
            return R.ok("撤销成功");

    }


    @PostMapping("/getSceneVersion")
    @Operation(summary = "获取版本号", description = "获取所有版本号")
    public R<List<Integer>> getSceneVersion(@RequestBody Map<String, Object> params) {
        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        List<Integer> numbers = planResultService.getSceneFileNumbers(sceneId);
        return R.ok(numbers);
    }



    @PostMapping("/getSceneVersionWithIndex")
    @Operation(summary = "获取版本号及当前索引", description = "获取版本号列表及当前版本在列表中的索引",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "获取版本号及当前索引参数",
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "获取版本号及当前索引示例",
                                    value = "{\n  \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\"\n}"
                            )
                    )
            )
    )
    public R<Map<String, Object>> getSceneVersionWithIndex(@RequestBody Map<String, Object> params) {
        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        Map<String, Object> versionData = planResultService.getSceneVersion(sceneId);
        return R.ok(versionData);
    }

    @PostMapping("/getSceneVersionWithIndexPreview")
    @Operation(summary = "获取版本号、当前索引和甘特概览", description = "返回版本信息，并按资源甘特数据统计场景时间、工单、订单、设备和预览图")
    public R<Map<String, Object>> getSceneVersionWithIndexPreview(
            @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "previewWidth、previewHeight 为可选字段，用于控制返回 preview 图片尺寸。",
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "获取版本和缩略图示例",
                                    value = "{\n  \"sceneId\": \"F397427A76754E33A5655C41A7D0BC4A\",\n  \"previewWidth\": 896,\n  \"previewHeight\": 20\n}"
                            )
                    )
            )
            @RequestBody Map<String, Object> params) {
        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        return R.ok(planResultService.getSceneVersionWithIndexPreview(sceneId, params));
    }

    @PostMapping("/revertVersion")
    @Operation(summary = "撤销操作", description = "撤销操作",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "撤销操作参数",
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "撤销操作示例",
                                    value = "{\n  \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n  \"version\": 1\n}"
                            )
                    )
            )
    )
    public R<String> revertVersion(@RequestBody Map<String, Object> params) {

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID不能为空");
        Integer version = ParamValidator.getInteger(params, "version", "版本号不能为空");
        if (sceneId == null ) {
            return R.failed("场景ID和版本号不能为空");
        }

        Chromosome result = planResultService.revertVersion(sceneId, version);
        return R.ok("撤销成功");

    }




    @PostMapping("/unFixStartDate")
    @Operation(summary = "取消固定开始日期", description = "取消固定开始日期",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "取消固定开始日期参数",
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "取消固定开始日期示例",
                                    value = "{\n  \"sceneId\": \"B571EF6682DB463AB2977B1055A74112\",\n  \"id\": 123\n}"
                            )
                    )
            )
    )
    public R<String> unFixStartDate(@RequestBody Map<String, Object> params) {

        // 1. 提取参数
        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        Integer opid = ParamValidator.getInteger(params, "id", "操作ID");


        // 2. 验证场景
        ParamValidator.validateSceneExists(sceneService, sceneId);

        planResultService.UnlockStartTime(sceneId, opid);

        return R.ok("取消固定开始日期成功");
    }


    @PostMapping("/operationDrag")
    @Operation(summary = "工单拖拽排序", description = "工单拖拽排序",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "工单拖拽排序",
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "工单拖拽排序示例",
                                    value = "{\n  \"sceneId\": \"F2EAE9B2786349A2B950CEB0FD108807\",\n  \"id\": [9,3],\n  \"targetOpId\": 13,\n  \"isFront\": true,\n  \"newMachineId\": 1263\n}"
                            )
                    )
            )
    )
    public R<String> operationDrag(@RequestBody Map<String, Object> params) {
        log.info("operationDrag 请求参数: {}", params);
        // 验证场景

        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");

        Integer targetOpId = ParamValidator.getInteger(params, "targetOpId", "目标操作ID");
        Boolean isFront = ParamValidator.getBoolean(params, "isFront", "是否前置");
        Long newMachineId = ParamValidator.getLong(params, "newMachineId", "新机器ID");
        List opId = ParamValidator.getList(params, "id", "操作ID");
        List<Integer>  opIds= ParamValidator.convertToIntArray(opId, "操作IDS");
        ParamValidator.validateSceneExists(sceneService, sceneId);



        // 执行拖拽操作
        Chromosome result = planResultService.Drag(sceneId,opIds, targetOpId, isFront, newMachineId);
        return R.ok("工单拖拽排序成功");
    }

    @PostMapping("/supplyRelation")
    @Operation(summary = "获取供给关系", description = "根据工单工序ID获取其供给关系",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "获取供给关系参数",
                    content = @io.swagger.v3.oas.annotations.media.Content(
                            mediaType = "application/json",
                            examples = @io.swagger.v3.oas.annotations.media.ExampleObject(
                                    name = "获取供给关系示例",
                                    value = "{\n  \"sceneId\": \"7044578FAF8D488B96197ED77920CFBA\",\n  \"id\": 6\n}"
                            )
                    )
            )

    )
    public R<List<Object>> getSupplyRelation(@RequestBody Map<String, Object> params) {
        log.info("getSupplyRelation 请求参数: {}", params);
        // 提取参数
        String sceneId = ParamValidator.getString(params, "sceneId", "场景ID");
        Integer entryId = ParamValidator.getInteger(params, "id", "工序ID");
//        ParamValidator.validateSceneExists(sceneService, sceneId);

        // 调用服务获取供给关系
        List<Object> data = planResultService.getSupplyRelation(sceneId, entryId, sceneService);
        return R.ok(data);
    }

    private Map<String, Object> convertNewOrderPayload(Map<String, Object> source) {
        Map<String, Object> target = new HashMap<>(source);
        target.put("orderCode", requireValue(source, "订单编号", "orderCode", "code"));
        target.put("materialId", requireValue(source, "物料ID", "materialId", "mmid"));
        target.put("quantity", requireValue(source, "数量", "quantity"));

        Object startDate = firstValue(source, "startDate", "begintime");
        if (startDate != null) {
            target.put("startDate", startDate);
        }

        Object endDate = firstValue(source, "endDate", "deliverytime");
        if (endDate != null) {
            target.put("endDate", endDate);
        }

        Object priority = firstValue(source, "priority", "prioritry");
        if (priority != null) {
            target.put("priority", priority);
        }

        return target;
    }

    private Object requireValue(Map<String, Object> source, String fieldName, String... keys) {
        Object value = firstValue(source, keys);
        if (value == null || String.valueOf(value).trim().isEmpty()) {
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
        return value;
    }

    private Object firstValue(Map<String, Object> source, String... keys) {
        if (source == null || keys == null) {
            return null;
        }
        for (String key : keys) {
            Object value = source.get(key);
            if (value != null && !String.valueOf(value).trim().isEmpty()) {
                return value;
            }
        }
        return null;
    }

}
