package com.persagy.proxy.relation.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.dmp.basic.model.QueryCriteria;
import com.persagy.dmp.common.constant.CommonConstant;
import com.persagy.dmp.digital.client.DigitalRelationFacade;
import com.persagy.dmp.digital.entity.ObjectRelation;
import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
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.entity.InstanceUrlParam;
import com.persagy.proxy.common.entity.RelationDTO;
import com.persagy.proxy.relation.model.BdInSyList;
import com.persagy.proxy.relation.model.SyInBd;
import com.persagy.proxy.relation.model.SyInBdList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

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

/**
 * @author zhangwencheng
 * 系统所在建筑
 */
@Slf4j
@RestController
@RequestMapping("/rel/sy-in-bd")
public class RelationSyInBdController {

    @Autowired
    private IAdmRelationService service;

    /**
     * 系统所在建筑
     *
     * @param syInBd
     * @param projectId
     * @return
     * @throws Exception
     */
    @PostMapping("/link")
    public AdmResponse create(@RequestBody SyInBd syInBd) throws Exception {
        log.info("创建系统所在建筑关系create方法开始参数projectId为{}", AdmContextUtil.toDmpContext().getProjectId());
        //系统Id
        String sysID = syInBd.getSysId();
        //建筑Id
        String buildingId = syInBd.getBuildingId();
        if (StrUtil.isBlank(sysID) || StrUtil.isBlank(buildingId)) {
            return AdmResponse.failure("必填项：SysId（系统id）、BuildingId（建筑id）");
        }
        List<RelationDTO> voList = new ArrayList<>();
        AdmRelationTypeEnum sy2bdMechinarch = AdmRelationTypeEnum.SY2BD_MECHINARCH;
        String graphCode = sy2bdMechinarch.getGraphCode();
        String relCode = sy2bdMechinarch.getRelCode();
        RelationDTO relation = new RelationDTO(null, graphCode, relCode, null, sysID, buildingId);
        voList.add(relation);
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        service.doSave(context, voList);
        log.info("创建系统所在建筑create方法结束");
        return AdmResponse.success();
    }


//    /**
//     * 系统和楼层的关系对象
//     *
//     * @param syInFlList
//     * @param projectId
//     * @return
//     * @throws Exception
//     */
//    @PostMapping("/link-fl")
//    public AdmResponse createSy(@RequestBody SyInFlList syInFlList, @RequestParam("projectId") String projectId) throws Exception {
//        log.info("创建系统所在建筑关系create方法开始参数projectId为{}", projectId);
//        //系统Id
//        String sysID = syInFlList.getSysId();
//        //楼层
//        List<String> floors = syInFlList.getFloorIdList();
//        if (StringUtils.isBlank(sysID) || CollectionUtils.isEmpty(floors)) {
//            return AdmResponse.failure("必填项：SysId（系统id）、floorIdList（楼层）");
//        }
//        List<RelationDTO> voList = new ArrayList<>();
//        for (String floorId : floors) {
//            //todo graphCode
//            RelationDTO relation = new RelationDTO(null, "MechInArch", "Eq2Sp", null, sysID, floorId);
//            voList.add(relation);
//        }
//        // 组装上下文条件
//        InstanceUrlParam context = new InstanceUrlParam(groupCode, null, projectId, AdmCommonConstant.APP_ID);
//        service.doSave(context, voList);
//        log.info("创建系统服务于业务空间关系create方法结束");
//        return AdmResponse.success();
//    }

