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

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.NodeBaseDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionChangePointBindingDO;
import cn.iocoder.yudao.module.system.service.positionmap.PositionChangePointBindingService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.HOUSE_LOCATION_HAVE_TASK;

@Component
public class ChangeNodeStrategyImpl implements NodeProcessingStrategy {

    @Resource
    private PositionChangePointBindingService positionChangePointBindingService;

    @Override
    public void processNodes(Long positionMapId, List<NodeBaseDTO> nodeBaseDTOS) {

        List<PositionChangePointBindingDO> newList = new ArrayList<>();
        // -- 拿到这个地图所绑定的设备 -
        List<PositionChangePointBindingDO> oldList = positionChangePointBindingService.getPositionChangePointBindingByMapId(positionMapId);

        List<Long> startPointIds = new ArrayList<>();
        List<Long> endPointIds = new ArrayList<>();
        List<Long> sortNums = new ArrayList<>();

        for (NodeBaseDTO item : nodeBaseDTOS) {
            if (ObjectUtil.isEmpty(item.getDataJson())) {
                continue;
            }
            PositionChangePointBindingDO positionChangePointBindingDO = new PositionChangePointBindingDO();
            NodeBaseDTO nodeBase = JSONUtil.toBean(item.getDataJson(), NodeBaseDTO.class);

            if (sortNums.contains(nodeBase.getSortNum())) {
                throw exception0(HOUSE_LOCATION_HAVE_TASK.getCode(), "以下点位已经被选中: " + nodeBase.getSortNum(), nodeBase.getSortNum());
            }

            positionChangePointBindingDO.setPositionMapId(positionMapId);
            positionChangePointBindingDO.setStartingPointId(item.getId());
            positionChangePointBindingDO.setStartingPointSortNum(item.getSortNum());
            positionChangePointBindingDO.setEndPointId(nodeBase.getId());
            positionChangePointBindingDO.setEndPointSortNum(nodeBase.getSortNum());
            newList.add(positionChangePointBindingDO);
            startPointIds.add(item.getId());
            endPointIds.add(nodeBase.getId());
            sortNums.add(item.getSortNum());
            sortNums.add(nodeBase.getSortNum());
        }

        //判断这些点是否被绑定过
        if (ObjectUtil.isNotEmpty(endPointIds)) {
            List<PositionChangePointBindingDO> existList = positionChangePointBindingService.getByMapIdAndEndPointIds(positionMapId, endPointIds);
            if (ObjectUtil.isNotEmpty(existList)) {
                List<Long> sortNumList = existList.stream().map(PositionChangePointBindingDO::getEndPointSortNum).collect(Collectors.toList());
                String join = StringUtils.join(sortNumList, ",");
                throw exception0(HOUSE_LOCATION_HAVE_TASK.getCode(), "以下区域变更点已经被其他地图绑定:"+join,join);
            }

            List<PositionChangePointBindingDO> existBindingList = positionChangePointBindingService.getByMapIdAndStartPointIds(positionMapId, endPointIds,startPointIds);
            if (ObjectUtil.isNotEmpty(existBindingList)) {
                List<Long> sortNumList = existBindingList.stream().map(PositionChangePointBindingDO::getStartingPointSortNum).collect(Collectors.toList());
                String join = StringUtils.join(sortNumList, ",");
                throw exception0(HOUSE_LOCATION_HAVE_TASK.getCode(), "以下区域变更点绑定的点位错乱(出现A绑定B,B绑定C的情况):"+join,join);
            }
        }

        List<List<PositionChangePointBindingDO>> list = CollectionUtils.compareLists(oldList, newList,
                (oldVal, newVal) -> ObjectUtil.equal(oldVal.getEndPointId(), newVal.getEndPointId()));
        positionChangePointBindingService.batchEditOrDel(list);
    }
}
