package com.ningdatech.carapi.sys.manage;

import static com.ningdatech.carapi.sys.helper.RegionsCacheHelper.ROOT_PARENT_ID;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.tuple.Pair;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.carapi.archives.enums.AuditStateEnum;
import com.ningdatech.carapi.car.equipment.manage.VehicleEquipmentManage;
import com.ningdatech.carapi.car.equipment.model.DataAccessDevices;
import com.ningdatech.carapi.car.equipment.model.NdVehicleEquipmentChannels;
import com.ningdatech.carapi.car.equipment.model.NdVehicleEquipmentInfo;
import com.ningdatech.carapi.car.equipment.model.VehicleEquipmentNo;
import com.ningdatech.carapi.car.equipment.model.dto.VehicleEquipmentPageQuery;
import com.ningdatech.carapi.car.equipment.model.vo.VehicleEquipmentVO;
import com.ningdatech.carapi.car.equipment.service.IDataAccessDevicesService;
import com.ningdatech.carapi.car.equipment.service.INdVehicleEquipmentChannelsService;
import com.ningdatech.carapi.car.equipment.service.INdVehicleEquipmentInfoService;
import com.ningdatech.carapi.car.equipment.service.IVehicleEquipmentNoService;
import com.ningdatech.carapi.car.vehicle.model.NdVehicleBaseInfo;
import com.ningdatech.carapi.car.vehicle.service.IVehicleBaseInfoService;
import com.ningdatech.carapi.common.constant.DeletedEnum;
import com.ningdatech.carapi.common.constant.UserRoleTypeEnum;
import com.ningdatech.carapi.common.constant.VehicleEquipFuncEnum;
import com.ningdatech.carapi.company.enumeration.CompanyTypeEnum;
import com.ningdatech.carapi.datascope.aop.LambdaDataScope;
import com.ningdatech.carapi.datascope.model.DataScopeDto;
import com.ningdatech.carapi.datascope.provider.DataScopeContext;
import com.ningdatech.carapi.sys.convert.RegionConverter;
import com.ningdatech.carapi.sys.entity.Company;
import com.ningdatech.carapi.sys.entity.Region;
import com.ningdatech.carapi.sys.entity.dto.CompanyDTO;
import com.ningdatech.carapi.sys.entity.dto.OperatorQueryDTO;
import com.ningdatech.carapi.sys.entity.dto.RegionDTO;
import com.ningdatech.carapi.sys.entity.req.RegionTreeReq;
import com.ningdatech.carapi.sys.entity.vo.*;
import com.ningdatech.carapi.sys.helper.CompaniesCacheHelper;
import com.ningdatech.carapi.sys.helper.OperatorsCacheHelper;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.sys.service.CompanyService;
import com.ningdatech.carapi.sys.service.IRegionService;
import com.ningdatech.carapi.sys.utils.DataScopeCacheFilterUtil;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.map.MapUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * RegionManage
 * </p>
 *
 * @author WendyYang
 * @since 10:39 2022/10/12
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class RegionManage {

    private final RegionsCacheHelper regionsCacheHelper;
    private final CompaniesCacheHelper companiesCacheHelper;
    private final IRegionService regionService;
    private final IVehicleBaseInfoService vehicleBaseInfoService;
    private final VehicleEquipmentManage equipmentManage;
    private final INdVehicleEquipmentInfoService vehicleEquipmentInfoService;
    private final IDataAccessDevicesService dataAccessDevicesService;
    private final INdVehicleEquipmentChannelsService vehicleEquipmentChannelsService;
    private final CompanyService companyService;
    private final OperatorsCacheHelper operatorsCacheHelper;
    private final IVehicleEquipmentNoService vehicleEquipmentNoService;

    public List<RegionTreeVO> getRegionTree(RegionTreeReq req) {
        Map<Long, List<RegionTreeCompanyVO>> companyMap = null;
        Map<Long, List<CarVO>> carNoGroup = null;
        Optional<DataScopeDto> dataScope = DataScopeContext.getDataScope(LoginUserUtil.loginUserDetail().getDataScope());
        if (req != null) {
            if (req.getWithCarNo() || req.getWithCompany()) {
                companyMap = companiesCacheHelper.all().stream()
                        .map(w -> BeanUtil.copyProperties(w, RegionTreeCompanyVO.class))
                        .filter(c -> DataScopeCacheFilterUtil.dataScopeFilter(c, dataScope))
                        .collect(Collectors.groupingBy(RegionTreeCompanyVO::getRegionId));
            }
            if (req.getWithCarNo()) {
                LambdaQueryWrapper<NdVehicleBaseInfo> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfo.class);
                //数据权限
                ((RegionManage) AopContext.currentProxy()).wrapperDataScope(wrapper);
                carNoGroup = vehicleBaseInfoService.list(wrapper)
                        .stream()
                        .collect(Collectors.groupingBy(NdVehicleBaseInfo::getCompanyId,
                                Collectors.mapping(car -> convertCar(car), Collectors.toList())));
            }
        }
        Map<Long, List<RegionDTO>> regionMap = CollUtils.group(regionsCacheHelper.getAllWithRole(dataScope, companiesCacheHelper), RegionDTO::getParentId);
        return RegionConverter.toRegionTree(ROOT_PARENT_ID, regionMap, false, carNoGroup, companyMap);
    }

    public List<RegionCompanyCarTreeVo> getRegionCompanyCarNoTree(RegionTreeReq req) {
        Map<Long, List<RegionTreeCompanyVO>> companyMap = null;
        Map<Long, List<Pair<Long, CarVO>>> carNoGroup = null;
        Optional<DataScopeDto> dataScope = DataScopeContext.getDataScope(LoginUserUtil.loginUserDetail().getDataScope());
        if (req != null) {
            if (req.getWithCarNo() || req.getWithCompany()) {
                companyMap = companiesCacheHelper.all().stream()
                        .map(w -> BeanUtil.copyProperties(w, RegionTreeCompanyVO.class))
                        .filter(c -> DataScopeCacheFilterUtil.dataScopeFilter(c, dataScope))
                        // 过滤掉管理企业
                        .filter(c -> !CompanyTypeEnum.MANAGE_BU.getCode().equals(c.getCompanyType()))
                        .filter(item -> Objects.nonNull(item.getRegionId()))
                        .collect(Collectors.groupingBy(RegionTreeCompanyVO::getRegionId));
            }
            if (req.getWithCarNo()) {
                LambdaQueryWrapper<NdVehicleBaseInfo> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfo.class);
                //数据权限
                ((RegionManage) AopContext.currentProxy()).wrapperDataScope(wrapper);
                if(req.getWithDevice()){
                    List<String> withDeviceCars = null;
                    VehicleEquipmentPageQuery vehicleEquipmentPageQuery = new VehicleEquipmentPageQuery();
                    vehicleEquipmentPageQuery.setPageNumber(1);
                    vehicleEquipmentPageQuery.setPageSize(200000);
                    PageVo<VehicleEquipmentVO> ePage = equipmentManage.queryAdded(vehicleEquipmentPageQuery);
                    if(ePage.getTotal() > 0L){
                        withDeviceCars = ePage.getRecords().stream().map(VehicleEquipmentVO::getCarPlate).collect(Collectors.toList());
                        if(CollUtil.isNotEmpty(withDeviceCars)){
                            wrapper.in(NdVehicleBaseInfo::getCarPlate,withDeviceCars);
                        }
                    }
                }
                carNoGroup = vehicleBaseInfoService.list(wrapper)
                        .stream()
                        .collect(Collectors.groupingBy(NdVehicleBaseInfo::getCompanyId,
                                Collectors.mapping(w -> Pair.of(w.getId(), convertCar(w)), Collectors.toList())));
            }
        }
        Map<Long, List<RegionDTO>> regionMap = CollUtils.group(regionsCacheHelper.getAllWithRole(dataScope, companiesCacheHelper), RegionDTO::getParentId);
        // 以车牌号分组，获取所有视频设备信息
        Map<String, List<NdVehicleEquipmentInfo>> equipmentMap = vehicleEquipmentInfoService.list().stream()
                .filter(c -> VehicleEquipFuncEnum.video.name().equals(c.getEquipmentFunction()))
                .collect(Collectors.groupingBy(NdVehicleEquipmentInfo::getCarPlate));
        // 获取设备的开启状态信息
        Map<String, DataAccessDevices> devicesMap = dataAccessDevicesService.list().stream()
                .collect(Collectors.toMap(c -> c.getPlatformId() + c.getDeviceId(), c -> c));

        // 获取设备通道信息
        Map<Long, NdVehicleEquipmentChannels> channelsMap = vehicleEquipmentChannelsService.list().stream()
                .collect(Collectors.toMap(NdVehicleEquipmentChannels::getEquipmentId, e -> e));
        return RegionConverter.toRegionCompanyCarNoTree(ROOT_PARENT_ID, regionMap, false, carNoGroup, companyMap,devicesMap,equipmentMap,channelsMap);
    }

    @LambdaDataScope
    public LambdaQueryWrapper<NdVehicleBaseInfo> wrapperDataScope(LambdaQueryWrapper<NdVehicleBaseInfo> wrapper) {
        return wrapper.select(NdVehicleBaseInfo::getCarPlate,NdVehicleBaseInfo::getStatus,NdVehicleBaseInfo::getMoving, NdVehicleBaseInfo::getCompanyId)
                .eq(NdVehicleBaseInfo::getDeleted, DeletedEnum.NO_DELETED.getCode())
                .eq(NdVehicleBaseInfo::getAuditState, AuditStateEnum.AUDIT_SUCCESS.getCode());
    }


    public LambdaQueryWrapper<NdVehicleBaseInfo> buildRegionWrapper(LambdaQueryWrapper<NdVehicleBaseInfo> wrapper) {
        return wrapper.select(NdVehicleBaseInfo::getCarPlate,NdVehicleBaseInfo::getStatus,NdVehicleBaseInfo::getMoving, NdVehicleBaseInfo::getCompanyId)
                .eq(NdVehicleBaseInfo::getDeleted, DeletedEnum.NO_DELETED.getCode())
                .eq(NdVehicleBaseInfo::getAuditState, AuditStateEnum.AUDIT_SUCCESS.getCode());
    }

    public synchronized void saveOrUpdate(RegionTreeVO req) {
        if (req.getId() == null) {
            if (req.getLevel() > RegionsCacheHelper.MAX_LEVEL) {
                throw new BizException("暂不支持添加第四级区域");
            }
            if (req.getParentCode().equals(RegionsCacheHelper.ROOT_PARENT_CODE)) {
                boolean exists = regionService.getBaseMapper().exists(Wrappers.lambdaQuery(Region.class)
                        .eq(Region::getParentCode, req.getParentCode())
                        .eq(Region::getDeleted, false));
                Assert.isFalse(exists, "顶级区域已存在");
            }
        }
        LambdaQueryWrapper<Region> query = Wrappers.lambdaQuery(Region.class)
                .eq(Region::getRegionCode, req.getRegionCode())
                .last("limit 1");
        Region region = regionService.getOne(query);
        if (region != null) {
            if (!region.getRegionCode().equals(req.getParentCode())) {
                if (req.getId() == null || !req.getId().equals(region.getId())) {
                    throw new BizException("地区编码已存在");
                }
            }
        }
        Long parentId = 0L;
        if (req.getLevel() > 1) {
            LambdaQueryWrapper<Region> wrapper = Wrappers.lambdaQuery(Region.class)
                    .eq(Region::getRegionCode, req.getParentCode())
                    .eq(Region::getLevel, req.getLevel() - 1);
            Region parent = regionService.getOne(wrapper);
            parentId = parent.getId();
        }
        Region regionNew = BeanUtil.copyProperties(req, Region.class);
        regionNew.setDeleted(false);
        regionNew.setParentId(parentId);
        regionNew.setUpdateBy(LoginUserUtil.getUserId());
        regionNew.setUpdateOn(LocalDateTime.now());
        if (req.getId() == null) {
            regionNew.setCreateBy(regionNew.getUpdateBy());
            regionNew.setCreateOn(regionNew.getUpdateOn());
        }
        if (regionService.saveOrUpdate(regionNew)) {
            regionsCacheHelper.refresh(regionNew.getId());
        }
    }

    public void remove(Long id, Integer level) {
        LambdaUpdateWrapper<Region> updater = Wrappers.lambdaUpdate(Region.class)
                .set(Region::getDeleted, true)
                .eq(Region::getDeleted, false)
                .eq(Region::getId, id);
        if (regionService.update(updater)) {
            regionsCacheHelper.refresh(id);
        }
    }

    private CarVO convertCar(NdVehicleBaseInfo car) {
        CarVO res = new CarVO();
        res.setCarPlate(car.getCarPlate());
        res.setStatus(car.getStatus());
        res.setMoving(car.getMoving());
        return res;
    }

    public List<RegionTreeVO> getRegionInfo() {

        Map<Long, RegionDTO> regionInfoMap = regionService.list().stream().collect(Collectors.toMap(Region::getId, RegionConverter::toRegionDTO));
        Collection<@NonNull RegionDTO> regions = regionInfoMap.values();
        Map<Long, List<RegionDTO>> regionMap = CollUtils.group(regions, RegionDTO::getParentId);
        return RegionConverter.toRegionTree(ROOT_PARENT_ID, regionMap, false, null, null);
    }

    public CompanyCarInfoVO getCompanyCarInfo(RegionTreeReq req) {

        // 按照登录用户，如果是运营商账号登录，删选出该运营商关联的车辆信息
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        Long roleId = userDetail.getRoleId();

        Long regionId = req.getRegionId();
        String carPlate = req.getCarPlate();
        CompanyCarInfoVO companyCarInfoVo = new CompanyCarInfoVO();

        StopWatch stopWatch = new StopWatch();
        StopWatch stopWatch2 = new StopWatch();
        StopWatch stopWatch3 = new StopWatch();
        StopWatch stopWatch4 = new StopWatch();

        // 0.09
        Map<Long, List<NdVehicleBaseInfo>> companyCarMap = vehicleBaseInfoService.list(Wrappers.lambdaQuery(NdVehicleBaseInfo.class)
                        .eq(Objects.nonNull(regionId),NdVehicleBaseInfo::getRegionId,regionId)).stream()
                .filter(v -> Objects.nonNull(v.getCompanyId()))
                .collect(Collectors.groupingBy(NdVehicleBaseInfo::getCompanyId));

        // 0.046
        Map<String, Integer> carStatusMap = vehicleBaseInfoService.list(Wrappers.lambdaQuery(NdVehicleBaseInfo.class)
                        .eq(Objects.nonNull(regionId),NdVehicleBaseInfo::getRegionId,regionId)
                        .eq(NdVehicleBaseInfo::getDeleted,DeletedEnum.NO_DELETED.getCode())
                        .eq(NdVehicleBaseInfo::getAuditState,AuditStateEnum.AUDIT_SUCCESS.getCode())
                        .select(NdVehicleBaseInfo::getCarPlate, NdVehicleBaseInfo::getMoving))
                .stream().collect(Collectors.toMap(NdVehicleBaseInfo::getCarPlate, NdVehicleBaseInfo::getMoving));


        //// 0.5
        //stopWatch.start();
        //// 以车牌号分组，获取所有视频设备信息
        //Map<Long, List<NdVehicleEquipmentInfo>> equipmentMap = vehicleEquipmentInfoService.list(Wrappers.lambdaQuery(NdVehicleEquipmentInfo.class)
        //                .select(NdVehicleEquipmentInfo::getVehicleId, NdVehicleEquipmentInfo::getId,NdVehicleEquipmentInfo::getEquipmentNo,NdVehicleEquipmentInfo::getPlatformId)
        //                .eq(NdVehicleEquipmentInfo::getEquipmentFunction,VehicleEquipFuncEnum.video.name()))
        //        .stream()
        //        .collect(Collectors.groupingBy(NdVehicleEquipmentInfo::getVehicleId));
        //stopWatch.stop();
        //log.info("设备信息查询 耗时 {}s", stopWatch.getTotalTimeSeconds());
        //// 获取设备的开启状态信息
        //// 0.6
        //stopWatch2.start();
        //Map<String, String> devicesMap = dataAccessDevicesService.list(Wrappers.lambdaQuery(DataAccessDevices.class)
        //                .select(DataAccessDevices::getPlatformId,DataAccessDevices::getDeviceId,DataAccessDevices::getStatus)).stream()
        //        .collect(Collectors.toMap(c -> c.getPlatformId() + c.getDeviceId(), DataAccessDevices::getStatus));
        //stopWatch2.stop();
        //log.info("设备在线信息查询 耗时 {}s", stopWatch2.getTotalTimeSeconds());
        //// 获取设备通道信息
        //// 0.98
        //stopWatch3.start();
        //Map<Long, String> channelsMap = vehicleEquipmentChannelsService.list().stream().filter(v -> Objects.nonNull(v.getName()))
        //        .collect(Collectors.toMap(NdVehicleEquipmentChannels::getEquipmentId, NdVehicleEquipmentChannels::getName));
        //stopWatch3.stop();
        //log.info("设备通道信息查询 耗时 {}s", stopWatch2.getTotalTimeSeconds());

        Map<String, List<VehicleEquipmentNo>> carEquipmentNoMap = vehicleEquipmentNoService.list().stream()
                .collect(Collectors.groupingBy(VehicleEquipmentNo::getCarPlate));

        // 直接查询车牌号
        if (Objects.nonNull(carPlate)){
            NdVehicleBaseInfo vehicleBaseInfo = vehicleBaseInfoService.getOne(Wrappers.lambdaQuery(NdVehicleBaseInfo.class)
                    .eq(NdVehicleBaseInfo::getCarPlate, carPlate));
            if (Objects.nonNull(vehicleBaseInfo)) {
                Long baseInfoRegionId = vehicleBaseInfo.getRegionId();
                Long vehicleId = vehicleBaseInfo.getId();
                if (Objects.nonNull(baseInfoRegionId)) {
                    companyCarInfoVo.setRegionId(baseInfoRegionId);
                    List<CompanyVO> companyVos = Lists.newArrayList();
                    CompanyVO companyVo = new CompanyVO();
                    CompanyDTO companyDto = companiesCacheHelper.getById(vehicleBaseInfo.getCompanyId());
                    if (Objects.isNull(companyDto)){
                        throw new BizException("查询车辆所属企业不存在!");
                    }
                    companyVo.setId(companyDto.getId());
                    companyVo.setName(companyDto.getName());
                    companyVo.setRegionId(companyDto.getRegionId());
                    companyVos.add(companyVo);
                    companyCarInfoVo.setCompanyList(companyVos);
                    List<CarInfoVO> carInfoList = Lists.newArrayList();
                    HashMap<Long, List<CarInfoVO>> carInfoMap = MapUtil.newHashMap();
                    CarInfoVO carInfoVo = new CarInfoVO();
                    carInfoVo.setCompanyId(vehicleBaseInfo.getCompanyId());
                    carInfoVo.setCarPlate(carPlate);
                    carInfoVo.setMoving(vehicleBaseInfo.getMoving());

                    List<VehicleEquipmentNo> vehicleEquipmentNos = carEquipmentNoMap.get(carPlate);
                    HashMap<String, List<EquipmentInfoVO>> equipmentInfoMap = MapUtil.newHashMap();
                    if (CollUtil.isNotEmpty(vehicleEquipmentNos)) {
                        List<EquipmentInfoVO> equipmentInfoList = Lists.newArrayList();
                        for (VehicleEquipmentNo equipmentInfo : vehicleEquipmentNos) {
                            EquipmentInfoVO equipmentInfoVo = new EquipmentInfoVO();
                            equipmentInfoVo.setCarPlate(carPlate);
                            equipmentInfoVo.setDeviceId(equipmentInfo.getDeviceId());
                            equipmentInfoVo.setDeviceName(equipmentInfo.getDeviceName());
                            String videoStatus = equipmentInfo.getStatus();
                            if (Objects.nonNull(videoStatus)) {
                                equipmentInfoVo.setVideoStatus(videoStatus);
                            }else {
                                equipmentInfoVo.setVideoStatus("OFF");
                            }
                            equipmentInfoList.add(equipmentInfoVo);
                        }
                        equipmentInfoMap.put(carPlate,equipmentInfoList);
                    }
                    carInfoVo.setEquipmentInfoMap(equipmentInfoMap);
                    carInfoList.add(carInfoVo);
                    carInfoMap.put(companyDto.getId(),carInfoList);
                    companyCarInfoVo.setCarInfoMap(carInfoMap);
                    return companyCarInfoVo;
                }
            }else {
                throw new BizException("查询车辆不存在!");
            }

        }

        //// 直接查询车牌号
        //if (Objects.nonNull(carPlate)){
        //    NdVehicleBaseInfo vehicleBaseInfo = vehicleBaseInfoService.getOne(Wrappers.lambdaQuery(NdVehicleBaseInfo.class)
        //            .eq(NdVehicleBaseInfo::getCarPlate, carPlate));
        //    if (Objects.nonNull(vehicleBaseInfo)) {
        //        Long baseInfoRegionId = vehicleBaseInfo.getRegionId();
        //        Long vehicleId = vehicleBaseInfo.getId();
        //        if (Objects.nonNull(baseInfoRegionId)) {
        //            companyCarInfoVo.setRegionId(baseInfoRegionId);
        //            List<CompanyVO> companyVos = Lists.newArrayList();
        //            CompanyVO companyVo = new CompanyVO();
        //            CompanyDTO companyDto = companiesCacheHelper.getById(vehicleBaseInfo.getCompanyId());
        //            if (Objects.isNull(companyDto)){
        //                throw new BizException("查询车辆所属企业不存在!");
        //            }
        //            companyVo.setId(companyDto.getId());
        //            companyVo.setName(companyDto.getName());
        //            companyVo.setRegionId(companyDto.getRegionId());
        //            companyVos.add(companyVo);
        //            companyCarInfoVo.setCompanyList(companyVos);
        //            List<CarInfoVO> carInfoList = Lists.newArrayList();
        //            HashMap<Long, List<CarInfoVO>> carInfoMap = MapUtil.newHashMap();
        //            CarInfoVO carInfoVo = new CarInfoVO();
        //            carInfoVo.setCompanyId(vehicleBaseInfo.getCompanyId());
        //            carInfoVo.setCarPlate(carPlate);
        //            carInfoVo.setMoving(vehicleBaseInfo.getMoving());
        //            List<NdVehicleEquipmentInfo> equipmentInfos = equipmentMap.get(vehicleId);
        //            HashMap<String, List<EquipmentInfoVO>> equipmentInfoMap = MapUtil.newHashMap();
        //            if (CollUtil.isNotEmpty(equipmentInfos)) {
        //                List<EquipmentInfoVO> equipmentInfoList = Lists.newArrayList();
        //                for (NdVehicleEquipmentInfo equipmentInfo : equipmentInfos) {
        //                    EquipmentInfoVO equipmentInfoVo = new EquipmentInfoVO();
        //                    equipmentInfoVo.setCarPlate(carPlate);
        //                    equipmentInfoVo.setDeviceId(equipmentInfo.getEquipmentNo());
        //                    String deviceName = channelsMap.get(equipmentInfo.getId());
        //                    equipmentInfoVo.setDeviceName(deviceName);
        //                    String videoStatus = devicesMap.get(equipmentInfo.getPlatformId() + equipmentInfo.getEquipmentNo());
        //                    if (Objects.nonNull(videoStatus)) {
        //                        equipmentInfoVo.setVideoStatus(videoStatus);
        //                    }else {
        //                        equipmentInfoVo.setVideoStatus("OFF");
        //                    }
        //                    equipmentInfoList.add(equipmentInfoVo);
        //                }
        //                equipmentInfoMap.put(carPlate,equipmentInfoList);
        //            }
        //            carInfoVo.setEquipmentInfoMap(equipmentInfoMap);
        //            carInfoList.add(carInfoVo);
        //            carInfoMap.put(companyDto.getId(),carInfoList);
        //            companyCarInfoVo.setCarInfoMap(carInfoMap);
        //            return companyCarInfoVo;
        //        }
        //    }else {
        //        throw new BizException("查询车辆不存在!");
        //    }
        //
        //}

        HashMap<Long, List<CarInfoVO>> carInfoMap = MapUtil.newHashMap();
        // 获取单个区域的数据
        if (CollUtil.isEmpty(req.getRegionIdList())) {
            List<CompanyVO> companyVoList = Lists.newArrayList();
            List<Company> companyList = Lists.newArrayList();
            // 如果登录用户是企业用户
            if (UserRoleTypeEnum.COMPANY_INFO_OFFICER_ROLE_ID.getId().equals(roleId)) {
                Long companyId = userDetail.getCompanyId();
                String companyName = userDetail.getCompanyName();
                Long regId = userDetail.getRegionId();
                CompanyVO companyVo = new CompanyVO();
                companyVo.setId(companyId);
                companyVo.setName(companyName);
                companyVo.setRegionId(regId);
                companyVoList.add(companyVo);
                companyList.add(companyService.getById(companyId));
            }else {
                // 获取该区域下的所有企业
                companyList = companyService.list(Wrappers.lambdaQuery(Company.class)
                        .in(Company::getCompanyType, Lists.newArrayList(1, 2, 3))
                        .eq(Company::getRegionId, regionId));
                companyVoList = companyList.stream().map(c -> {
                    CompanyVO companyVo = new CompanyVO();
                    companyVo.setId(c.getId());
                    companyVo.setName(c.getName());
                    companyVo.setRegionId(c.getRegionId());
                    return companyVo;
                }).collect(Collectors.toList());
            }
            companyCarInfoVo.setCompanyList(companyVoList);
            stopWatch4.start();
            for (Company company : companyList) {
                List<CarInfoVO> carInfoList = Lists.newArrayList();
                List<NdVehicleBaseInfo> vehicleBaseInfos = companyCarMap.get(company.getId());
                // 该企业下没有车,直接跳过
                if (CollUtil.isEmpty(vehicleBaseInfos)) {
                    continue;
                }
                // 如果登录用户是运营商，只过滤出运营商下的车辆
                if (UserRoleTypeEnum.OPERATOR_ROLE_ID.getId().equals(roleId)) {
                    String companyName = userDetail.getCompanyName();
                    // 暂时控制运营商名称和运营商所在企业名称相同
                    OperatorQueryDTO operatorQueryDTO = operatorsCacheHelper.getByName(companyName);
                    // 获取运营商id
                    Long operatorId = operatorQueryDTO.getId();
                    vehicleBaseInfos = vehicleBaseInfos.stream().filter(v -> operatorId.equals(v.getOperatorId()))
                        .collect(Collectors.toList());
                }
                // 如果登录用户是企业用户
                else if (UserRoleTypeEnum.COMPANY_INFO_OFFICER_ROLE_ID.getId().equals(roleId)) {
                    LambdaQueryWrapper<NdVehicleBaseInfo> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfo.class);
                    wrapper.and(w -> w.eq(NdVehicleBaseInfo::getCompanyId, company.getId()).or().eq(NdVehicleBaseInfo::getUseCompanyId, company.getId()));
                    vehicleBaseInfos = vehicleBaseInfoService.list(wrapper);
                }
                for (NdVehicleBaseInfo vehicleBaseInfo : vehicleBaseInfos) {
                    String carNo = vehicleBaseInfo.getCarPlate();
                    Long vehicleId = vehicleBaseInfo.getId();
                    CarInfoVO carInfoVo = new CarInfoVO();
                    carInfoVo.setCompanyId(company.getId());
                    carInfoVo.setCarPlate(carNo);
                    Integer moving = carStatusMap.get(carNo);
                    carInfoVo.setMoving(moving);
                    List<VehicleEquipmentNo> vehicleEquipmentNos = carEquipmentNoMap.get(carNo);
                    HashMap<String, List<EquipmentInfoVO>> equipmentInfoMap = MapUtil.newHashMap();
                    if (CollUtil.isNotEmpty(vehicleEquipmentNos)) {
                        List<EquipmentInfoVO> equipmentInfoList = Lists.newArrayList();
                        for (VehicleEquipmentNo equipmentInfo : vehicleEquipmentNos) {
                            EquipmentInfoVO equipmentInfoVo = new EquipmentInfoVO();
                            equipmentInfoVo.setCarPlate(carNo);
                            equipmentInfoVo.setDeviceId(equipmentInfo.getDeviceId());
                            equipmentInfoVo.setDeviceName(equipmentInfo.getDeviceName());
                            String videoStatus = equipmentInfo.getStatus();
                            if (Objects.nonNull(videoStatus)) {
                                equipmentInfoVo.setVideoStatus(videoStatus);
                            } else {
                                equipmentInfoVo.setVideoStatus("OFF");
                            }
                            equipmentInfoList.add(equipmentInfoVo);
                        }
                        equipmentInfoMap.put(carNo, equipmentInfoList);
                        carInfoVo.setEquipmentInfoMap(equipmentInfoMap);
                    }
                    carInfoList.add(carInfoVo);
                    carInfoMap.put(company.getId(), carInfoList);
                }
            }
            stopWatch4.stop();
            log.info("装配车辆信息 耗时 {}s", stopWatch2.getTotalTimeSeconds());

        }else {
            // 获取多个区域的企业数据
            List<Company> companyList = companyService.list(Wrappers.lambdaQuery(Company.class)
                    .in(Company::getCompanyType, Lists.newArrayList(1, 2, 3))
                    .in(Company::getRegionId, req.getRegionIdList()));
            List<CompanyVO> companyVoList = companyList.stream().map(c -> {
                CompanyVO companyVo = new CompanyVO();
                companyVo.setId(c.getId());
                companyVo.setName(c.getName());
                companyVo.setRegionId(c.getRegionId());
                return companyVo;
            }).collect(Collectors.toList());
            companyCarInfoVo.setCompanyList(companyVoList);
        }


        //// 获取单个区域的数据
        //if (CollUtil.isEmpty(req.getRegionIdList())) {
        //    List<CompanyVO> companyVoList = Lists.newArrayList();
        //    List<Company> companyList = Lists.newArrayList();
        //    // 如果登录用户是企业用户
        //    if (UserRoleTypeEnum.COMPANY_INFO_OFFICER_ROLE_ID.getId().equals(roleId)) {
        //        Long companyId = userDetail.getCompanyId();
        //        String companyName = userDetail.getCompanyName();
        //        Long regId = userDetail.getRegionId();
        //        CompanyVO companyVo = new CompanyVO();
        //        companyVo.setId(companyId);
        //        companyVo.setName(companyName);
        //        companyVo.setRegionId(regId);
        //        companyVoList.add(companyVo);
        //        companyList.add(companyService.getById(companyId));
        //    }else {
        //        // 获取该区域下的所有企业
        //        companyList = companyService.list(Wrappers.lambdaQuery(Company.class)
        //                .in(Company::getCompanyType, Lists.newArrayList(1, 2, 3))
        //                .eq(Company::getRegionId, regionId));
        //        companyVoList = companyList.stream().map(c -> {
        //            CompanyVO companyVo = new CompanyVO();
        //            companyVo.setId(c.getId());
        //            companyVo.setName(c.getName());
        //            companyVo.setRegionId(c.getRegionId());
        //            return companyVo;
        //        }).collect(Collectors.toList());
        //    }
        //    companyCarInfoVo.setCompanyList(companyVoList);
        //    stopWatch4.start();
        //    for (Company company : companyList) {
        //        List<CarInfoVO> carInfoList = Lists.newArrayList();
        //        List<NdVehicleBaseInfo> vehicleBaseInfos = companyCarMap.get(company.getId());
        //        // 该企业下没有车,直接跳过
        //        if (CollUtil.isEmpty(vehicleBaseInfos)) {
        //            continue;
        //        }
        //        // 如果登录用户是运营商，只过滤出运营商下的车辆
        //        if (UserRoleTypeEnum.OPERATOR_ROLE_ID.getId().equals(roleId)) {
        //            String companyName = userDetail.getCompanyName();
        //            // 暂时控制运营商名称和运营商所在企业名称相同
        //            OperatorQueryDTO operatorQueryDTO = operatorsCacheHelper.getByName(companyName);
        //            // 获取运营商id
        //            Long operatorId = operatorQueryDTO.getId();
        //            vehicleBaseInfos = vehicleBaseInfos.stream().filter(v -> operatorId.equals(v.getOperatorId()))
        //                    .collect(Collectors.toList());
        //        }
        //        // 如果登录用户是企业用户
        //        else if (UserRoleTypeEnum.COMPANY_INFO_OFFICER_ROLE_ID.getId().equals(roleId)) {
        //            LambdaQueryWrapper<NdVehicleBaseInfo> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfo.class);
        //            wrapper.and(w -> w.eq(NdVehicleBaseInfo::getCompanyId, company.getId()).or().eq(NdVehicleBaseInfo::getUseCompanyId, company.getId()));
        //            vehicleBaseInfos = vehicleBaseInfoService.list(wrapper);
        //        }
        //        for (NdVehicleBaseInfo vehicleBaseInfo : vehicleBaseInfos) {
        //            String carNo = vehicleBaseInfo.getCarPlate();
        //            Long vehicleId = vehicleBaseInfo.getId();
        //            CarInfoVO carInfoVo = new CarInfoVO();
        //            carInfoVo.setCompanyId(company.getId());
        //            carInfoVo.setCarPlate(carNo);
        //            Integer moving = carStatusMap.get(carNo);
        //            carInfoVo.setMoving(moving);
        //            List<NdVehicleEquipmentInfo> equipmentInfos = equipmentMap.get(vehicleId);
        //            HashMap<String, List<EquipmentInfoVO>> equipmentInfoMap = MapUtil.newHashMap();
        //            if (CollUtil.isNotEmpty(equipmentInfos)) {
        //                List<EquipmentInfoVO> equipmentInfoList = Lists.newArrayList();
        //                for (NdVehicleEquipmentInfo equipmentInfo : equipmentInfos) {
        //                    EquipmentInfoVO equipmentInfoVo = new EquipmentInfoVO();
        //                    equipmentInfoVo.setCarPlate(carNo);
        //                    equipmentInfoVo.setDeviceId(equipmentInfo.getEquipmentNo());
        //                    String deviceName = channelsMap.get(equipmentInfo.getId());
        //                    equipmentInfoVo.setDeviceName(deviceName);
        //                    String videoStatus =
        //                            devicesMap.get(equipmentInfo.getPlatformId() + equipmentInfo.getEquipmentNo());
        //                    if (Objects.nonNull(videoStatus)) {
        //                        equipmentInfoVo.setVideoStatus(videoStatus);
        //                    } else {
        //                        equipmentInfoVo.setVideoStatus("OFF");
        //                    }
        //                    equipmentInfoList.add(equipmentInfoVo);
        //                }
        //                equipmentInfoMap.put(carNo, equipmentInfoList);
        //                carInfoVo.setEquipmentInfoMap(equipmentInfoMap);
        //            }
        //            carInfoList.add(carInfoVo);
        //            carInfoMap.put(company.getId(), carInfoList);
        //        }
        //    }
        //    stopWatch4.stop();
        //    log.info("装配车辆信息 耗时 {}s", stopWatch2.getTotalTimeSeconds());
        //
        //}else {
        //    // 获取多个区域的企业数据
        //    List<Company> companyList = companyService.list(Wrappers.lambdaQuery(Company.class)
        //            .in(Company::getCompanyType, Lists.newArrayList(1, 2, 3))
        //            .in(Company::getRegionId, req.getRegionIdList()));
        //    List<CompanyVO> companyVoList = companyList.stream().map(c -> {
        //        CompanyVO companyVo = new CompanyVO();
        //        companyVo.setId(c.getId());
        //        companyVo.setName(c.getName());
        //        companyVo.setRegionId(c.getRegionId());
        //        return companyVo;
        //    }).collect(Collectors.toList());
        //    companyCarInfoVo.setCompanyList(companyVoList);
        //}

        companyCarInfoVo.setCarInfoMap(carInfoMap);
        companyCarInfoVo.setRegionId(regionId);
        return companyCarInfoVo;
    }

    public List<RegionCompanyCarTreeVo> getRegionCompanyTree(RegionTreeReq req) {

        Map<Long, List<RegionTreeCompanyVO>> companyMap = null;
        Optional<DataScopeDto> dataScope = DataScopeContext.getDataScope(LoginUserUtil.loginUserDetail().getDataScope());
        if (req != null) {
            if (req.getWithCompany()) {
                companyMap = companiesCacheHelper.all().stream()
                        .map(w -> BeanUtil.copyProperties(w, RegionTreeCompanyVO.class))
                        .filter(c -> DataScopeCacheFilterUtil.dataScopeFilter(c, dataScope))
                        // 过滤掉管理企业
                        .filter(c -> !CompanyTypeEnum.MANAGE_BU.getCode().equals(c.getCompanyType()))
                        .filter(item -> Objects.nonNull(item.getRegionId()))
                        .collect(Collectors.groupingBy(RegionTreeCompanyVO::getRegionId));
            }
        }
        Map<Long, List<RegionDTO>> regionMap = CollUtils.group(regionsCacheHelper.getAllWithRole(dataScope, companiesCacheHelper), RegionDTO::getParentId);

        return RegionConverter.toRegionCompanyCarNoTree(ROOT_PARENT_ID, regionMap, false, null, companyMap,null,null,null);
    }
}
