package com.persagy.adm.server.algorithm.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.persagy.adm.server.algorithm.constant.AdmServerConstant;
import com.persagy.adm.server.algorithm.domain.*;
import com.persagy.adm.server.algorithm.entity.AdmModelFile;
import com.persagy.adm.server.algorithm.service.AdmModelService;
import com.persagy.dmp.common.constant.DigitalObjectType;
import com.persagy.dmp.common.context.AppContext;
import com.persagy.dmp.common.model.response.CommonResult;
import com.persagy.dmp.common.utils.ResultHelper;
import com.persagy.dmp.delivery.dto.ObjectTypeCollectDTO;
import com.persagy.dmp.delivery.entity.ObjectTypeCollect;
import com.persagy.dmp.digital.entity.ObjectDigital;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
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.*;
import java.util.stream.Collectors;

/**
 * 01-模型文件管理
 * 后端服务名:adm-server
 * @author : lijie
 * Update By 2022/1/12 14:01
 */
@RestController
@RequestMapping("/model")
@RequiredArgsConstructor
public class AdmModelController {

    private final AdmModelService admModelService;

    /**
     * 010101-模型文件-查询模型文件列表
     * @param queryModelFileVo : 模型文件查询信息
     * @return : com.persagy.dmp.common.model.response.CommonResult<java.util.List<com.persagy.adm.server.algorithm.entity.AdmModelFile>>
     * @author : lijie
     * Update By 2022/1/12 16:32
     * @undone
     */
    @PostMapping(value = "/queryModelFilesByProjectId")
    public CommonResult<List<BuildingVo>> queryModelFilesByProjectId(@RequestBody QueryModelFileVo queryModelFileVo) {
        // 1.根据建筑id查询建筑下的所有楼层
        List<ObjectDigital> allBuildFloors = admModelService.queryBuildFloorsByProjectId();
        if (CollUtil.isEmpty(allBuildFloors)){
            return ResultHelper.multi(new ArrayList<>());
        }
        // 2.根据floorId查询最新的模型文件信息
        Map<String, AdmModelFile> modelFileMap = admModelService
                .queryCurrentModelFileByFloorIds(allBuildFloors.stream()
                        .filter(objectDigital -> DigitalObjectType.FLOOR.getIndex().equals(objectDigital.getObjType()))
                        .map(ObjectDigital::getId).collect(Collectors.toList()));
        // 3.组装返回值
        Map<String, BuildingVo> buildingVoMap = new HashMap<>(allBuildFloors.size());
        for (ObjectDigital digital : allBuildFloors) {
            if (DigitalObjectType.BUILDING.getIndex().equals(digital.getObjType())){
                // 处理建筑数据
                BuildingVo buildingVo = buildingVoMap.getOrDefault(digital.getId(),new BuildingVo());
                buildingVo.setBuildingId(digital.getId());
                buildingVo.setBuildingName(digital.getLocalName());
                if (null!=digital.getInfos()
                        && digital.getInfos().has(AdmServerConstant.BUILD_SEQUENCE_ID)
                        && digital.getInfos().get(AdmServerConstant.BUILD_SEQUENCE_ID).isIntegralNumber()){
                    buildingVo.setBuildSequenceId(digital.getInfos().get(AdmServerConstant.BUILD_SEQUENCE_ID).asInt());
                }
                if (null!=digital.getInfos()
                        && digital.getInfos().has(AdmServerConstant.BUILD_SEQUENCE_ID)
                        && digital.getInfos().get(AdmServerConstant.BUILD_SEQUENCE_ID).isTextual()){
                    buildingVo.setBuildSequenceId(Integer.parseInt(digital.getInfos().get(AdmServerConstant.BUILD_SEQUENCE_ID).asText()));
                }
                buildingVoMap.put(digital.getId(),buildingVo);
                continue;
            }
            if (null==digital.getInfos()
                    || !digital.getInfos().has(AdmServerConstant.BUILDING_ID)
                    || !digital.getInfos().get(AdmServerConstant.BUILDING_ID).isTextual()){
                continue;
            }
            String buildingId = digital.getInfos().get(AdmServerConstant.BUILDING_ID).asText();
            BuildingVo buildingVo = buildingVoMap.getOrDefault(buildingId, new BuildingVo());
            buildingVoMap.put(buildingId,buildingVo);
            List<ModelFileVo> modelFileVos = CollUtil.defaultIfEmpty(buildingVo.getModelFiles(), CollUtil.newArrayList());
            buildingVo.setModelFiles(modelFileVos);
            ModelFileVo vo = new ModelFileVo();
            modelFileVos.add(vo);
            vo.setFloorId(digital.getId());
            vo.setBuildingId(buildingId);
            vo.setFloorName(digital.getLocalName());
            if (null!=digital.getInfos()
                    && digital.getInfos().has(AdmServerConstant.FLOOR_SEQUENCE_ID)
                    && digital.getInfos().get(AdmServerConstant.FLOOR_SEQUENCE_ID).isIntegralNumber()){
                vo.setFloorSequenceId(digital.getInfos().get(AdmServerConstant.FLOOR_SEQUENCE_ID).asInt());
            }
            AdmModelFile admModelFile = modelFileMap.get(digital.getId());
            if (null==admModelFile){
                continue;
            }
            vo.setDataFileId(admModelFile.getDataFileId());
            vo.setMinDataFileId(admModelFile.getMinDataFileId());
            vo.setOriginalName(admModelFile.getOriginalName());
            vo.setRevitFileId(admModelFile.getRevitFileId());
            vo.setRevitVersion(admModelFile.getRevitVersion());
            vo.setStatus(admModelFile.getStatus());
            vo.setUserId(admModelFile.getUserId());
            vo.setUserName(admModelFile.getUserName());
        }
        // 4.处理一下排序
        List<BuildingVo> buildingVos = CollUtil.newArrayList(buildingVoMap.values()).stream()
                .filter(buildingVo -> CollUtil.isEmpty(queryModelFileVo.getBuildingIds())
                        || queryModelFileVo.getBuildingIds().contains(buildingVo.getBuildingId()))
                .filter(buildingVo -> StrUtil.isNotBlank(buildingVo.getBuildingId())).collect(Collectors.toList());
        for (BuildingVo buildingVo : buildingVos) {
            if(CollUtil.isEmpty(buildingVo.getModelFiles())){
                continue;
            }
            buildingVo.getModelFiles().sort(Comparator.comparing(ModelFileVo::getFloorSequenceId));
        }
        buildingVos.sort(Comparator.comparing(BuildingVo::getBuildSequenceId));
        return ResultHelper.multi(buildingVos);
    }
    /**
     * 010102-模型文件-创建模型文件信息
     * @param modelFileVo : 模型文件信息
     * @return : com.persagy.dmp.common.model.response.CommonResult<java.lang.Void>
     * @author : lijie
     * Update By 2022/1/12 16:54
     * @undone
     */
    @PostMapping(value = "/saveModelFile")
    public CommonResult<List<Void>> saveModelFile(@Validated @RequestBody ModelFileVo modelFileVo) {
        AdmModelFile modelFile = BeanUtil.copyProperties(modelFileVo, AdmModelFile.class);
        modelFile.setGroupCode(AppContext.getContext().getGroupCode());
        modelFile.setProjectId(AppContext.getContext().getProjectId());
        modelFile.setCreator(AppContext.getContext().getAccountId());
        modelFile.setModifier(AppContext.getContext().getAccountId());
        admModelService.saveModelFile(modelFile);
        return ResultHelper.multi(new ArrayList<>());
    }
    /**
     * 010103-模型文件-查询正向/逆向交付范围
     * @param queryVo : 查询条件
     * @return : com.persagy.dmp.common.model.response.CommonResult<java.lang.Void>
     * @author : lijie
     * Update By 2022/1/12 16:54
     * @undone
     */
    @PostMapping(value = "/queryScopeOfDeliver")
    public CommonResult<List<ScopeOfDeliverVo>> queryScopeOfDeliver(@Validated @RequestBody QueryScopeOfDeliverVo queryVo) {
        // 1.查询对象类型交付范围
        List<ObjectTypeCollect> typeCollects = admModelService.queryObjectTypeCollectByDeliveryWay(queryVo.getDeliveryWay());
        if (CollUtil.isEmpty(typeCollects)){
            return ResultHelper.multi(new ArrayList<>());
        }
        List<ScopeOfDeliverVo> result = new ArrayList<>();
        for (ObjectTypeCollect typeCollect : typeCollects) {
            result.add(BeanUtil.toBean(typeCollect,ScopeOfDeliverVo.class));
        }
        // 2.查询对象信息点交付范围
        // 3.查询对象关系交付范围
        return ResultHelper.multi(result);
    }

}