    /**
     * 创建系统所在建筑关系
     * @param syInFlList: 请求参数
     * @return
     * @throws Exception
     */
    @PostMapping("/link-bd")
    public AdmResponse createBd(@RequestBody SyInBdList syInFlList) throws Exception {
        log.debug("创建系统所在建筑关系createBD方法开始参数projectId为{}", AdmContextUtil.toDmpContext().getProjectId());
        // 原来的逻辑:2021年11月2日14:59:13 lijie修改
        // 1.删除图类型MechInArch,边类型为Sy2Bd,系统id为sysID的关系
        // 2.如果建筑id列表不为空,则创建对应的关系进行保存
        //系统Id
        String sysID = syInFlList.getSysId();
        //楼层
        List<String> buildIds = syInFlList.getBuildingIdList();
        if (StringUtils.isBlank(sysID)) {
            return AdmResponse.success();
        }
        // 1.1 根据图类型MechInArch,边类型为Sy2Bd,系统id为sysID查询有效关系列表
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        List<ObjectRelation> objectRelations =
                queryObjectRelationsByGraphCodeAndRelCodeAndSystemId(AdmRelationTypeEnum.SY2BD_MECHINARCH.getGraphCode(),
                    AdmRelationTypeEnum.SY2BD_MECHINARCH.getRelCode(), sysID);
        if (CollUtil.isNotEmpty(objectRelations)){
            // 1.2 收集关系的主键列表
            List<String> relIds = objectRelations.stream()
                    .filter(objectRelation -> StrUtil.isNotBlank(objectRelation.getId()))
                    .map(ObjectRelation::getId).collect(Collectors.toList());
            // 1.3 删除关系
            DigitalRelationFacade.delete(context.getGroupCode(),context.getProjectId(),
                    context.getAppId(),context.getUserId(),relIds);
        }
        if (CollUtil.isEmpty(buildIds)){
            return AdmResponse.success(new ArrayList<>());
        }
        List<RelationDTO> voList = new ArrayList<>();
        for (String buildId : buildIds) {
            RelationDTO relation = new RelationDTO(StrUtil
                    .format(CommonConstant.DEFAULT_GRAPH_ID_FORMAT,AdmRelationTypeEnum.SY2BD_MECHINARCH.getGraphCode()),
                    AdmRelationTypeEnum.SY2BD_MECHINARCH.getGraphCode(),
                    AdmRelationTypeEnum.SY2BD_MECHINARCH.getRelCode(), null, sysID, buildId);
            voList.add(relation);
        }
        service.doSave(context, voList);
        log.debug("创建系统所在建筑关系createBD方法结束");
        return AdmResponse.success();
    }

    /**
     * 创建系统所在建筑关系 同上
     * @param syInFlList:请求参数
     * @return
     * @throws Exception
     */
    @PostMapping("/link-bd-sy")
    public AdmResponse createSyBd(@RequestBody SyInBdList syInFlList) throws Exception {
        log.info("创建系统所在建筑关系createSyBd方法开始参数projectId为{}", AdmContextUtil.toDmpContext().getProjectId());
        //系统Id
        String sysID = syInFlList.getSysId();
        //楼层
        List<String> builds = syInFlList.getBuildingIdList();
        if (StringUtils.isBlank(sysID) || CollectionUtils.isEmpty(builds)) {
            return AdmResponse.failure("必填项：SysId（系统id）、buildingIdList（建筑Id）");
        }
        List<RelationDTO> voList = new ArrayList<>();
        AdmRelationTypeEnum sy2bdMechinarch = AdmRelationTypeEnum.SY2BD_MECHINARCH;
        String graphCode = sy2bdMechinarch.getGraphCode();
        String relCode = sy2bdMechinarch.getRelCode();
        for (String buildId : builds) {
            RelationDTO relation = new RelationDTO(null, graphCode, relCode, null, sysID, buildId);
            voList.add(relation);
        }
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        service.doSave(context, voList);
        log.info("创建系统所在建筑关系createSyBd方法结束");
        return AdmResponse.success();
    }

