package com.yuchen.saas.park.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yuchen.saas.manage.system.api.entity.DataScope;
import com.yuchen.saas.manage.system.api.entity.RoleScope;
import com.yuchen.saas.manage.system.api.feign.DataScopeFeignServer;
import com.yuchen.saas.manage.system.api.feign.RoleFeignServer;
import com.yuchen.saas.manage.system.api.feign.RoleScopeFeignServer;
import com.yuchen.saas.park.api.constant.CommonConstant;
import com.yuchen.saas.park.api.dto.response.PmgBatDeviceDataResponse;
import com.yuchen.saas.park.api.dto.response.PmgBatDeviceTreeResponse;
import com.yuchen.saas.park.api.entity.device.PmgBatSmartEquipment;
import com.yuchen.saas.park.api.entity.park.PmgBatDeviceCategory;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.enums.ParkDataTypeEnum;
import com.yuchen.saas.park.api.vo.request.DeviceCategoryAddRequest;
import com.yuchen.saas.park.api.vo.request.DeviceCategoryDelRequest;
import com.yuchen.saas.park.api.vo.request.DeviceCategoryReOperationRequest;
import com.yuchen.saas.park.api.vo.request.DeviceCategoryUpdateRequest;
import com.yuchen.saas.park.service.mapper.DeviceCategoryMapper;
import com.yuchen.saas.park.service.service.PmgBatDeviceCategoryService;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.PmgBatSmartEquipmentService;
import com.yuchen.saas.parking.api.entity.IotBatIntegratedDevice;
import com.yuchen.saas.parking.api.feign.IntegratedClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.redis.cache.NestRedis;
import org.nest.springwrap.core.secure.ContextUser;
import org.nest.springwrap.core.secure.utils.AuthUtil;
import org.nest.springwrap.core.tool.api.R;
import org.nest.springwrap.core.tool.constant.NestConstant;
import org.nest.springwrap.core.tool.utils.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @ClassName PmgBatDeviceCategoryServiceImpl
 * @Description 设备分类实现类
 * @Author 肖祥
 * @Date 2022/10/5 14:53
 * @Version 1.0。0
 **/
