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.alibaba.excel.util.CollectionUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
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.ResponseCode;
import com.persagy.dmp.common.model.response.CommonResult;
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.FlInSyList;
import com.persagy.proxy.relation.model.SyInFl;
import com.persagy.proxy.relation.model.SyInFlList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.List;
import java.util.Map;

/**
 * @author zhangwencheng
 * 系统所在楼层相关接口
 */
@Slf4j
@RestController
@RequestMapping("/rel/sy-in-fl")
public class RelationSyInFlController {

    @Autowired
    private IAdmRelationService service;

   /**
     * 创建系统所在楼层关系
     *
     * @param syInFl
     * @param
     * @return
     * @throws Exception
     */
    @PostMapping("/link")
    public AdmResponse create(@RequestBody SyInFl syInFl) throws Exception {
        //系统Id
        String sysID = syInFl.getSysId();
        //楼层Id
        String floorId = syInFl.getFloorId();
        //
        String type = syInFl.getType();
        if (StrUtil.isBlank(sysID) || StrUtil.isBlank(floorId)) {
            return AdmResponse.failure("必填项：SysId（系统id）、floorId（楼层id）");
        }
        List<RelationDTO> voList = new ArrayList<>();
        AdmRelationTypeEnum sy2fl = AdmRelationTypeEnum.SY2FL;
        String graphCode = sy2fl.getGraphCode();
        String relCode = sy2fl.getRelCode();
        RelationDTO relation = new RelationDTO(null, graphCode, relCode, type, sysID, floorId);
        voList.add(relation);
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        service.doSave(context, voList);
        return AdmResponse.success();
    }


    /**
     * 创建所在系统和楼层的关系 系统楼层一对多
     *
     * @param
     * @return
     * @throws Exception
     */
    @PostMapping("/link-fl")
    public AdmResponse createSy(@RequestBody SyInFlList syInFlList) throws Exception {
        log.info("创建系统所在楼层关系link-fl方法开始，参数projectId为{}", AdmContextUtil.toDmpContext().getProjectId());
        //系统Id
        String sysId = syInFlList.getSysId();
        //楼层Id
        List<String> floorIdList = syInFlList.getFloorIdList();
        if (StringUtils.isBlank(sysId)) {
            //return AdmResponse.failure("必填项：sysId（系统id）、floorIdList（楼层Id）");
            //兼容adm历史逻辑，若楼层id为空时，返回success
            return AdmResponse.success();
        }
        // 按原有逻辑接口处理:2021年11月2日16:52:13 by lijie
        // 1.根据系统id,图类型编码为MechInArch,边类型为Sy2Fl删除关系
        // 1.1 组装删除参数
        QueryCriteria deleteQueryCriteria = new QueryCriteria();
        ObjectMapper mapper = SpringUtil.getBean(ObjectMapper.class);
        ObjectNode criteria = mapper.createObjectNode();
        criteria.put("graphCode",AdmRelationTypeEnum.SY2FL.getGraphCode());
        criteria.put("relCode",AdmRelationTypeEnum.SY2FL.getRelCode());
        criteria.put("objFrom",sysId);
        criteria.put("valid",Boolean.TRUE);
        deleteQueryCriteria.setCriteria(criteria);
        // 1.2 根据参数删除关系
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        CommonResult<List<ObjectRelation>> commonResult = DigitalRelationFacade.deleteByCriteria(context.getGroupCode(),
                context.getProjectId(), context.getAppId(), context.getUserId(), deleteQueryCriteria);
        if (!ResponseCode.A00000.getDesc().equals(commonResult.getResult())){
            return AdmResponse.failure(commonResult.getMessage());
        }
        if (CollUtil.isEmpty(floorIdList)){
            return AdmResponse.success(new ArrayList<>());
        }
        // 2.创建系统所属楼层关系
        List<RelationDTO> voList = new ArrayList<>();
        AdmRelationTypeEnum sy2fl = AdmRelationTypeEnum.SY2FL;
        String graphCode = sy2fl.getGraphCode();
        String relCode = sy2fl.getRelCode();
        for (String floorId : floorIdList) {
            RelationDTO relation = new RelationDTO(null, graphCode, relCode, null, sysId, floorId);
            voList.add(relation);
        }
        //查询 floor所属的建筑 增加关系:页面交互的/rel/sy-in-bd/link-bd接口会创建系统所属建筑的关系,该处省略.防止重复创建
//        QueryCriteria criteriaQuery = new QueryCriteria();
//        ObjectNode buildCriteria = JsonNodeFactory.instance.objectNode();
//        buildCriteria.put(ObjectRelation.REL_CODE_HUM, "Bd2Fl");
//        buildCriteria.put(ObjectRelation.GRAPH_CODE_HUM, "ArchSubset");
//        ArrayNode arrayNode = buildCriteria.putObject("objTo").putArray("$in");
//        floorIdList.stream().forEach(floorId -> arrayNode.add(floorId));
//        criteriaQuery.setCriteria(buildCriteria);
//        List<ObjectRelation> relationList = service.queryByCondition(AdmContextUtil.toDmpContext(), criteriaQuery);
//        if(CollUtil.isNotEmpty(relationList)){
//            Map<String,ObjectRelation> objectRelationMap = CollUtil.fieldValueMap(relationList, "objFrom");
//            for (String buildingId : objectRelationMap.keySet()) {
//                RelationDTO relation = new RelationDTO(null, graphCode, "Sy2Bd", null, sysId, buildingId);
//                voList.add(relation);
//            }
//        }
        // 组装上下文条件
        service.doSave(AdmContextUtil.toDmpContext(), voList);
        log.info("创建系统所在楼层关系link-fl方法结束");
        return AdmResponse.success();
    }


