package com.persagy.proxy.calculation.controller;

import cn.hutool.core.collection.CollUtil;
import com.persagy.dmp.common.exception.BusinessException;
import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
import com.persagy.proxy.adm.constant.BusinessErrorRwdCode;
import com.persagy.proxy.adm.request.AdmResponse;
import com.persagy.proxy.calculation.service.AdmRelCalService;
import com.persagy.proxy.adm.utils.AdmContextUtil;
import com.persagy.proxy.common.entity.InstanceUrlParam;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Map;

/***
 * Description:关系计算输入类
 * @author : lijie
 * @date :2021/8/31 11:37
 * Update By lijie 2021/8/31 11:37
 */
@RestController
@RequestMapping("/relation-calc/")
@RequiredArgsConstructor
public class AdmRelCalController {

    private final AdmRelCalService admRelCalService;

    /***
     * Description: 添加关系(图类型关系为ArchSubset)
     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型)，以英文逗号隔开 HeatingZone,CleanZone,
     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
     * bd2sp: 建筑下的空间
     * fl2sp: 楼层下的空间
     * sh2bd: 建筑下的竖井,实际关系应该是bd2sh
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"bd2sp","fl2sp","sh2bd"})
    public AdmResponse archSubsetCalcRelation(@RequestParam(value = "objectTypes",required = false) String objectTypeStr,
                                              @RequestParam(value = "relationType",required = false) String relationTypeStr,
                                              HttpServletRequest request) {
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),CollUtil.newArrayList(getAdmRelationTypeEnum(request)),objectTypeStr);
        return AdmResponse.success(new ArrayList<>());
    }

    /***
     * Description: 添加关系(图类型关系为MechInArch)
     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型)，以英文逗号隔开 HeatingZone,CleanZone,
     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
     * eq2bd:设备所在建筑
     * eq2fl:设备所在楼层
     * eq2sh:设备所在竖井
     * eq2sp_in:设备所在业务空间
     * sy2bd: 系统所在建筑
     * sy2fl: 系统所在楼层
     * sy2sh: 系统所在竖井
     * sy2sp: 系统所在业务空间
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"eq2bd","eq2fl","eq2sh","eq2sp_in","sy2bd","sy2fl","sy2sh","sy2sp"})
    public AdmResponse mechInArchCalcRelation(@RequestParam(value = "objectTypes",required = false) String objectTypeStr,
                                              @RequestParam(value = "relationType",required = false) String relationTypeStr,
                                              HttpServletRequest request) {
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(), CollUtil.newArrayList(getAdmRelationTypeEnum(request)),objectTypeStr);
        return AdmResponse.success(new ArrayList<>());
    }

    /***
     * Description: 添加关系(图类型关系为PropertyInArch)
     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型)，以英文逗号隔开 HeatingZone,CleanZone,
     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
     * pe2bd:资产所在建筑
     * pe2fl:资产所在楼层
     * pe2sh:资产所在竖井
     * pe2sp:资产所在业务空间
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"pe2bd","pe2fl","pe2sh","pe2sp"})
    public AdmResponse propertyInArchCalcRelation(@RequestParam(value = "objectTypes",required = false) String objectTypeStr,
                                                  @RequestParam(value = "relationType",required = false) String relationTypeStr) {
        // 资产暂时未引入,直接返回成功
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        // admRelCalService.calcRelation(context,relType,objectTypeStr,relationTypeStr);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(图类型关系为MechForArch)
     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型)，以英文逗号隔开 HeatingZone,CleanZone,
     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
     * eq2sp_for:设备服务空间关系
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"eq2sp_for"})
    public AdmResponse mechForArchCalcRelation(@RequestParam(value = "objectTypes",required = false) String objectTypeStr,
                                               @RequestParam(value = "relationType",required = false) String relationTypeStr) {
        // 资产暂时未引入,直接返回成功
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        // admRelCalService.calcRelation(context,relType,objectTypeStr,relationTypeStr);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(图类型关系为ArchForArch)
     * @param buildingId : 建筑id
     * @param objectType : 对象分类
     * @param type : 对象类型
     * sp2sp:空间服务于空间
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"sp2sp"})
    public AdmResponse archForArchCalcRelation( @RequestParam(value = "buildingId",required = false) String buildingId,
                                                @RequestParam(value = "objectType",required = false) String objectType,
                                                @RequestParam(value = "type",required = false) String type) {
        admRelCalService.calcRelationForArchForArchSpToSp(AdmContextUtil.toDmpContext(),buildingId,objectType,type,
                AdmRelationTypeEnum.SP2SP_ARCHFORARCH);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(图类型关系为SensorRelationship)
     * eq2sp_SensorRelationship_ss2sp:传感器测量空间关系
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"eq2sp_SensorRelationship_ss2sp"})
    public AdmResponse sensorRelationshipCalcRelation() {
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
                CollUtil.newArrayList(AdmRelationTypeEnum.EQ2SP_SENSORRELATIONSHIP_SS2SP),"AirConditioningZone");
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(图类型关系为ConvectionNetwork)
     * sp2sp_ConvectionNetwork_1:Natural-空气自然对流
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"sp2sp_ConvectionNetwork_1"})
    public AdmResponse convectionNetworkCalcRelation() {
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
                CollUtil.newArrayList(AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1),null);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(图类型关系为RadiationNetwork)
     * sp2sp_RadiationNetwork_1:光照辐射网络-Connect-光照连通
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"sp2sp_RadiationNetwork_1"})
    public AdmResponse radiationNetworkCalcRelation() {
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
                CollUtil.newArrayList(AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1),null);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(图类型关系为SpaceNeighborhood)
     * sp2sp_SpaceNeighborhood_5:业务空间（同类）邻接关系-Connect-空间连通
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"sp2sp_SpaceNeighborhood_5"})
    public AdmResponse spaceNeighborhoodCalcRelation() {
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
                CollUtil.newArrayList(AdmRelationTypeEnum.SP2SP_SPACENEIGHBORHOOD_5),null);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(计算设备所在建筑,系统所在建筑,图类型关系为MechInArch)
     * syeq2bd:建筑下的系统设备部件,计算设备所在建筑(eq2bd),系统所在建筑(sy2bd)
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"syeq2bd"})
    public AdmResponse syeq2bdCalcRelation() {
        Map<String, AdmRelationTypeEnum> relationTypeMap = AdmRelationTypeEnum.getRelationTypeMap();
        if (!relationTypeMap.containsKey("eq2bd") || !relationTypeMap.containsKey("sy2bd")){
            throw new BusinessException(BusinessErrorRwdCode.A7201.getCode(),BusinessErrorRwdCode.A7201.getDesc());
        }
        ArrayList<AdmRelationTypeEnum> admRelationTypeEnums =
                CollUtil.newArrayList(relationTypeMap.get("eq2bd"), relationTypeMap.get("sy2bd"));
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),admRelationTypeEnums,null);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(图类型关系为TrafficNetwork)
     * sp2sp_TrafficNetwork_1:建筑交通网络（同类）-Normal-普通交通
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"sp2sp_TrafficNetwork_1"})
    public AdmResponse trafficNetworkCalcRelation() {
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
                CollUtil.newArrayList(AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_1),null);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 添加关系(图类型关系为ThroughRelationship)
     * fl2fl:楼层贯通关系
     * sh2sh:竖井贯通关系
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"fl2fl","sh2sh"})
    public AdmResponse throughRelationshipCalcRelation(HttpServletRequest request) {
        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
                CollUtil.newArrayList(getAdmRelationTypeEnum(request)),null);
        return AdmResponse.success(new ArrayList<>());
    }

    /***
     * Description: 更改计算标记
     * @param relType : 关系类型
     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型)，以英文逗号隔开 HeatingZone,CleanZone,
     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
     * sign: 更改计算标记
     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
     * @author : lijie
     * @date :2021/8/31 12:10
     * Update By lijie 2021/8/31 12:10
     */
    @PostMapping(value = {"sign"})
    public AdmResponse changeSign( @RequestParam(value = "objectTypes",required = false) String objectTypeStr,
                                   @RequestParam(value = "relationType",required = false) String relationTypeStr) {
        // 资产暂时未引入,直接返回成功
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        // admRelCalService.calcRelation(context,relType,objectTypeStr,relationTypeStr);
        return AdmResponse.success(new ArrayList<>());
    }
    /***
     * Description: 其他计算接口,预留接口,用于处理其他的关系不存在接口会出现404问题
     * @param relType : 关系类型
     * @param objectTypeStr : 对象类型
     * @param relationTypeStr : 关系类型
     * @return : com.persagy.proxy.adm.request.AdmResponse
     * @author : lijie
     * @date :2021/10/15 19:58
     * Update By lijie 2021/10/15 19:58
     */
    @PostMapping(value = "{relType}")
    public AdmResponse otherCal( @PathVariable("relType") String relType,
                                 @RequestParam(value = "objectTypes",required = false) String objectTypeStr,
                                 @RequestParam(value = "relationType",required = false) String relationTypeStr) {
        // 资产暂时未引入,直接返回成功
        // 组装上下文条件
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        // admRelCalService.calcRelation(context,relType,objectTypeStr,relationTypeStr);
        return AdmResponse.success(new ArrayList<>());
    }

    /***
     * Description: 获得关系枚举类型
     * @param request : 请求体
     * @return : com.persagy.proxy.adm.constant.AdmRelationTypeEnum
     * @author : lijie
     * @date :2021/9/11 22:33
     * Update By lijie 2021/9/11 22:33
     */
    private AdmRelationTypeEnum getAdmRelationTypeEnum(HttpServletRequest request) {
        String suffix = getSuffixRequestUrl(request);
        Map<String, AdmRelationTypeEnum> relationTypeMap = AdmRelationTypeEnum.getRelationTypeMap();
        if (!relationTypeMap.containsKey(suffix)){
            throw new BusinessException(BusinessErrorRwdCode.A7201.getCode(),BusinessErrorRwdCode.A7201.getDesc());
        }
        return relationTypeMap.get(suffix);
    }

    /***
     * Description: 获得最后一个/后请求地址
     * @param request : 请求对象
     * @return : void
     * @author : lijie
     * @date :2021/9/11 22:09
     * Update By lijie 2021/9/11 22:09
     */
    private String getSuffixRequestUrl(HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        return requestURI.substring(requestURI.lastIndexOf("/")+1);
    }

}