@Slf4j
@Service
public class PmgBatDeviceCategoryServiceImpl extends BaseServiceImpl<DeviceCategoryMapper, PmgBatDeviceCategory>
        implements PmgBatDeviceCategoryService {
    public static final String ADMINISTRATOR = "administrator";
    public static final String ADMIN = "admin";
    @Resource
    private PmgBatSmartEquipmentService pmgBatSmartEquipmentService;

    @Resource
    private IntegratedClient integratedClient;

    @Resource
    private PmgBatParkInfoService pmgBatParkInfoService;

   /* @Resource
    private IRoleScopeService roleScopeService;

    @Resource
    private IDataScopeService dataScopeService;*/

    @Resource
    private NestRedis nestRedis;

   /* @Resource
    private IRoleService roleService;*/

    @Resource
    private RoleScopeFeignServer roleScopeFeignServer;

    @Resource
    private DataScopeFeignServer dataScopeFeignServer;

    @Resource
    private RoleFeignServer roleFeignServer;

    public static Map<String, String> deviceMap = new ConcurrentHashMap<>();


    @Override
    public R addDeviceCategory(DeviceCategoryAddRequest deviceCategoryAddRequest) {
        LambdaQueryWrapper<PmgBatParkInfo> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(PmgBatParkInfo::getId, deviceCategoryAddRequest.getParkId());

        PmgBatParkInfo pmgBatParkInfo = pmgBatParkInfoService.getOne(lambdaQueryWrapper);
        log.info("pmgBatParkInfo: {}", pmgBatParkInfo);
        if (Func.isEmpty(pmgBatParkInfo)) {
            return R.error("该园区不存在！");
        }

        PmgBatDeviceCategory pmgBatDeviceCategory = new PmgBatDeviceCategory();
        BeanUtils.copyProperties(deviceCategoryAddRequest, pmgBatDeviceCategory);
        pmgBatDeviceCategory.setParkId(deviceCategoryAddRequest.getParkId());
        pmgBatDeviceCategory.setTenantId(pmgBatParkInfo.getTenantId());
        pmgBatDeviceCategory.setCreateTime(new Date());
        pmgBatDeviceCategory.setCreateUser(AuthUtil.getUser().getUserId());
        pmgBatDeviceCategory.setUpdateTime(new Date());
        pmgBatDeviceCategory.setUpdateUser(AuthUtil.getUser().getUserId());
        pmgBatDeviceCategory.setCreateDept(Long.valueOf(AuthUtil.getUser().getDeptId()));
        if (Func.isEmpty(pmgBatDeviceCategory.getParentId())){
            pmgBatDeviceCategory.setParentId(NestConstant.TOP_PARENT_ID);
            pmgBatDeviceCategory.setLevel(1);
        }
        log.info("pmgBatDeviceCategory: {}", pmgBatDeviceCategory);
        return R.status(baseMapper.insert(pmgBatDeviceCategory) > 0);
    }

    @Override
    public R updateDeviceCategory(DeviceCategoryUpdateRequest deviceCategoryUpdateRequest) {
        LambdaQueryWrapper<PmgBatDeviceCategory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PmgBatDeviceCategory::getParkId, deviceCategoryUpdateRequest.getParkId());
        lambdaQueryWrapper.eq(PmgBatDeviceCategory::getName, deviceCategoryUpdateRequest.getName());
        lambdaQueryWrapper.eq(PmgBatDeviceCategory::getLevel, deviceCategoryUpdateRequest.getLevel());
        lambdaQueryWrapper.ne(PmgBatDeviceCategory::getId, deviceCategoryUpdateRequest.getId());
        if (baseMapper.selectCount(lambdaQueryWrapper) > 0) {
            return R.error("设备同级分类名称重复");
        }

        LambdaUpdateWrapper<PmgBatDeviceCategory> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(PmgBatDeviceCategory::getName, deviceCategoryUpdateRequest.getName())
                .set(PmgBatDeviceCategory::getUpdateTime, new Date())
                .set(PmgBatDeviceCategory::getUpdateUser, AuthUtil.getUser().getUserId())
                .eq(PmgBatDeviceCategory::getId, deviceCategoryUpdateRequest.getId())
                .eq(PmgBatDeviceCategory::getParkId, deviceCategoryUpdateRequest.getParkId());
        return R.status(baseMapper.update(new PmgBatDeviceCategory(), lambdaUpdateWrapper) > 0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deleteDeviceCategory(DeviceCategoryDelRequest deviceCategoryDelRequest) {
        //移除分类
        removeChildCategoryById(deviceCategoryDelRequest.getId());
        return R.success("操作成功");
    }

    @Override
    public R<List<PmgBatDeviceTreeResponse>> getParkingTree(Long parkId) {
        LambdaQueryWrapper<PmgBatParkInfo> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(PmgBatParkInfo::getId, parkId);

        PmgBatParkInfo pmgBatParkInfo = pmgBatParkInfoService.getOne(lambdaQueryWrapper);
        log.info("pmgBatParkInfo: {}", pmgBatParkInfo);
        if (Func.isEmpty(pmgBatParkInfo)) {
            return R.error("该园区不存在！");
        }
        List<PmgBatDeviceCategory> pmgBatParkCategoryList = this.lambdaQuery().eq(PmgBatDeviceCategory::getParkId, String.valueOf(parkId))
                .list();
        log.info("pmgBatParkCategoryList: {}", pmgBatParkCategoryList);
        if (CollectionUtil.isEmpty(pmgBatParkCategoryList)) {
            PmgBatDeviceCategory pmgBatDeviceCategory = new PmgBatDeviceCategory();
            pmgBatDeviceCategory.setParkId(parkId);
            pmgBatDeviceCategory.setName(pmgBatParkInfo.getParkName());
            pmgBatDeviceCategory.setTenantId(pmgBatParkInfo.getTenantId());
            pmgBatDeviceCategory.setParentId(NestConstant.TOP_PARENT_ID);
            pmgBatDeviceCategory.setLevel(1);
            pmgBatDeviceCategory.setCreateTime(new Date());
            pmgBatDeviceCategory.setCreateUser(AuthUtil.getUser().getUserId());
            pmgBatDeviceCategory.setUpdateTime(new Date());
            pmgBatDeviceCategory.setUpdateUser(AuthUtil.getUser().getUserId());
            save(pmgBatDeviceCategory);
        }
        List<PmgBatDeviceCategory> pmgBatParkCategoryListNew = this.lambdaQuery().eq(PmgBatDeviceCategory::getParkId, String.valueOf(parkId))
                .list();
        List<PmgBatDeviceTreeResponse> pmgBatDeviceTreeResponseList = pmgBatParkCategoryListNew.stream()
                .map(pmgBatDeviceCategory -> {
                            PmgBatDeviceTreeResponse pmgBatDeviceTreeResponse = new PmgBatDeviceTreeResponse();
                            BeanUtils.copyProperties(pmgBatDeviceCategory, pmgBatDeviceTreeResponse);
                            return pmgBatDeviceTreeResponse;
                        }
                )
                .collect(Collectors.toList());
        List<PmgBatDeviceTreeResponse> treeResponseList = buildTree(pmgBatDeviceTreeResponseList, true);
        return R.data(treeResponseList);
    }

    @Override
    public R<List<PmgBatDeviceTreeResponse>> getParkingTreeV2(Long parkId) {
        LambdaQueryWrapper<PmgBatParkInfo> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(PmgBatParkInfo::getId, parkId);

        PmgBatParkInfo pmgBatParkInfo = pmgBatParkInfoService.getOne(lambdaQueryWrapper);
        log.info("pmgBatParkInfo: {}", pmgBatParkInfo);
        if (Func.isEmpty(pmgBatParkInfo)) {
            return R.error("该园区不存在！");
        }

        List<PmgBatDeviceCategory> pmgBatParkCategoryList = this.lambdaQuery().eq(PmgBatDeviceCategory::getParkId, String.valueOf(parkId))
                                                                              .list();
        log.info("pmgBatParkCategoryList: {}", pmgBatParkCategoryList);
        if (Func.isEmpty(pmgBatParkCategoryList)) {

            LambdaQueryWrapper<PmgBatDeviceCategory> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(PmgBatDeviceCategory::getName, "厦门火炬广场")
                        .eq(PmgBatDeviceCategory::getLevel, 1);
            PmgBatDeviceCategory pmgBatDeviceCategory = getOne(queryWrapper);

            if(Func.isEmpty(pmgBatDeviceCategory)) {
                return R.data(Collections.EMPTY_LIST);
            }

            pmgBatParkCategoryList = this.lambdaQuery().eq(PmgBatDeviceCategory::getParentId, pmgBatDeviceCategory.getId())
                                                       .eq(PmgBatDeviceCategory::getLevel, 2)
                                                       .list();
            log.info("pmgBatParkCategoryList: {}", pmgBatParkCategoryList);
            if(Func.isEmpty(pmgBatParkCategoryList)) {
                return R.data(Collections.EMPTY_LIST);
            }

            pmgBatDeviceCategory.setParkId(parkId);
            pmgBatDeviceCategory.setName(pmgBatParkInfo.getParkName());
            pmgBatDeviceCategory.setTenantId(pmgBatParkInfo.getTenantId());
            pmgBatDeviceCategory.setId(0L);
            pmgBatDeviceCategory.setCreateTime(new Date());
            pmgBatDeviceCategory.setCreateUser(AuthUtil.getUser().getUserId());
            pmgBatDeviceCategory.setUpdateTime(new Date());
            pmgBatDeviceCategory.setUpdateUser(AuthUtil.getUser().getUserId());
            if (save(pmgBatDeviceCategory)){
                PmgBatDeviceCategory select = this.lambdaQuery().eq(PmgBatDeviceCategory::getParkId, String.valueOf(parkId))
                                                                .eq(PmgBatDeviceCategory::getLevel, 1)
                                                                .one();

                log.info("select---------: {}", select);
                pmgBatParkCategoryList.forEach(e->{
                    e.setParentId(select.getId());
                    e.setParkId(select.getParkId());
                    e.setTenantId(select.getTenantId());
                    e.setId(0L);
                    e.setCreateTime(new Date());
                    e.setCreateUser(AuthUtil.getUser().getUserId());
                    e.setUpdateTime(new Date());
                    e.setUpdateUser(AuthUtil.getUser().getUserId());
                });

                saveBatch(pmgBatParkCategoryList);
                pmgBatParkCategoryList = this.lambdaQuery().eq(PmgBatDeviceCategory::getParkId, String.valueOf(parkId))
                                                           .list();
            }
        }

        List<PmgBatDeviceTreeResponse> pmgBatDeviceTreeResponseList = pmgBatParkCategoryList.stream()
                .map(pmgBatDeviceCategory -> {
                            PmgBatDeviceTreeResponse pmgBatDeviceTreeResponse = new PmgBatDeviceTreeResponse();
                            BeanUtils.copyProperties(pmgBatDeviceCategory, pmgBatDeviceTreeResponse);
                            return pmgBatDeviceTreeResponse;
                        }
                )
                .collect(Collectors.toList());
        List<PmgBatDeviceTreeResponse> treeResponseList = buildTree(pmgBatDeviceTreeResponseList, true);

        return R.data(treeResponseList);
    }

    @Override
    public R<List<PmgBatDeviceDataResponse>> waitRelDevice(Long parkId) {
        List<PmgBatSmartEquipment> pmgBatSmartEquipmentList = pmgBatSmartEquipmentService.lambdaQuery()
                .eq(PmgBatSmartEquipment::getParkId, parkId)
                .eq(PmgBatSmartEquipment::getCategoryRel, 0)
                .list();
        List<PmgBatDeviceDataResponse> deviceDataResponseList = pmgBatSmartEquipmentList.stream().map(
                device -> {
                    PmgBatDeviceDataResponse pmgBatDeviceDataResponse = new PmgBatDeviceDataResponse();
                    BeanUtils.copyProperties(device, pmgBatDeviceDataResponse);
                    return pmgBatDeviceDataResponse;
                }
        ).collect(Collectors.toList());
        return R.data(deviceDataResponseList);
    }

    @Override
    public R<List<PmgBatDeviceDataResponse>> alreadyRelDevice(Long parkId, Long categoryId) {
        //IOT集成的监控设备
        R<List<IotBatIntegratedDevice>> iotIntegratedDeviceList = integratedClient.getAllDevices(CommonConstant.PRODUCT_CAMERA_POINT);
        Map<String, IotBatIntegratedDevice> iotIntegratedDeviceMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(iotIntegratedDeviceList.getData())) {
            for (IotBatIntegratedDevice iotBatIntegratedDevice : iotIntegratedDeviceList.getData()) {
                if (iotBatIntegratedDevice.getDeviceName() != null) {
                    iotIntegratedDeviceMap.put(parkId + iotBatIntegratedDevice.getDeviceName(), iotBatIntegratedDevice);
                }
            }
        }

        //查询已经关联的分类设备
        List<PmgBatSmartEquipment> pmgBatSmartEquipmentList = pmgBatSmartEquipmentService.lambdaQuery()
                .eq(PmgBatSmartEquipment::getParkId, parkId)
                .eq(PmgBatSmartEquipment::getCategoryRel, 1)
                .eq(PmgBatSmartEquipment::getCategoryId, categoryId)
                .list();
        if (CollectionUtil.isEmpty(pmgBatSmartEquipmentList)) {
            return R.data(Collections.EMPTY_LIST);
        }

        //对输出的树数据进行角色权限控制
        ContextUser contextUser = AuthUtil.getUser();
        List<Long> adminRoleIdList = roleFeignServer.listByAlias(Arrays.asList(ADMINISTRATOR, ADMIN), Long.valueOf(contextUser.getTenantId())).getData();
        String roleIdString = contextUser.getRoleId();
        List<Long> userRoleIdList = Func.toLongList(StringPool.COMMA, roleIdString);
        boolean isAdmin = false;
        for (Long roleId : userRoleIdList) {
            if (adminRoleIdList != null && adminRoleIdList.contains(roleId)) {
                isAdmin = true;
            }
        }
        //是管理员或者没有配置园区,则有所有权限
        List<RoleScope> roleScopeList = roleScopeFeignServer.list(userRoleIdList, 2).getData();
        if (isAdmin || CollectionUtils.isEmpty(roleScopeList)) {
            //对集成的设备属性进行转换
            List<PmgBatDeviceDataResponse> pmgBatDeviceDataResponseList = pmgBatSmartEquipmentList.stream()
                    .map(pmgBatSmartEquipment -> {
                        PmgBatDeviceDataResponse pmgBatDeviceDataResponse = new PmgBatDeviceDataResponse();
                        BeanUtils.copyProperties(pmgBatSmartEquipment, pmgBatDeviceDataResponse);
                        IotBatIntegratedDevice iotBatIntegratedDevice = iotIntegratedDeviceMap.get(pmgBatSmartEquipment.getParkId() + pmgBatSmartEquipment.getDeviceName());
                        if (Func.isNotEmpty(iotBatIntegratedDevice)){
                            pmgBatDeviceDataResponse.setCameraIndexCode(iotBatIntegratedDevice.getSn());
                            pmgBatDeviceDataResponse.setCid(iotBatIntegratedDevice.getVideoId());
                        }
                        pmgBatDeviceDataResponse.setCameraName(pmgBatSmartEquipment.getName());
                        return pmgBatDeviceDataResponse;
                    }).collect(Collectors.toList());
            return R.data(pmgBatDeviceDataResponseList);
        }

        List<PmgBatSmartEquipment> roleDeviceList = buildRoleEquipments(userRoleIdList);

        List<PmgBatDeviceDataResponse> pmgBatDeviceDataResponseList = new ArrayList<>();
        for (PmgBatSmartEquipment pmgBatSmartEquipment : pmgBatSmartEquipmentList) {
            //不包含对象跳过
            if (!roleDeviceList.contains(pmgBatSmartEquipment)) {
                continue;
            }
            PmgBatDeviceDataResponse pmgBatDeviceDataResponse = new PmgBatDeviceDataResponse();
            BeanUtils.copyProperties(pmgBatSmartEquipment, pmgBatDeviceDataResponse);
            IotBatIntegratedDevice iotBatIntegratedDevice = iotIntegratedDeviceMap.get(pmgBatSmartEquipment.getParkId() + pmgBatSmartEquipment.getDeviceName());
            if (Func.isNotEmpty(iotBatIntegratedDevice)){
                pmgBatDeviceDataResponse.setCameraIndexCode(iotBatIntegratedDevice.getSn());
                pmgBatDeviceDataResponse.setCid(iotBatIntegratedDevice.getVideoId());
            }
            pmgBatDeviceDataResponse.setCameraName(pmgBatSmartEquipment.getName());
            pmgBatDeviceDataResponseList.add(pmgBatDeviceDataResponse);
        }
        return R.data(pmgBatDeviceDataResponseList);
    }

    private List<PmgBatSmartEquipment> buildRoleEquipments(List<Long> userRoleIdList) {
        List<RoleScope> roleScopeList = (List<RoleScope>) roleScopeFeignServer.list(userRoleIdList, ParkDataTypeEnum.DEVICE_DATA.getType()).getData();
        List<PmgBatSmartEquipment> roleDeviceList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(roleScopeList)) {
            for (RoleScope roleScope : roleScopeList) {
                DataScope dataScopeQuery = new DataScope();
                dataScopeQuery.setId(roleScope.getScopeId());
                DataScope dataScope = dataScopeFeignServer.detail(dataScopeQuery).getData();
                //查询已经关联的分类设备
                List<PmgBatSmartEquipment> pmgBatSmartEquipmentList = pmgBatSmartEquipmentService.lambdaQuery()
                        .last(dataScope.getScopeValue())
                        .list();
                roleDeviceList.addAll(pmgBatSmartEquipmentList);
            }
        }
        return roleDeviceList;
    }

    @Override
    public R deviceCategoryLinkOperation(DeviceCategoryReOperationRequest operationRequest) {
        //查询分类需要解关联的列表
        List<PmgBatSmartEquipment> smartEquipmentList = pmgBatSmartEquipmentService.lambdaQuery()
                .eq(PmgBatSmartEquipment::getCategoryId, operationRequest.getCategoryId())
                .list();
        if (CollectionUtil.isNotEmpty(smartEquipmentList)) {
            //更新设备分类
            smartEquipmentList.forEach(pmgBatSmartEquipment -> {
                LambdaUpdateWrapper<PmgBatSmartEquipment> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(PmgBatSmartEquipment::getCategoryRel, 0);
                updateWrapper.set(PmgBatSmartEquipment::getCategoryId, null);
                updateWrapper.eq(PmgBatSmartEquipment::getCategoryId, operationRequest.getCategoryId());
                pmgBatSmartEquipmentService.update(updateWrapper);
            });
        }
        if (CollectionUtil.isNotEmpty(operationRequest.getDeviceIdList())) {
            //重新关联设备
            operationRequest.getDeviceIdList().stream().forEach(deviceId -> {
                PmgBatSmartEquipment pmgBatSmartEquipment = pmgBatSmartEquipmentService.lambdaQuery()
                        .eq(PmgBatSmartEquipment::getId, deviceId)
                        .one();
                if (Objects.nonNull(pmgBatSmartEquipment)) {
                    pmgBatSmartEquipment.setCategoryId(operationRequest.getCategoryId());
                    pmgBatSmartEquipment.setCategoryRel(1);
                }
                pmgBatSmartEquipmentService.updateById(pmgBatSmartEquipment);
            });
        }
        return R.success("操作成功");
    }

    @Override
    public R<Set<Long>> getParkingTreeById(Long id) {
        List<PmgBatDeviceTreeResponse> list = this.baseMapper.getParkingTreeById(id);
        Set<Long> areaIds = new HashSet<>();
        if (CollectionUtil.isNotEmpty(list)) {
            for (PmgBatDeviceTreeResponse pmgBatDeviceTreeResponse : list) {
                areaIds.add(pmgBatDeviceTreeResponse.getId());
                areaIds.add(pmgBatDeviceTreeResponse.getParentId());
            }
        }
        return R.data(areaIds);
    }

    @Override
    public R<List<PmgBatDeviceTreeResponse>> getParkingAreaTree(Long parkId) {
        ContextUser user = AuthUtil.getUser();
        if (Func.isEmpty(user)){
            return R.data(new ArrayList<>());
        }
        List<PmgBatParkInfo> pmgBatParkInfoList = pmgBatParkInfoService.getAllParkV1(null,user.getIsAdmin(), user.getDeptId(), user.getTenantId(), user.getOrgUserId());
        if (Func.isEmpty(pmgBatParkInfoList)){
            return R.data(new ArrayList<>());
        }
        List<PmgBatDeviceCategory> pmgBatParkCategoryList = this.lambdaQuery().eq(PmgBatDeviceCategory::getIsDeleted, 0)
                .in(PmgBatDeviceCategory::getParkId, pmgBatParkInfoList.stream().map(PmgBatParkInfo::getId).collect(Collectors.toList())).list();
        if (CollectionUtil.isEmpty(pmgBatParkCategoryList)) {
            return R.data(Collections.EMPTY_LIST);
        }
        List<PmgBatDeviceTreeResponse> pmgBatDeviceTreeResponseList = pmgBatParkCategoryList.stream()
                .map(pmgBatDeviceCategory -> {
                            PmgBatDeviceTreeResponse pmgBatDeviceTreeResponse = new PmgBatDeviceTreeResponse();
                            BeanUtils.copyProperties(pmgBatDeviceCategory, pmgBatDeviceTreeResponse);
                            return pmgBatDeviceTreeResponse;
                        }
                )
                .collect(Collectors.toList());
        List<PmgBatDeviceTreeResponse> treeResponseList = buildTreeNew(pmgBatDeviceTreeResponseList, false);
        return R.data(treeResponseList);

    }

    @Override
    public Map<String, String> getParkBusinessDataByRoleId(Long parKId, Long roleId, Integer type) {
        if (parKId == null || roleId == null || type == null) {
            return deviceMap;
        }
        String deviceKey = String.format("%d%d%d", parKId, roleId, type);
        if (deviceMap.get(deviceKey) != null) {
            return deviceMap;
        }
        if (Objects.equals(type, ParkDataTypeEnum.DEVICE_DATA.getType())) {
            RoleScope roleScopeQuery = new RoleScope();
            roleScopeQuery.setRoleId(roleId);
            roleScopeQuery.setDataType(ParkDataTypeEnum.DEVICE_DATA.getType());
            List<RoleScope> roleScope = roleScopeFeignServer.list(roleScopeQuery).getData();
            if (CollectionUtil.isNotEmpty(roleScope)) {
                DataScope dataScope = dataScopeFeignServer.detailById(roleScope.get(0).getScopeId()).getData();
                //查询已经配置的角色关联设备数量
                Integer fenZi = pmgBatSmartEquipmentService.lambdaQuery()
                        .last(dataScope.getScopeValue()).count();
                Integer fenMu = pmgBatSmartEquipmentService.lambdaQuery().eq(PmgBatSmartEquipment::getCategoryRel, 1).count();
                String deviceValue = String.format("%d%s%d", fenZi, "/", fenMu);
                deviceMap.put(deviceKey, deviceValue);
            }
        }
        return deviceMap;
    }

    @Override
    public R<Integer> parkDeviceDataCount(Long parkId) {
        Integer deviceR = this.lambdaQuery()
                .eq(PmgBatDeviceCategory::getParkId, parkId)
                .count();
        return R.data(deviceR);
    }

    @Override
    public R<Set<String>> parkDeviceDataScopeValue(String scopeValue) {
        Set<String> categoryDeviceList = SpringUtil.getBean(PmgBatSmartEquipmentService.class).lambdaQuery()
                .last(scopeValue)
                .list().stream().map(pmgBatSmartEquipment -> Func.toStr(pmgBatSmartEquipment.getId()))
                .collect(Collectors.toSet());
        return R.data(categoryDeviceList);
    }

    /**
     * 递归删除分类下的子分类
     */
    public void removeChildCategoryById(Long id) {
        List<Long> idList = new ArrayList<>();
        this.selectChildCategoryListById(id, idList);
        idList.add(id);
        //删除分类
        baseMapper.deleteBatchIds(idList);
        //同时解关联分类下的设备数据
        List<PmgBatSmartEquipment> pmgBatSmartEquipmentList = pmgBatSmartEquipmentService
                .lambdaQuery()
                .in(PmgBatSmartEquipment::getCategoryId, idList)
                .eq(PmgBatSmartEquipment::getCategoryRel, 1)
                .list();
        if (CollectionUtil.isNotEmpty(pmgBatSmartEquipmentList)) {
            pmgBatSmartEquipmentList.forEach(pmgBatSmartEquipment -> {
                pmgBatSmartEquipmentService
                        .lambdaUpdate()
                        .set(PmgBatSmartEquipment::getCategoryRel, 0)
                        .eq(PmgBatSmartEquipment::getId, pmgBatSmartEquipment.getId());
            });
        }
    }

    /**
     * 查询传入的id，的下面的子孩子的集合
     */
    public void selectChildCategoryListById(Long id, List<Long> idList) {
        LambdaQueryWrapper<PmgBatDeviceCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PmgBatDeviceCategory::getParentId, id);
        wrapper.select(PmgBatDeviceCategory::getId);
        List<PmgBatDeviceCategory> childIdList = baseMapper.selectList(wrapper);
        childIdList.stream().forEach(item -> {
            idList.add(item.getId());
            this.selectChildCategoryListById(item.getId(), idList);
        });
    }
    /**
     * 建立树形结构
     */
    public List<PmgBatDeviceTreeResponse> buildTreeNew(List<PmgBatDeviceTreeResponse> categoryList, boolean hasNeedDevice) {
        List<PmgBatDeviceTreeResponse> treeMenus = new ArrayList<PmgBatDeviceTreeResponse>();
        for (PmgBatDeviceTreeResponse categoryNode : getRootNode(categoryList)) {
            categoryNode = buildChildTreeNew(categoryNode, categoryList, hasNeedDevice);
            treeMenus.add(categoryNode);
        }
        return treeMenus;
    }


    /**
     * 递归，建立子树形结构 前端无子节点让返回null
     */
    public PmgBatDeviceTreeResponse buildChildTreeNew(PmgBatDeviceTreeResponse pmgBatDeviceTreeResponse,
                                                   List<PmgBatDeviceTreeResponse> treeResponseList, boolean hasNeedDevice) {
        List<Object> childCategoryList =new ArrayList<>();
        for (PmgBatDeviceTreeResponse category : treeResponseList) {
            if (Objects.equals(category.getParentId(), pmgBatDeviceTreeResponse.getId())) {
                childCategoryList.add(buildChildTreeNew(category, treeResponseList, hasNeedDevice));
            }
        }
        if (hasNeedDevice) {
            R<List<PmgBatDeviceDataResponse>> alreadyRelDevice = alreadyRelDevice(pmgBatDeviceTreeResponse.getParkId(),
                    pmgBatDeviceTreeResponse.getId());
            if (CollectionUtil.isNotEmpty(alreadyRelDevice.getData())) {
                childCategoryList.addAll(alreadyRelDevice.getData());
            }
        }
        if (Func.isNotEmpty(childCategoryList)){
            pmgBatDeviceTreeResponse.setChildrenVoList(childCategoryList);
        }else {
            pmgBatDeviceTreeResponse.setChildrenVoList(null);
            pmgBatDeviceTreeResponse.setHasNode(false);
        }
        return pmgBatDeviceTreeResponse;
    }
    /**
     * 建立树形结构
     */
    public List<PmgBatDeviceTreeResponse> buildTree(List<PmgBatDeviceTreeResponse> categoryList, boolean hasNeedDevice) {
        List<PmgBatDeviceTreeResponse> treeMenus = new ArrayList<PmgBatDeviceTreeResponse>();
        for (PmgBatDeviceTreeResponse categoryNode : getRootNode(categoryList)) {
            categoryNode = buildChildTree(categoryNode, categoryList, hasNeedDevice);
            treeMenus.add(categoryNode);
        }
        return treeMenus;
    }


    /**
     * 递归，建立子树形结构
     */
    public PmgBatDeviceTreeResponse buildChildTree(PmgBatDeviceTreeResponse pmgBatDeviceTreeResponse,
                                                   List<PmgBatDeviceTreeResponse> treeResponseList, boolean hasNeedDevice) {
        List<Object> childCategoryList = new ArrayList<Object>();
        for (PmgBatDeviceTreeResponse category : treeResponseList) {
            if (Objects.equals(category.getParentId(), pmgBatDeviceTreeResponse.getId())) {
                childCategoryList.add(buildChildTree(category, treeResponseList, hasNeedDevice));
            }
        }
        if (hasNeedDevice) {
            R<List<PmgBatDeviceDataResponse>> alreadyRelDevice = alreadyRelDevice(pmgBatDeviceTreeResponse.getParkId(),
                    pmgBatDeviceTreeResponse.getId());
            if (CollectionUtil.isNotEmpty(alreadyRelDevice.getData())) {
                childCategoryList.addAll(alreadyRelDevice.getData());
            }
        }
        pmgBatDeviceTreeResponse.setChildrenVoList(childCategoryList);
        return pmgBatDeviceTreeResponse;
    }

    /**
     * 获取根节点(获取所有的父节点)
     */
    public List<PmgBatDeviceTreeResponse> getRootNode(List<PmgBatDeviceTreeResponse> categoryList) {
        List<PmgBatDeviceTreeResponse> rootCategoryLists = new ArrayList<PmgBatDeviceTreeResponse>();
        for (PmgBatDeviceTreeResponse category : categoryList) {
            if (Objects.equals(category.getParentId(), 0L)) {
                rootCategoryLists.add(category);
            }
        }
        return rootCategoryLists;
    }


    public R<IPage<PmgBatSmartEquipment>> getSmartEquipmentList(Long parkId, String productKey,String name,String categoryId,  int current, int size) {

        PageHelper.startPage(current, size);
        List<PmgBatSmartEquipment> pmgBatSmartEquipmentList = pmgBatSmartEquipmentService.lambdaQuery()
                .eq(PmgBatSmartEquipment::getParkId, parkId)
                .eq(StringUtil.isNotBlank(categoryId),PmgBatSmartEquipment::getCategoryId,categoryId)
                .like(StringUtil.isNotBlank(name),PmgBatSmartEquipment::getName,name)
                .eq(StringUtil.isNotBlank(productKey),PmgBatSmartEquipment::getProductKey, productKey)
                .eq(PmgBatSmartEquipment::getCategoryRel, 1)
                .list();
        for (PmgBatSmartEquipment item:pmgBatSmartEquipmentList
             ) {
            PmgBatDeviceCategory pmgBatDeviceCategory= this.getById(item.getCategoryId());
            item.setCategoryName(pmgBatDeviceCategory.getName());
        }
        PageInfo<PmgBatSmartEquipment> pageInfo=new PageInfo<PmgBatSmartEquipment>(pmgBatSmartEquipmentList);
        IPage<PmgBatSmartEquipment> iPage=new Page<PmgBatSmartEquipment>();
        iPage.setRecords(pageInfo.getList());
        iPage.setCurrent(pageInfo.getPageNum());
        iPage.setSize(pageInfo.getPageSize());
        iPage.setTotal(pageInfo.getTotal());
        iPage.setPages(pageInfo.getPages());
        return R.data(iPage);
    }

    /**
     * 需要展示的分类数据
     *
     * @param parkId 园区ID
     * @return
     */
    public List<String> needViewData(Long parkId) {
        //查询已经关联的分类设备
        List<PmgBatSmartEquipment> pmgBatSmartEquipmentList = pmgBatSmartEquipmentService.lambdaQuery()
                .eq(PmgBatSmartEquipment::getParkId, parkId)
                .eq(PmgBatSmartEquipment::getCategoryRel, 1)
                .list();
        if (CollectionUtil.isEmpty(pmgBatSmartEquipmentList)) {
            return Collections.EMPTY_LIST;
        }

        ContextUser contextUser = AuthUtil.getUser();
        //对输出的树数据进行角色权限控制
        List<Long> adminRoleIdList = (List<Long>) roleFeignServer.listByAlias(Arrays.asList(ADMINISTRATOR, ADMIN), Long.valueOf(contextUser.getTenantId())).getData();
        String roleIdString = contextUser.getRoleId();
        List<Long> userRoleIdList = Func.toLongList(StringPool.COMMA, roleIdString);
        boolean isAdmin = false;
        for (Long roleId : userRoleIdList) {
            if (adminRoleIdList != null && adminRoleIdList.contains(roleId)) {
                isAdmin = true;
            }
        }
        //是管理员或者没有配置园区,则有所有权限
        List<RoleScope> roleScopeList = (List<RoleScope>) roleScopeFeignServer.list(userRoleIdList, 2).getData();
        if (isAdmin || CollectionUtils.isEmpty(roleScopeList)) {
            List<String> list = pmgBatSmartEquipmentList.stream().distinct()
                    .map(pmgBatSmartEquipment -> pmgBatSmartEquipment.getCategoryId().toString())
                    .collect(Collectors.toList());
            Set<String> categoryList = new HashSet<>();
            if (CollectionUtils.isNotEmpty(list)) {
                for (String categoryId : list) {
                    List listParent = SpringUtil.getBean(PmgBatSmartEquipmentService.class).getDeviceTreeByCategoryId(Long.valueOf(categoryId));
                    categoryList.addAll(listParent);
                }
            }
            list.addAll(categoryList);
            return list;
        }
        List<PmgBatSmartEquipment> roleDeviceList = buildRoleEquipments(userRoleIdList);

        Set<String> pmgBatDeviceDataResponseList = new HashSet<>();
        for (PmgBatSmartEquipment pmgBatSmartEquipment : pmgBatSmartEquipmentList) {
            //不包含对象跳过
            if (!roleDeviceList.contains(pmgBatSmartEquipment)) {
                continue;
            }
            pmgBatDeviceDataResponseList.add(pmgBatSmartEquipment.getCategoryId().toString());
            List listParent = SpringUtil.getBean(PmgBatSmartEquipmentService.class).getDeviceTreeByCategoryId(Long.valueOf(pmgBatSmartEquipment.getCategoryId()));
            pmgBatDeviceDataResponseList.addAll(listParent);
        }

        return new ArrayList<>(pmgBatDeviceDataResponseList);
    }

}
