package com.persagy.proxy.dictionary.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.persagy.proxy.adm.constant.AdmDictCategoryEnum;
import com.persagy.proxy.adm.request.AdmDictQueryCriteria;
import com.persagy.proxy.adm.request.AdmQueryCriteria;
import com.persagy.proxy.adm.request.AdmResponse;
import com.persagy.proxy.adm.utils.AdmContextUtil;
import com.persagy.proxy.common.entity.InstanceUrlParam;
import com.persagy.proxy.dictionary.model.AdmDict;
import com.persagy.proxy.dictionary.model.AdmObjectType;
import com.persagy.proxy.dictionary.service.IAdmDictService;
import com.persagy.proxy.object.model.AdmEquipment;
import com.persagy.proxy.object.model.AdmObjectInfo;
import com.persagy.proxy.object.service.IAdmEquipmentService;
import com.persagy.proxy.report.service.IAdmLabslService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName AdmLabslController
 * @Description: 蜡笔森林定制接口
 * @Author linhuili
 * @Date 2021/9/17 20:01
 * @Version V1.0
 **/
@RestController
@RequestMapping("/labsl")
@Slf4j
public class AdmLabslController {


    @Autowired
    private IAdmLabslService service;

    @Autowired
    private IAdmEquipmentService iAdmEquipmentService;

    @Autowired
    private IAdmDictService admDictService;

    /**
     * 查询项目下的设备类型
     * @return
     * @throws Exception
     */
    @PostMapping("/category")
    public AdmResponse queryCategory() throws Exception {
        return querySystemEquipTree(AdmContextUtil.toDmpContext(),AdmObjectType.class);
        //return service.queryCategory(context, AdmObjectInfo.class);
    }


    /**
     * 查询项目下的空间类型
     * @return
     * @throws Exception
     */
    @PostMapping("/zone/type")
    public AdmResponse queryZoneType() throws Exception {
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        return service.queryZoneType(context, AdmObjectInfo.class);
    }

    /**
     * 查询项目下的建筑楼层
     * @return
     * @throws Exception
     */
    @PostMapping("/building/floor")
    public AdmResponse queryBuildFloor(@RequestParam(value = "projectId",required = false) String projectId) throws Exception {
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        return service.queryBuildFloor(context, AdmObjectInfo.class);
    }


  /*  *//**
     * 查询设备包含设备类型
     * @return
     * @throws Exception
     *//*
    @PostMapping("/query/equip")
    public AdmResponse queryEquipType(@QueryParam("projectId") AdmQueryCriteria request) throws Exception {
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        return iAdmEquipmentService.doQuery(context, AdmObjectInfo.class);
    }*/


    /**
     * 查询设备包含设备类型
     * @return
     * @throws Exception
     */
    @PostMapping("/query/equip")
    public AdmResponse queryEquipType(@RequestBody AdmQueryCriteria request) throws Exception {
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        // 组装上下文条件
        request.setName(AdmEquipment.OBJ_TYPE);
        //过滤条件处理
        String filters = request.getFilters();
        Boolean specialQueryFlag = false;
        StringBuilder newFilters = new StringBuilder();
        StringBuilder specailFilters = new StringBuilder();
        if(StringUtils.isEmpty(filters)){
            return iAdmEquipmentService.doQuery(context, request, AdmEquipment.class);
        }
        //处理查询条件
        specialQueryFlag = handleRequestCriteria(filters, newFilters, specailFilters, specialQueryFlag);
        List<AdmEquipment> result = new ArrayList<>();
        List<AdmEquipment> specailContent = new ArrayList<>();

        AdmQueryCriteria specifal = new AdmQueryCriteria();
        specifal = request;
        specifal.setFilters(specailFilters.toString());

        int totalCount = 0 ;
        request.setFilters(newFilters.toString());
        AdmResponse queryResponse = iAdmEquipmentService.doQuery(context, request, AdmEquipment.class);
        List<AdmEquipment> content = (List<AdmEquipment>)queryResponse.getContent();
        if(queryResponse.getTotal() != null){
            totalCount += queryResponse.getTotal().intValue();
        }
        if(specialQueryFlag){
            //查询未明确建筑，未明确楼层
            Long count = CollectionUtil.isEmpty(queryResponse.getContent()) ? 0 : Long.valueOf(queryResponse.getContent().size());
            Integer pageSize = request.getPageSize();
            if(count < pageSize){
                long specailPageSize = pageSize - count;
                specifal.setPageSize((int) specailPageSize);
                AdmResponse specailQueryResponse = iAdmEquipmentService.doQuery(context, specifal, AdmEquipment.class);
                specailContent = (List<AdmEquipment>)specailQueryResponse.getContent();
                if(specailQueryResponse.getTotal() != null){
                    totalCount += specailQueryResponse.getTotal().intValue();
                }
            }
        }
        if(CollUtil.isNotEmpty(content)){
            result.addAll(content);
        }
        if(CollUtil.isNotEmpty(specailContent)){
            result.addAll(specailContent);
        }
        AdmResponse response = AdmResponse.success(result);
        response.setTotal(Long.valueOf(totalCount));
        response.setCount(CollectionUtil.isEmpty(result) ? 0 : Long.valueOf(result.size()));
        response.setPageNumber(request.getPageNumber());
        response.setPageSize(request.getPageSize());
        return response;
    }

