package cn.iocoder.yudao.module.system.handler.mapnode;


import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.enums.NodeTypeEnum;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.NodeBaseDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.handler.mapnode.strategy.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class NodeProcessingContext {

    private final Map<Integer, NodeProcessingStrategy> strategyMap = new HashMap<>();
    @Autowired
    private MapNodeStrategyImpl mapNodeStrategyImpl;
    @Autowired
    private ChangeNodeStrategyImpl changeNodeStrategyImpl;
    @Autowired
    private HouseLocationStrategyImpl houseLocationStrategyImpl;
    @Autowired
    private ParkingSpotStrategyImpl parkingSpotStrategyImpl;
    @Autowired
    @Lazy
    private DeviceStrategyImpl deviceStrategyImpl;
    @Autowired
    private CheckStrategyImpl checkStrategyImpl;

    /**
     * 项目启动时 初始化策略
     */
    @PostConstruct
    public void init() {
        // 节点
        strategyMap.put(NodeTypeEnum.ROUTE.getType(), mapNodeStrategyImpl);
        // 库位
        strategyMap.put(NodeTypeEnum.WARE.getType(), houseLocationStrategyImpl);
        // 设备点
        strategyMap.put(NodeTypeEnum.DEVICE.getType(), deviceStrategyImpl);
        // 停车点
        strategyMap.put(NodeTypeEnum.PARKING.getType(), parkingSpotStrategyImpl);
        // 路径点
        strategyMap.put(NodeTypeEnum.CHANGE.getType(), changeNodeStrategyImpl);
        // 等待点
        strategyMap.put(NodeTypeEnum.WAIT.getType(), mapNodeStrategyImpl);
        // 文字点
        strategyMap.put(NodeTypeEnum.TEXT.getType(), mapNodeStrategyImpl);
        // 检测点
        strategyMap.put(NodeTypeEnum.CHECK.getType(), checkStrategyImpl);
        // todo 可以继续添加更多的策略 - 新增实现即可
    }

    @Transactional(rollbackFor = Exception.class)
    public List<PositionMapItemDO> processNodesByStrategy(Long positionMapId, int key, List<NodeBaseDTO> nodeBaseDTOS) {
        // -- 获取对应的策略 - 如果没有对应的直接 return
        NodeProcessingStrategy strategy = strategyMap.get(key);
        if (strategy == null) {
            return Collections.emptyList();
        }
        // 策略模式 策略实现 - 组装好数据后返回给上一层
        strategy.processNodes(positionMapId, nodeBaseDTOS);
        return BeanUtil.copyToList(nodeBaseDTOS, PositionMapItemDO.class);
    }
}