    /**
     * 所在楼层的系统，楼层一对多系统
     */
    @PostMapping("/link-sy")
    public AdmResponse createSy(@RequestBody FlInSyList flInSyList) {
        log.info("创建系统所在楼层关系link-sy方法开始，参数projectId为{}", AdmContextUtil.toDmpContext().getProjectId());
        String floorId = flInSyList.getFloorId();
        List<String> sysIdList = flInSyList.getSysIdList();
        if (StringUtils.isBlank(floorId) || CollectionUtils.isEmpty(sysIdList)) {
            return AdmResponse.failure("必填项：sysIdList（系统id不能为空）、floorId（楼层Id）");
        }
        AdmRelationTypeEnum sy2fl = AdmRelationTypeEnum.SY2FL;
        String graphCode = sy2fl.getGraphCode();
        String relCode = sy2fl.getRelCode();
        List<RelationDTO> voList = new ArrayList<>();
        for (String sysId : sysIdList) {
            RelationDTO relation = new RelationDTO(null, graphCode, relCode, null, sysId, floorId);
            voList.add(relation);
        }
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        service.doSave(context, voList);
        log.info("创建系统所在楼层关系link-sy方法结束");
        return AdmResponse.success();
    }


    /**
     * 系统所在楼层，系统一对多楼层,此方法不会覆盖
     */
    @PostMapping("/link-fl-sy")
    public AdmResponse createSyFl(@RequestBody SyInFlList syInFlList) {
        log.info("创建系统所在楼层关系link-fl-sy方法开始，参数projectId为{}", AdmContextUtil.toDmpContext().getProjectId());
        List<String> floorIdList = syInFlList.getFloorIdList();
        String sysId = syInFlList.getSysId();
        if (StringUtils.isBlank(sysId) || CollectionUtils.isEmpty(floorIdList)) {
            return AdmResponse.failure("必填项：sysId（系统sysId不能为空）、floorIdList（楼层Id不能为空）");
        }
        AdmRelationTypeEnum sy2fl = AdmRelationTypeEnum.SY2FL;
        String graphCode = sy2fl.getGraphCode();
        String relCode = sy2fl.getRelCode();
        List<RelationDTO> voList = new ArrayList<>();
        for (String floorId : floorIdList) {
            RelationDTO relation = new RelationDTO(null, graphCode, relCode, null, sysId, floorId);
            voList.add(relation);
        }
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        service.doSave(context, voList);
        log.info("创建系统所在楼层关系link-fl-sy方法结束");
        return AdmResponse.success();
    }

    /**
     * 根据对象删除
     *
     * @return
     */
    @PostMapping("/unlink")
    public AdmResponse delete(@RequestBody SyInFl syInFl) {
        String floorId = syInFl.getFloorId();
        String sysId = syInFl.getSysId();
        AdmRelationTypeEnum sy2fl = AdmRelationTypeEnum.SY2FL;
        String graphCode = sy2fl.getGraphCode();
        String relCode = sy2fl.getRelCode();
        String type = syInFl.getType();
        ObjectNode node = JsonNodeFactory.instance.objectNode();
        node.put("graphCode", graphCode);
        node.put("relCode", relCode);
        node.put("relValue",type);
        node.put("objFrom", sysId);
        node.put("objTo", floorId);
        QueryCriteria criteria = new QueryCriteria();
        criteria.setCriteria(node);
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        service.doDelete(context,criteria);
        return AdmResponse.success();
    }

}