    /**
     * 处理查询条件
     * @param filters
     * @param newFilters
     * @param specailFilters
     * @param specialQueryFlag
     */
    private boolean handleRequestCriteria(String filters,StringBuilder newFilters,StringBuilder specailFilters,Boolean specialQueryFlag){
        String[] filter = filters.split(";");
        for(int i =0 ;i< filter.length;i++){
            if(filter[i].contains("not")){
                String[] param = filter[i].split(" ");
                filter[i] = StrUtil.format("{} $notcontains {}",param[1],param[3]);
            }
            if(filter[i].contains(" in [") && filter[i].contains("]or")){
                //针对未明确建筑，未明确楼层查询单独处理
                String[] split = filter[i].split("]or");
                newFilters.append(split[0]+"]");
                specailFilters.append(split[1]);
                //标记特殊查询标识
                specialQueryFlag = true;
                newFilters.append(" ; ");
                specailFilters.append(" ; ");
            }else{
                newFilters.append(filter[i]);
                specailFilters.append(filter[i]);
                if(i != filter.length -1){
                    newFilters.append(" ; ");
                    specailFilters.append(" ; ");
                }
            }
        }
        return specialQueryFlag;
    }

    /**
     * 根据设备id统计设备所属的专业
     * @return
     * @throws Exception
     */
    @PostMapping("/major/category")
    public AdmResponse queryMajorCategory(@RequestParam(value = "projectId",required = false) String projectId,
                                          @RequestBody List<String> ids) throws Exception {
        InstanceUrlParam context = AdmContextUtil.toDmpContext();
        if(CollUtil.isEmpty(ids)){
            return AdmResponse.success(new ArrayList<>());
        }
        List<String> newIds = ids.stream().filter(id->!"fisnull".equals(id)).collect(Collectors.toList());
        if(CollUtil.isEmpty(newIds)){
            return AdmResponse.success(new ArrayList<>());
        }
        return service.queryMajorCategory(context, newIds , AdmObjectType.class);
    }

    /**
     * 查询项目下已有的系统设备类型树
     * @param context
     * @param clazz
     * @return
     * @throws Exception
     */
    private <T> AdmResponse querySystemEquipTree(InstanceUrlParam context, Class<T> clazz) throws Exception {
        AdmDictQueryCriteria request = new AdmDictQueryCriteria();
        //查询项目下已有的设备类型
        request.setName("equipment");
        AdmResponse dictResponse = iAdmEquipmentService.queryEquipClassCode(context, request, AdmEquipment.class);
        List<String> classCodes = (List<String>)dictResponse.getContent();
        if(CollUtil.isEmpty(classCodes)){
            return AdmResponse.success(new ArrayList<>());
        }
        Map<String, List<String>> classCodeMap = classCodes.stream().collect(Collectors.groupingBy(item->item.substring(0,4),Collectors.toList()));
        //查询系统设备类树
        AdmDict admDict = new AdmDict();
        admDict.setType(AdmDictCategoryEnum.MAJOR_SYSTEM_EQUIP.getValue());
        AdmResponse categoryResponse = admDictService.queryCategory(context, admDict, clazz);
        List<AdmObjectType> objectTypes = (List<AdmObjectType>) categoryResponse.getContent();
        if(CollUtil.isEmpty(objectTypes)){
            return AdmResponse.success(new ArrayList<>());
        }
        //过滤设备实体中不存在的类型
        Iterator<AdmObjectType> it = objectTypes.iterator();
        while(it.hasNext()){
            AdmObjectType major = it.next();
            //过滤系统
            List<AdmObjectType> systemList = major.getChildren();
            if(CollUtil.isNotEmpty(systemList)){
                Iterator<AdmObjectType> systemListIter = systemList.iterator();
                while (systemListIter.hasNext()){
                    AdmObjectType objectType = systemListIter.next();
                    List<String> objTypes = classCodeMap.get(objectType.getCode());
                    if(CollUtil.isEmpty(objTypes)){
                        systemListIter.remove();
                        continue;
                    }
                    //过滤子级：设备类型
                    List<AdmObjectType> children = objectType.getChildren();
                    if(CollUtil.isEmpty(children)){
                        systemListIter.remove();
                        continue;
                    }
                    Iterator<AdmObjectType> chidIterator = children.iterator();
                    while (chidIterator.hasNext()){
                        AdmObjectType next = chidIterator.next();
                        if(!objTypes.contains(next.getCode())){
                            chidIterator.remove();
                        }
                    }
                }
            }
            if(CollUtil.isEmpty(systemList)){
                it.remove();
            }

        }
        return AdmResponse.success(objectTypes);
    }
}
