package com.persagy.proxy.relation.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.dmp.basic.dto.RequestData;
import com.persagy.dmp.basic.model.QueryCriteria;
import com.persagy.dmp.digital.client.DigitalObjectFacade;
import com.persagy.dmp.digital.entity.ObjectDigital;
import com.persagy.dmp.digital.entity.ObjectRelation;
import com.persagy.proxy.adm.constant.AdmCommonConstant;
import com.persagy.proxy.adm.constant.AdmDictCategoryEnum;
import com.persagy.proxy.adm.request.AdmResponse;
import com.persagy.proxy.adm.service.IAdmRelationService;
import com.persagy.proxy.adm.utils.AdmContextUtil;
import com.persagy.proxy.common.client.DmpRwdClient;
import com.persagy.proxy.common.entity.InstanceUrlParam;
import com.persagy.proxy.common.entity.RelationDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * @description:024、关系-空间关系
 * @author:lgy
 * @data:2021/9/24 11:53
 */
@RestController
@RequestMapping("/rel/sp-rel")
public class RelationSpaceConnectionController {

    @Autowired
    private IAdmRelationService service;
    @Autowired
    DmpRwdClient rwdClient;

//    //默认图类型 业务空间（同类）邻接关系
//    public static final String DEFAULT_GRAPH_CODE = "SpaceNeighborhood";
//    //None	空间隔断无门窗
//    public static final String REL_CODE_NONE = "None";
//    //Door	空间隔断有门
//    public static final String REL_CODE_DOOR = "Door";
//    //Window	空间隔断有窗
//    public static final String REL_CODE_WINDOW = "Window";
//    //DoorWindow	空间隔断有门窗
//    public static final String REL_CODE_DOORWINDOW = "DoorWindow";
//    //Connect	空间连通
//    public static final String REL_CODE_CONNECT = "Connect";

    /**
     * 创创建邻接关系
     * 图类型 GraphType：空间邻接关系 SpaceNeighborhood 建筑交通关系 TrafficNetwork  空气流通关系  ConvectionNetwork  光照辐射关系  RadiationNetwork
     *
     * @param param
     * @return
     * @throws Exception
     */
    @PostMapping(value = {"/space-neighborhood-Create"})
    public AdmResponse spaceNeighborhood(@RequestBody JSONObject param) throws Exception {
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        JSONArray contentList = param.getJSONArray("content");
        for (int i = 0; i < contentList.size(); i++) {
            JSONObject content = contentList.getJSONObject(i);
            String spaceIdOne = content.getString("spaceIdOne");
            String spaceIdTwo = content.getString("spaceIdTwo");
            String graphType = content.getString("graphType");
            String relType = content.getString("relType");
            String zoneType = content.getString("zoneType");
            if (!StrUtil.isAllNotEmpty(graphType, spaceIdTwo, spaceIdOne, relType)) {
                return AdmResponse.failure("请检查数据的完整性");
            }
            if (StrUtil.isEmpty(zoneType)) {
                QueryCriteria queryCriteria = new QueryCriteria();
                ObjectNode criteria = JsonNodeFactory.instance.objectNode();
                criteria.put("id", spaceIdOne);
                queryCriteria.setCriteria(criteria);
                List<ObjectNode> objectNodeList = DigitalObjectFacade.query(context.getGroupCode(),
                        context.getProjectId(), AdmCommonConstant.APP_ID, context.getUserId(), queryCriteria);
                if (CollUtil.isNotEmpty(objectNodeList)) {
                    String classCode = objectNodeList.get(0).get("classCode").asText();
                    content.put("zoneType", classCode);
                }
            }
        }
        for (int i = 0; i < contentList.size(); i++) {
            JSONObject content = contentList.getJSONObject(i);
            String spaceIdOne = content.getString("spaceIdOne");
            String spaceIdTwo = content.getString("spaceIdTwo");
            String graphType = content.getString("graphType");
            String relType = content.getString("relType");
            String zoneType = content.getString("zoneType");
            QueryCriteria queryRequest = new QueryCriteria();
            ObjectNode node = JsonNodeFactory.instance.objectNode();
            node.put("graphCode", graphType);
            node.put("relCode", relType);
            node.put("relValue", zoneType);
            node.put("objFrom", spaceIdOne);
            node.put("objTo", spaceIdTwo);
            queryRequest.setCriteria(node);
            service.doDelete(context, queryRequest);
            // 创建关系对象
            List<RelationDTO> voList = new ArrayList<>();
            voList.add(new RelationDTO(null, graphType, relType, zoneType, spaceIdOne, spaceIdTwo));
            service.doSave(context, voList);
        }
        return AdmResponse.success();
    }

    /**
     * 查询空间关系
     * " 楼层id FloorId   图类型 GraphType:空间邻接关系 SpaceNeighborhood 建筑交通关系 TrafficNetwork  空气流通关系  ConvectionNetwork  光照辐射关系  RadiationNetwork ，边类型RelType
     *
     * @param param
     * @return 创建的结果信息
     */
    @PostMapping("/space-neighborhood-query")
    public AdmResponse spaceNeighborhoodQuery(@RequestBody JSONObject param) throws Exception {
        //原接口传入一个filter进行过滤，不清楚具体参数前无法兼容该接口
        //TODO:
        return AdmResponse.failure("不支持该接口");
    }