    /**
     * 创建所在建筑的系统关系
     * @param bdInSyList
     * @param projectId
     * @return
     * @throws Exception
     */
    @PostMapping("/link-sy")
    public AdmResponse createSyBd(@RequestBody BdInSyList bdInSyList) throws Exception {
        log.info("创建系统所在建筑关系createSyBd方法开始参数projectId为{}", AdmContextUtil.toDmpContext().getProjectId());
        //建筑Id
        String buildingId = bdInSyList.getBuildingId();
        //系统
        List<String> sysIdList = bdInSyList.getSysIdList();
        if (StringUtils.isBlank(buildingId) || CollectionUtils.isEmpty(sysIdList)) {
            return AdmResponse.failure("必填项：buildingId（建筑id）、sysIdList（系统Id）");
        }
        List<RelationDTO> voList = new ArrayList<>();
        AdmRelationTypeEnum sy2bdMechinarch = AdmRelationTypeEnum.SY2BD_MECHINARCH;
        String graphCode = sy2bdMechinarch.getGraphCode();
        String relCode = sy2bdMechinarch.getRelCode();
        for (String sysId : sysIdList) {
            RelationDTO relation = new RelationDTO(null, graphCode, relCode, null, sysId, buildingId);
            voList.add(relation);
        }
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        service.doSave(context, voList);
        log.info("创建系统所在建筑关系createSyBd方法结束");
        return AdmResponse.success();
    }


    /**
     * 系统所在建筑
     *
     * @param syInBd
     * @param projectId
     * @return
     * @throws Exception
     */
    @PostMapping("/unlink")
    public AdmResponse delete(@RequestBody SyInBd syInBd) throws Exception {
        log.info("创建系统所在建筑关系delete方法开始参数projectId为{}", AdmContextUtil.toDmpContext().getProjectId());
        //系统Id
        String sysID = syInBd.getSysId();
        //建筑Id
        String buildingId = syInBd.getBuildingId();
        if (StrUtil.isBlank(sysID) || StrUtil.isBlank(buildingId)) {
            return AdmResponse.failure("必填项：SysId（系统id）、BuildingId（建筑id）");
        }
        QueryCriteria criteria = new QueryCriteria();
//        RelationDTO relation = new RelationDTO(null, "MechInArch", "Eq2Sp", null, sysID, buildingId);
        AdmRelationTypeEnum sy2bdMechinarch = AdmRelationTypeEnum.SY2BD_MECHINARCH;
        String graphCode = sy2bdMechinarch.getGraphCode();
        String relCode = sy2bdMechinarch.getRelCode();
        // 组装上下文条件
        ObjectNode node = JsonNodeFactory.instance.objectNode();
        node.put("graphCode", graphCode);
        node.put("relCode", relCode);
//        node.put("relValue", );
        node.put("objFrom", sysID);
        node.put("objTo", buildingId);
        criteria.setCriteria(node);
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        service.doDelete(context,criteria);
        log.info("创建系统服务于业务空间关系delete方法结束");
        return AdmResponse.success();
    }

    /***
     * Description: 根据图类型,边类型,系统id查询有效关系
     * @param graphCode : 图类型
     * @param relCode : 边类型
     * @param systemId : 系统id
     * @return : void
     * @author : lijie
     * @date :2021/11/2 15:07
     * Update By lijie 2021/11/2 15:07
     */
    private List<ObjectRelation> queryObjectRelationsByGraphCodeAndRelCodeAndSystemId(String graphCode, String relCode, String systemId) {
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        QueryCriteria queryCriteria = new QueryCriteria();
        ObjectMapper mapper = SpringUtil.getBean(ObjectMapper.class);
        ObjectNode criteria = mapper.createObjectNode();
        criteria.put("graphCode",graphCode);
        criteria.put("relCode",relCode);
        criteria.put("objFrom",systemId);
        criteria.put("valid",Boolean.TRUE);
        queryCriteria.setCriteria(criteria);
        // 根据systemId,图类型,边类型查询有效的数据
        return DigitalRelationFacade.query(context.getGroupCode(), context.getProjectId(),
                context.getAppId(), context.getUserId(), queryCriteria);
    }
}