    /**
     * 删除某一个关系
     * 为了防止误删，边类型也改成了必填项
     *
     * @param paramList 对象
     * @return 删除的结果信息
     */
    @PostMapping("/delete")
    public AdmResponse delete(@RequestBody JSONArray paramList) throws Exception {
        if (CollUtil.isEmpty(paramList)) {
            return AdmResponse.success();
        }
        for (int i = 0; i < paramList.size(); i++) {
            JSONObject param = paramList.getJSONObject(i);
            String spaceIdOne = param.getString("spaceIdOne");
            String spaceIdTwo = param.getString("spaceIdTwo");
            String graphType = param.getString("graphType");
            String relType = param.getString("relType");
            String zoneType = param.getString("zoneType");
            if (!StrUtil.isAllNotEmpty(spaceIdOne, spaceIdTwo, graphType, relType, zoneType)) {
                return AdmResponse.failure("必填: SpaceIdOne、SpaceIdTwo、GraphType、ZoneType、relType");
            }
        }
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        for (int i = 0; i < paramList.size(); i++) {
            JSONObject param = paramList.getJSONObject(i);
            String spaceIdOne = param.getString("spaceIdOne");
            String spaceIdTwo = param.getString("spaceIdTwo");
            String graphType = param.getString("graphType");
            String relType = param.getString("relType");
            String zoneType = param.getString("zoneType");
            if (!StrUtil.isAllNotEmpty(spaceIdOne, spaceIdTwo, graphType, relType, zoneType)) {
                return AdmResponse.failure("必填: SpaceIdOne、SpaceIdTwo、GraphType、ZoneType、relType");
            }
            QueryCriteria criteria = new QueryCriteria();
            ObjectNode node = JsonNodeFactory.instance.objectNode();
            node.put("graphCode", graphType);
            node.put("relCode", relType);
            node.put("relValue", zoneType);
            node.put("objFrom", spaceIdOne);
            node.put("objTo", spaceIdTwo);
            criteria.setCriteria(node);
            service.doDelete(context, criteria);
            //无方向的关系应该只删除一次，下面的应该不需要，为了防止可能出现的有方向的关系，此处额外删除一次
            ObjectNode node2 = JsonNodeFactory.instance.objectNode();
            node2.put("graphCode", graphType);
            node2.put("relCode", relType);
            node2.put("relValue", zoneType);
            node2.put("objFrom", spaceIdTwo);
            node2.put("objTo", spaceIdOne);
            criteria.setCriteria(node2);
            service.doDelete(context, criteria);
        }
        return AdmResponse.success();
    }

    /**
     * 清除某个楼层下的数据
     *
     * @param param 竖井和业务空间的关系对象
     * @return 创建的结果信息
     */
    @PostMapping("/delete-floor")
    public AdmResponse createSpshs(@RequestBody JSONObject param) throws Exception {
        String graphType = param.getString("graphType");
        String relType = param.getString("relType");
        String zoneType = param.getString("zoneType");
        String floorId = param.getString("floorId");
        if (!StrUtil.isAllNotEmpty(graphType, relType, zoneType, floorId)) {
            return AdmResponse.failure("必填 graphType、floorId、ZoneType、relType");
        }
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        RequestData requestData = RequestData.builder().classCode(zoneType).floorId(floorId)
                .projectId(context.getProjectId()).objType(AdmDictCategoryEnum.SPACE.getValue()).build();
        //关系查询空间id
        List<ObjectDigital> objectDigitals = DigitalObjectFacade.queryObjectListSuperiorId(context.getGroupCode(),
                context.getProjectId(), AdmCommonConstant.APP_ID, context.getUserId(), requestData);
        //楼层、建筑、对象类查询的空间id
        Set<String> spaceIdSet = objectDigitals.stream().map(ObjectDigital::getId).collect(Collectors.toSet());
        HashMap<String, ObjectRelation> distinctMap = new HashMap<>(spaceIdSet.size());
        for (String spaceId : spaceIdSet) {
            QueryCriteria queryRequestTmp = new QueryCriteria();
            ObjectNode nodeTmp = JsonNodeFactory.instance.objectNode();
            nodeTmp.put("graphCode", graphType);
            nodeTmp.put("relCode", relType);
            nodeTmp.put("relValue", zoneType);
            nodeTmp.put("objFrom", spaceId);
            queryRequestTmp.setCriteria(nodeTmp);
            //关系查询空间id
            List<ObjectRelation> objectRelations = service.queryByCondition(context, queryRequestTmp);
            for (ObjectRelation objectRelation : objectRelations) {
                String key = StrUtil.format("{}_{}_{}_{}_{}", objectRelation.getGraphCode(), objectRelation.getRelCode(), objectRelation.getRelValue(), objectRelation.getObjFrom(), objectRelation.getObjTo());
                distinctMap.put(key, objectRelation);
            }
            nodeTmp = JsonNodeFactory.instance.objectNode();
            nodeTmp.put("graphCode", graphType);
            nodeTmp.put("relCode", relType);
            nodeTmp.put("relValue", zoneType);
            nodeTmp.put("objTo",spaceId);
            queryRequestTmp.setCriteria(nodeTmp);
            //关系查询空间id
            objectRelations = service.queryByCondition(context, queryRequestTmp);
            for (ObjectRelation objectRelation : objectRelations) {
                String key = StrUtil.format("{}_{}_{}_{}_{}", objectRelation.getGraphCode(), objectRelation.getRelCode(), objectRelation.getRelValue(), objectRelation.getObjFrom(), objectRelation.getObjTo());
                distinctMap.put(key, objectRelation);
            }
        }
        for (ObjectRelation objectRelation : distinctMap.values()) {
            QueryCriteria queryRequest = new QueryCriteria();
            ObjectNode node = JsonNodeFactory.instance.objectNode();
            node.put("graphCode", objectRelation.getGraphCode());
            node.put("relCode", objectRelation.getRelCode());
            node.put("relValue", objectRelation.getRelValue());
            node.put("objFrom", objectRelation.getObjFrom());
            node.put("objTo", objectRelation.getObjTo());
            queryRequest.setCriteria(node);
            service.doDelete(context, queryRequest);
        }
        return AdmResponse.success();
    }
}
