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

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.thinkunion.park.service.common.constant.CommonConstant;
import com.thinkunion.park.service.common.enums.parking.ParkIdEnum;
import com.yuchen.saas.manage.system.api.entity.NestRoleBusiness;
import com.yuchen.saas.manage.system.api.feign.RoleV1FeignServer;
import com.yuchen.saas.manage.system.api.vo.RoleV1BusinessScopeVO;
import com.yuchen.saas.park.api.dto.park.AddSubSiteNumReqDTO;
import com.yuchen.saas.park.api.dto.park.ParkInfoPageQueryDTO;
import com.yuchen.saas.park.api.dto.park.ParkInfoStatusUpdateDTO;
import com.yuchen.saas.park.api.dto.park.VerifyParkReqDTO;
import com.yuchen.saas.park.api.entity.park.*;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingUnit;
import com.yuchen.saas.park.api.entity.property.PropertyBuildings;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingsLevel;
import com.yuchen.saas.park.api.entity.property.PropertyHouses;
import com.yuchen.saas.park.api.response.ParkInfoResponse;
import com.yuchen.saas.park.api.vo.park.*;
import com.yuchen.saas.park.api.vo.park.alarm.AlarmBasicInformationVO;
import com.yuchen.saas.park.service.mapper.PmgBatParkInfoMapper;
import com.yuchen.saas.park.service.service.*;
import com.yuchen.saas.park.service.service.accredit.ISaasParkAccreditInfoService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingUnitService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsLevelService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsService;
import com.yuchen.saas.park.service.service.property.PropertyHousesService;
import com.yuchen.saas.parking.api.entity.PmgBatParkParking;
import com.yuchen.saas.parking.api.feign.PmgBatParkParkingClient;
import com.yuchen.saas.parking.charge.api.entity.charge.SpcStation;
import com.yuchen.saas.parking.charge.api.feign.SpcStationFeignClient;
import com.yuchen.saas.parking.charge.api.vo.charge.SpcStationStatisticsVO;
import com.yuchen.saas.payment.api.entity.setting.SaasPaymentSiteConfig;
import com.yuchen.saas.payment.api.feign.setting.PaymentSettingFeign;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.mp.base.BaseEntity;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.Condition;
import org.nest.springwrap.core.mp.support.NestPage;
import org.nest.springwrap.core.mp.support.Query;
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.utils.Func;
import org.nest.springwrap.core.tool.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 刘通
 * @date 2020/12/25 17:54
 */
@Service
public class PmgBatParkInfoServiceImpl extends BaseServiceImpl<PmgBatParkInfoMapper, PmgBatParkInfo> implements PmgBatParkInfoService {

    /**
     * 设备服务
     */
    @Resource
    private ParkDeviceDataService parkDeviceDataService;

    @Resource
    private IWarningInfoService iWarningInfoService;

    /**
     * 园区入园人员统计表服务
     */
    @Resource
    private IPeopleCountService iPeopleCountService;

    @Resource
    private PmgBatSmartEquipmentService pmgBatSmartEquipmentService;

    /**
     * 视频事件
     */
    @Autowired
    private PmgLogVideoEventsCountService pmgLogVideoEventsCountService;

    @Resource
    private PmgBatParkBuildingInfoService pmgBatParkBuildingInfoService;

    @Resource
    private PropertyBuildingsService propertyBuildingsService;

    @Resource
    private PropertyBuildingUnitService propertyBuildingUnitService;

    @Resource
    private PropertyBuildingsLevelService propertyBuildingsLevelService;

    @Resource
    private PropertyHousesService propertyHousesService;

    @Resource
    private PmgBatPointLocationInfoService pmgBatPointLocationInfoService;

    @Resource
    private PmgBatParkFloorInfoService pmgBatParkFloorInfoService;

    @Resource
    private PmgBatParkRoomInfoService pmgBatParkRoomInfoService;

    @Resource
    private NestRedis nestRedis;

    @Resource
    private RoleV1FeignServer roleV1FeignServer;

    @Resource
    private INestApplyManageParkBindingService iNestApplyManageParkBindingService;
    @Resource
    private PmgBatParkParkingClient parkingClient;
    @Resource
    private SpcStationFeignClient spcStationFeignClient;
    @Resource
    private PaymentSettingFeign paymentSettingFeign;
    @Resource
    private ISaasParkAccreditInfoService parkAccreditInfoService;

    @Override
    public Boolean addPark(PmgBatParkInfo parkInfo) {
        return saveOrUpdate(parkInfo);
    }

    @Override
    public Map<String, Object> statement(Long id) {
        Map<String, Object> map = new HashMap<>();
        PmgBatParkInfoCountVo pmgBatParkInfoCountVo = baseMapper.statementCount(id);
        //表头信息封装
        map.put("pmgBatParkInfoCountVo", pmgBatParkInfoCountVo);
        //楼宇报表信息
        List<PmgBatParkCountVo> list = baseMapper.parkIntoCount(id);
        map.put("pmgBatParkCountVo", list);
        return map;
    }

    @Override
    public PmgBatParkInfo parkDetail(PmgBatParkInfo pmgBatParkInfo) {
        PmgBatParkInfoCountVo pmgBatParkInfoCountVo = baseMapper.statementCount(pmgBatParkInfo.getId());
        pmgBatParkInfo
                //空置房间数
                .setNumberVacantRooms((long) pmgBatParkInfoCountVo.getParkRoomUnborn())
                //入住企业
                .setInenterprise((long) pmgBatParkInfoCountVo.getParkCompanyCount())
                //封装楼宇数量
                .setBuildingNumber((long) pmgBatParkInfoCountVo.getBuildingCount())
                //计算置空率
                .setEmptyRate((pmgBatParkInfoCountVo.getParkRoomUnborn() > 0 && pmgBatParkInfoCountVo.getParkRoomCount() > 0) ?
                        (new BigDecimal((float) pmgBatParkInfoCountVo.getParkRoomUnborn() / pmgBatParkInfoCountVo.getParkRoomCount()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()) * 100 : 0);
        return pmgBatParkInfo;
    }

    @Override
    public List<PmgParkBuildingInfoVo> buildingCount(Long id) {
        return baseMapper.buildingCount(id);
    }

    @Override
    public Object listFileUrl(String parkId) {
        //查询所有的园区相册缩略图片
        return null;
    }

    @Override
    public List<PmgBatParkInfo> getAllPark() {

        return list();
    }

    @Override
    public List<PmgBatParkInfo> getAllPark(String roleId, Integer isAdmin, String deptId,String tenantId) {

        List<PmgBatParkInfo> allParks=list().stream().filter(item->item.getOperateStatus() == 2).collect(Collectors.toList());
        List<PmgBatParkInfo> roleParks;
        if( AuthUtil.isAdministrator()){
            if(StringUtil.isNotBlank(tenantId)) {
                roleParks = allParks.stream().filter(item->item.getTenantId().equals(tenantId)).collect(Collectors.toList());
            }else{
                roleParks = allParks;
            }
        }else{
            if(isAdmin==1){
                roleParks=baseMapper.deptPark(deptId);

            }else{
               if( StringUtil.isNotBlank(roleId)&&!"-1".equals(roleId)) {
                   roleParks = baseMapper.rolePark(Func.toLongList(roleId));
               }else{
                   roleParks=null;
                }
            }
        }
        return roleParks;
    }

    @Override
    public List<PmgBatParkInfo> getAllParkV1(String roleId, Integer isAdmin, String deptId,String tenantId,Long orgUserId) {

        List<PmgBatParkInfo> allParks=list().stream().filter(item->item.getOperateStatus() == 2).collect(Collectors.toList());
        List<PmgBatParkInfo> roleParks;
        ContextUser user = AuthUtil.getUser();
        Long customerManageId = user.getCustomerManageId();
        if( AuthUtil.isAdministrator()){
            if(StringUtil.isNotBlank(tenantId)) {
                roleParks = allParks.stream().filter(item->item.getTenantId().equals(tenantId)).collect(Collectors.toList());
            }else{
                roleParks = allParks;
            }
        }else if (CommonConstant.ADMIN_DEPT.equals(deptId)){
            if(isAdmin==1){
                roleParks=allParks;
            }else {
                R<RoleV1BusinessScopeVO> result = roleV1FeignServer.getBusinessScopeList(orgUserId, Long.valueOf(deptId), 1);
                if (result.isSuccess()&&Func.isNotEmpty(result)&&Func.isNotEmpty(result.getData())){
                    RoleV1BusinessScopeVO businessScopeVO = result.getData();
                    if (Func.isNotEmpty(businessScopeVO.getBusinessScopeType()) &&businessScopeVO.getBusinessScopeType()==1){
                        roleParks = allParks;
                    }else if (Func.isNotEmpty(businessScopeVO.getBusinessScopeIds())) {
                        List<Long> longList = businessScopeVO.getBusinessScopeIds().stream().map(NestRoleBusiness::getBusinessScopeId).collect(Collectors.toList());
                        LambdaQueryWrapper<PmgBatParkInfo> parkInfoLambdaQueryWrapper = Wrappers.lambdaQuery();
                        parkInfoLambdaQueryWrapper.in(PmgBatParkInfo::getId, longList);
                        roleParks = list(parkInfoLambdaQueryWrapper);
                    } else {
                        roleParks = new ArrayList<>();
                    }
                }else {
                    return new ArrayList<>();
                }

            }

        }else if (isAdmin == 1) {
            List<Long> projectIdList = parkAccreditInfoService.getProjectAccreditProjectIdList(customerManageId);
            roleParks = Optional.ofNullable(projectIdList)
                    .filter(Func::isNotEmpty)
                    .map(list -> allParks.stream()
                            .filter(item -> list.contains(item.getId()))
                            .collect(Collectors.toList()))
                    .orElseGet(ArrayList::new);
            roleParks.addAll(allParks.stream()
                    .filter(item -> Func.isNotEmpty(item.getOperator())&&item.getOperator().equals(customerManageId))
                            .distinct()
                    .collect(Collectors.toList()));
        } else {
            R<RoleV1BusinessScopeVO> result = roleV1FeignServer.getBusinessScopeList(orgUserId, Long.valueOf(deptId), 1);
            if (result.isSuccess() && Func.isNotEmpty(result) && Func.isNotEmpty(result.getData())) {
                RoleV1BusinessScopeVO businessScopeVO = result.getData();
                if (Func.isNotEmpty(businessScopeVO.getBusinessScopeType())&&businessScopeVO.getBusinessScopeType() == 1) {

                    List<Long> projectIdList = parkAccreditInfoService.getProjectAccreditProjectIdList(customerManageId);
                    roleParks = Optional.ofNullable(projectIdList)
                            .filter(Func::isNotEmpty)
                            .map(list -> allParks.stream()
                                    .filter(item -> list.contains(item.getId()))
                                    .collect(Collectors.toList()))
                            .orElseGet(ArrayList::new);
                    roleParks.addAll(allParks.stream()
                            .filter(item -> Func.isNotEmpty(item.getOperator())&&item.getOperator().equals(customerManageId))
                            .distinct()
                            .collect(Collectors.toList()));
                } else if (Func.isNotEmpty(businessScopeVO.getBusinessScopeIds())) {
                    List<Long> longList = businessScopeVO.getBusinessScopeIds()
                            .stream()
                            .map(NestRoleBusiness::getBusinessScopeId)
                            .collect(Collectors.toList());
                    LambdaQueryWrapper<PmgBatParkInfo> parkInfoLambdaQueryWrapper = Wrappers.lambdaQuery();
                    parkInfoLambdaQueryWrapper.in(PmgBatParkInfo::getId, longList);
                    roleParks = list(parkInfoLambdaQueryWrapper);
                } else {
                    roleParks = new ArrayList<>();
                }
            }else {
                return new ArrayList<>();
            }

        }
        return roleParks;
    }

    @Override
    public List<PmgBatParkInfo> getCanInvoiceList(Long customerId, String parkIds) {
        List<PmgBatParkInfo> parkInfoList = this.lambdaQuery().eq(PmgBatParkInfo::getOperator, customerId).list();
        List<PmgBatParkInfo> removeList = new ArrayList<>();
        for (PmgBatParkInfo parkInfo : parkInfoList) {
            if (nestRedis.get("invoice:park:id:" + parkInfo.getId()) != null) {
                removeList.add(parkInfo);
            }
        }
        parkInfoList.removeAll(removeList);
        if (Func.isNotEmpty(parkIds)) {
            List<Long> parkIdList = Arrays.stream(parkIds.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
            List<PmgBatParkInfo> myList = this.lambdaQuery().in(PmgBatParkInfo::getId, parkIdList).list();
            parkInfoList.addAll(myList);
        }
        return parkInfoList;
    }

    @Override
    public Map<String, Object> getParkAll(Long parkId,Long buildingId, Long floorId) {

        //首页统一接口 创建总返回对象
        Map<String, Object> all = new HashMap<>(11);

        //1.园区基本信息
        PmgBatParkInfo baseInfo = this.parkDetail(this.getById(parkId));
        all.put("baseInfo",baseInfo);

        //2.环境四个指标
        all.put("environmentInfo",null);

        //3.告警信息三个指标
        AlarmBasicInformationVO alarmInfo = iWarningInfoService.
                getBasicInformation(parkId, buildingId, floorId);
        all.put("alarmInfo",alarmInfo);

        //4.能耗信息四个指标

        all.put("energyInfo",null);

        //5.人员信息
        Map<String, String> personInfo = iPeopleCountService.getPeopleInfo(parkId,buildingId,floorId);
        all.put("personInfo",personInfo);

        //6.停车场信息 parkingInfo


        //7.设备信息
        DeviceOnLineCountVo byOnLineCount = pmgBatSmartEquipmentService.getByOnLineCount(parkId, buildingId, floorId);
        //返回对象
        DeviceOnLineCount deviceInfo = new DeviceOnLineCount();
        //设备总数
        deviceInfo.setDeviceCount(byOnLineCount.getDeviceCount());
        //在线设备
        deviceInfo.setOnlineDevice(byOnLineCount.getOnlineDevice());
        //离线设备
        deviceInfo.setWarningDevice(byOnLineCount.getWarningDevice());
        //故障设备 = 离线设备
        deviceInfo.setFaultDevice(byOnLineCount.getWarningDevice());
        all.put("deviceInfo",deviceInfo);

        //8.告警列表
        PmgBatWarningInfo pmgBatWarningInfo = new PmgBatWarningInfo();
        pmgBatWarningInfo.setParkId(parkId);
        IPage<PmgBatWarningInfo> alarmList = iWarningInfoService.page(Condition.getPage(new Query().setCurrent(1).setSize(30)),
                Condition.getQueryWrapper(pmgBatWarningInfo).orderByDesc("event_time"));
        all.put("alarmList",alarmList.getRecords());

        //9.人员异常行为列表
        PmgLogVideoEventsCount pmgLogVideoEventsCount = new PmgLogVideoEventsCount();
        pmgLogVideoEventsCount.setParkId(parkId);
        IPage<PmgLogVideoEventsCount> abnormalList = pmgLogVideoEventsCountService.page(Condition.getPage(new Query().setCurrent(1).setSize(30)),
                Condition.getQueryWrapper(pmgLogVideoEventsCount).orderByDesc("time_stamp"));
        all.put("abnormalList",abnormalList.getRecords());

        //楼层场景显示改楼层详情信息
        if(!Func.isEmpty(parkId) && !Func.isEmpty(buildingId) && !Func.isEmpty(floorId)){
            all.put("floorInfo",queryFloorWrapper(parkId,buildingId,floorId));
        }

        //楼栋场景显示改栋详情信息
        if(!Func.isEmpty(parkId) && !Func.isEmpty(buildingId)){
            all.put("buildingInfo",queryBuildingWrapper(parkId,buildingId));
        }


        return all;
    }

    /****************************** 3d/bi start *****************************/

    @Override
    public PmgBatParkTreeVo getParkTree(String parkId) {

        PmgBatParkTreeVo result = new PmgBatParkTreeVo();

        //楼栋信息集合
        List<PmgBatParkTreeVo> buildingList = new ArrayList<>();

        //获取园区信息
        PmgBatParkInfo pmgBatParkInfo = baseMapper.selectById(parkId);

        result.setId(pmgBatParkInfo.getId());
        result.setType(1);
        result.setName(pmgBatParkInfo.getParkName());
        result.setMark(pmgBatParkInfo.getSMark());
        result.setParentId(0L);

        //园区下所以楼栋信息
        List<PmgBatParkBuildingInfo> allBuilding = pmgBatParkBuildingInfoService.getAll(String.valueOf(pmgBatParkInfo.getId()));

        //循环根据楼栋id获取楼层信息
        allBuilding.forEach(building ->{

            PmgBatParkTreeVo buildingTree = new PmgBatParkTreeVo();
            buildingTree.setId(building.getId());
            buildingTree.setName(building.getBuildingName());
            buildingTree.setType(2);
            buildingTree.setMark(building.getBMark());
            buildingTree.setParentId(pmgBatParkInfo.getId());
            buildingList.add(buildingTree);


            RoomVo roomVo = new RoomVo();
            roomVo.setRoomType(0);
            roomVo.setRoomStatus(0);
            roomVo.setDecorateStatus(0);
            roomVo.setRoomArea(00);
            roomVo.setRoomPrice(00);
            roomVo.setBuildingIds(building.getId());
            //楼层信息
            List<PmgBatParkFloorInfo> allFloor = pmgBatParkFloorInfoService.getAll(roomVo);
            //楼层信息集合
            List<PmgBatParkTreeVo> floorList = new ArrayList<>();
            allFloor.forEach(floor ->{

                PmgBatParkTreeVo floorTree = new PmgBatParkTreeVo();
                floorTree.setId(floor.getId());
                floorTree.setName(floor.getFloorName());
                floorTree.setType(3);
                floorTree.setMark(floor.getLMark());
                floorTree.setParentId(building.getId());
                floorList.add(floorTree);

                //房间信息
                List<PmgbatParkRoomVo> allRoom = floor.getList();
                //房间信息集合
                List<PmgBatParkTreeVo> roomList = new ArrayList<>();

                allRoom.forEach(room ->{

                    PmgBatParkTreeVo roomTree = new PmgBatParkTreeVo();
                    PmgBatParkRoomInfo roomInfo = room.getPmgBatParkRoomInfo();
                    roomTree.setId(roomInfo.getId());
                    roomTree.setName(roomInfo.getRoomName());
                    roomTree.setType(4);
                    roomTree.setMark(roomInfo.getRemark());
                    roomTree.setParentId(floor.getId());
                    roomList.add(roomTree);
                });

                //房间信息
                floorTree.setChildrenVoList(roomList);

            });

            //楼层信息
            buildingTree.setChildrenVoList(floorList);

        });

        //楼栋信息
        result.setChildrenVoList(buildingList);

        return result;
    }

    @Override
    public List<ParkInfoResponse> getParkListByScopeValue(String tenantId, String scopeValue) {
        List<PmgBatParkInfo>  parkInfoResponsesList = this.lambdaQuery().eq(PmgBatParkInfo::getTenantId,tenantId).last(scopeValue).list();
        if(CollectionUtils.isEmpty(parkInfoResponsesList)){
            return Collections.EMPTY_LIST;
        }
        List<ParkInfoResponse> parkInfoResponseList = parkInfoResponsesList.stream().map(response->{
            ParkInfoResponse parkInfoResponse = new ParkInfoResponse();
            parkInfoResponse.setParkName(response.getParkName());
            parkInfoResponse.setId(response.getId());
            return parkInfoResponse;
        }).collect(Collectors.toList());
        return parkInfoResponseList;
    }

    @Override
    public List<ParkInfoResponse> getParkList(Long tenantId, Long parkId,String parkName) {
        List<PmgBatParkInfo>  parkInfoResponsesList = this.lambdaQuery()
                .eq(tenantId!=null,PmgBatParkInfo::getTenantId,tenantId)
                .eq(parkId!=null,PmgBatParkInfo::getId,parkId)
                .like(Func.isNotBlank(parkName),PmgBatParkInfo::getParkName,parkName)
                .list();
        if(CollectionUtils.isEmpty(parkInfoResponsesList)){
            return Collections.EMPTY_LIST;
        }
        List<ParkInfoResponse> parkInfoResponseList = parkInfoResponsesList.stream().map(response->{
            ParkInfoResponse parkInfoResponse = new ParkInfoResponse();
            parkInfoResponse.setParkName(response.getParkName());
            parkInfoResponse.setId(response.getId());
            return parkInfoResponse;
        }).collect(Collectors.toList());
        return parkInfoResponseList;
    }

    @Override
    public List<ParkInfoResponse> pageJt() {

        ArrayList list=new ArrayList();
        list.add(ParkIdEnum.BFTY.getCode());
        list.add(ParkIdEnum.JGZX.getCode());
        list.add(ParkIdEnum.TXYQ.getCode());
        list.add(ParkIdEnum.TXYQ_DM.getCode());
        List<PmgBatParkInfo>  parkInfoResponsesList = this.lambdaQuery()
                .in(PmgBatParkInfo::getId,list)
                .list();
        if(CollectionUtils.isEmpty(parkInfoResponsesList)){
            return Collections.EMPTY_LIST;
        }
        List<ParkInfoResponse> parkInfoResponseList = parkInfoResponsesList.stream().map(response->{
            ParkInfoResponse parkInfoResponse = new ParkInfoResponse();
            parkInfoResponse.setParkName(response.getParkName());
            parkInfoResponse.setId(response.getId());
            return parkInfoResponse;
        }).collect(Collectors.toList());
        return parkInfoResponseList;
    }

    @Override
    public List<PmgBatParkInfo> listAll(String cityName) {
        return baseMapper.listAll(cityName);
    }



    @Override
    public String getParkNamesByIds(String parkIds) {
        List<Long> parkIdList = Arrays.stream(parkIds.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        List<PmgBatParkInfo> parkInfoList = this.lambdaQuery().in(PmgBatParkInfo::getId, parkIdList).list();
        List<String> parkNameList = parkInfoList.stream().map(PmgBatParkInfo::getParkName).collect(Collectors.toList());
        return String.join(",", parkNameList);
    }

    @Override
    public Map<Long, String> getParkMap(List<Long> parkIds) {
        return this.listByIds(parkIds).stream().collect(Collectors.toMap(BaseEntity::getId, PmgBatParkInfo::getParkName));
    }

    @Override
    public Map<Long, String> getParkNameMap(List<Long> projectIdList) {
        return this.listByIds(projectIdList).stream().collect(Collectors.toMap(BaseEntity::getId, PmgBatParkInfo::getParkName));
    }

    @Override
    public Map<Long, PmgBatParkInfo> getParkInfoMap(List<Long> projectIdList) {
        return this.listByIds(projectIdList).stream().collect(Collectors.toMap(BaseEntity::getId, v -> v, (v1, v2) -> v2));
    }

    @Override
    public List<PmgBatParkInfo> listByApplyId(Long applyId) {
        List<NestApplyManageParkBinding>  list=iNestApplyManageParkBindingService.listByApplyId(applyId);
        List<PmgBatParkInfo> vo=new ArrayList<>();
        if(Func.isNotEmpty(list)){
            for (NestApplyManageParkBinding item:list) {
                vo.add(getById(item.getParkId()));
            }
        }
        return vo;
    }

    @Override
    public List<PmgBatParkInfo> getAllByOperator(Long operator) {
        ContextUser user = AuthUtil.getUser();
        List<PmgBatParkInfo> allParkV1 = this.getAllParkV1(null, user.getIsAdmin(), user.getDeptId(), user.getTenantId(), user.getOrgUserId());
        if (Func.isNotEmpty(operator)){
          return   allParkV1.stream().filter(e->operator.equals(e.getOperator())).collect(Collectors.toList());
        }else{
            return allParkV1;
        }
    }

    @Override
    public NestPage<PmgBatParkInfo> getPage(ParkInfoPageQueryDTO queryDTO) {
        LambdaQueryWrapper<PmgBatParkInfo> queryWrapper = Wrappers.lambdaQuery();
        ContextUser user = AuthUtil.getUser();
        List<PmgBatParkInfo> allParkV1 = getAllParkV1(null, user.getIsAdmin(), user.getDeptId(), user.getTenantId(), user.getOrgUserId());
        if(Func.isEmpty(allParkV1)){
            return new NestPage<>();
        }else {
            queryWrapper.in(PmgBatParkInfo::getId, allParkV1.stream().map(PmgBatParkInfo::getId).collect(Collectors.toList()));
        }
        queryWrapper.like(Func.isNotEmpty(queryDTO.getParkName()),PmgBatParkInfo::getParkName,queryDTO.getParkName());
        queryWrapper.like(Func.isNotEmpty(queryDTO.getOperatorName()),PmgBatParkInfo::getOperatorName,queryDTO.getOperatorName());
        queryWrapper.like(Func.isNotEmpty(queryDTO.getParkFunctionary()),PmgBatParkInfo::getParkFunctionary,queryDTO.getParkFunctionary());
        queryWrapper.like(Func.isNotEmpty(queryDTO.getPhone()),PmgBatParkInfo::getPhone,queryDTO.getPhone());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getOrgType()),PmgBatParkInfo::getOrgType,queryDTO.getOrgType());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getAreaCode()),PmgBatParkInfo::getAreaCode,queryDTO.getAreaCode());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getOperateStatus()),PmgBatParkInfo::getOperateStatus,queryDTO.getOperateStatus());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getParkType()),PmgBatParkInfo::getParkType,queryDTO.getParkType());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getVerifyState()),PmgBatParkInfo::getVerifyState,queryDTO.getVerifyState());
        queryWrapper.orderByDesc(PmgBatParkInfo::getCreateTime);
        IPage<PmgBatParkInfo> page = page(Condition.getPage(queryDTO), queryWrapper);
        return NestPage.of(page);
    }

    @Override
    public NestPage<PmgBatParkInfo> operatePage(ParkInfoPageQueryDTO queryDTO) {
        LambdaQueryWrapper<PmgBatParkInfo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(Func.isNotEmpty(queryDTO.getParkName()),PmgBatParkInfo::getParkName,queryDTO.getParkName());
        queryWrapper.like(Func.isNotEmpty(queryDTO.getParkFunctionary()),PmgBatParkInfo::getParkFunctionary,queryDTO.getParkFunctionary());
        queryWrapper.like(Func.isNotEmpty(queryDTO.getPhone()),PmgBatParkInfo::getPhone,queryDTO.getPhone());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getOperator()),PmgBatParkInfo::getOperator,queryDTO.getOperator());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getOrgType()),PmgBatParkInfo::getOrgType,queryDTO.getOrgType());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getAreaCode()),PmgBatParkInfo::getAreaCode,queryDTO.getAreaCode());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getOperateStatus()),PmgBatParkInfo::getOperateStatus,queryDTO.getOperateStatus());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getParkType()),PmgBatParkInfo::getParkType,queryDTO.getParkType());
        queryWrapper.eq(Func.isNotEmpty(queryDTO.getVerifyState()),PmgBatParkInfo::getVerifyState,queryDTO.getVerifyState());
        queryWrapper.orderByDesc(PmgBatParkInfo::getCreateTime);
        IPage<PmgBatParkInfo> page = page(Condition.getPage(queryDTO), queryWrapper);
        if (Func.isEmpty(page.getRecords())) {
            return NestPage.of(page);
        }
        // 项目id
        List<Long> parkIdList = page.getRecords().stream().map(BaseEntity::getId).collect(Collectors.toList());
        // 支付配置
        List<SaasPaymentSiteConfig> paymentSiteConfigList = paymentSettingFeign.getPaymentSiteConfigListBySiteIdList(parkIdList).getData();
        // 发布配置
        List<NestApplyManageParkBinding> parkBindingList = iNestApplyManageParkBindingService.listByParkIdList(parkIdList);
        Map<Long, List<NestApplyManageParkBinding>> resultMap = parkBindingList.stream()
                .collect(Collectors.groupingBy(NestApplyManageParkBinding::getParkId, Collectors.toList()));
        for (PmgBatParkInfo pmgBatParkInfo : page.getRecords()) {
            List<NestApplyManageParkBinding> list = resultMap.get(pmgBatParkInfo.getId());
            if (Func.isNotEmpty(list)) {
                pmgBatParkInfo.setPublishApplyIdList(list.stream().map(NestApplyManageParkBinding::getApplyId).collect(Collectors.toList()));
            }
            for (SaasPaymentSiteConfig saasPaymentSiteConfig : paymentSiteConfigList) {
                if (saasPaymentSiteConfig.getSiteId().equals(pmgBatParkInfo.getId())&&
                        StrUtil.equals(pmgBatParkInfo.getCollectFeeModel(), saasPaymentSiteConfig.getCollectFeeModel())) {
                    pmgBatParkInfo.setCollectFeeConfig(true);
                }
            }
        }
        return NestPage.of(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatus(ParkInfoStatusUpdateDTO dto) {
        PmgBatParkInfo parkInfo = this.getById(dto.getId());
        if (Func.isEmpty(parkInfo)){
            throw new ServiceException("园区不存在！");
        }
        if (dto.getOperateStatus() == 2) {
            if (!StringUtil.equals(parkInfo.getVerifyState(), "1")){
                throw new ServiceException("园区未确认，无法启动运营");
            }
            // 判断支付配置
            if (!StrUtil.equals(parkInfo.getCollectFeeModel(), "3")) {
                // 判断支付配置
                R<List<SaasPaymentSiteConfig>> result = paymentSettingFeign.getPaymentSiteConfigList(dto.getId(), parkInfo.getCollectFeeModel());
                if (!result.isSuccess()) {
                    throw new ServiceException(result.getMessage());
                }
                if (Func.isEmpty(result.getData())) {
                    throw new ServiceException("未配置支付配置，无法启动运营");
                }
            }
        }
        parkInfo.setOperateStatus(dto.getOperateStatus());
        return this.updateById(parkInfo);
    }

    @Override
    public Boolean verifyProject(VerifyParkReqDTO reqDTO) {
        PmgBatParkInfo parkInfo = this.getById(reqDTO.getProjectId());
        if (Func.isEmpty(parkInfo)){
            throw new ServiceException("数据不存在！");
        }
        parkInfo.setCollectFeeModel(reqDTO.getCollectFeeModel());
        parkInfo.setInvoiceModel(reqDTO.getInvoiceModel());
        // 确认项目
        parkInfo.setVerifyState("1");
        return this.updateById(parkInfo);
    }

    @Override
    public Boolean addSubSiteNum(AddSubSiteNumReqDTO reqDTO) {
        PmgBatParkInfo parkInfo = this.getById(reqDTO.getProjectId());
        if (Func.isEmpty(parkInfo)){
            throw new ServiceException("数据不存在！");
        }
        if (reqDTO.getSiteType() == 2) {
            parkInfo.setParkingNum(parkInfo.getParkingNum() + reqDTO.getSiteNum());
        }
        if (reqDTO.getSiteType() == 3) {
            parkInfo.setParkingChargeNum(parkInfo.getParkingChargeNum() + reqDTO.getSiteNum());
        }
        return updateById(parkInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteIds(String ids) {
        R<List<PmgBatParkParking>> parkingClientParkingListResult = parkingClient.getParkingList();
        List<PmgBatParkParking> pmgBatParkParkingList= parkingClientParkingListResult.getData().stream().filter(e -> Func.isNotEmpty(e.getParkId())&&ids.contains(e.getParkId())).collect(Collectors.toList());
        if (Func.isNotEmpty(pmgBatParkParkingList)){
            throw new ServiceException("此园区已绑定停车场，无法删除。");
        }
        R<List<SpcStation>> spcStationListResult = spcStationFeignClient.getSpcStationList();
        List<Long> idLongList = Func.toLongList(ids);
        List<SpcStation> spcStations = spcStationListResult.getData().stream().filter(e -> Func.isNotEmpty(e.getParkId())&&idLongList.contains(e.getParkId())).collect(Collectors.toList());
        if (Func.isNotEmpty(spcStations)){
            throw new ServiceException("此园区已绑定充电站，无法删除。");
        }
        return this.deleteLogic(idLongList);
    }

    /**
     * 普通方法 获取首页场景切换时楼栋的基本信息
     * @return
     */
    public BuildingFloorInfoVo queryBuildingWrapper(Long parkId,Long buildingId){
        BuildingFloorInfoVo buildingFloorInfoVo = new BuildingFloorInfoVo();
        PmgBatParkBuildingInfo buildingInfo = pmgBatParkBuildingInfoService.getById(buildingId);

        LambdaQueryWrapper<PmgBatParkFloorInfo> floorInfoLambdaQueryWrapper = Wrappers.lambdaQuery();
        floorInfoLambdaQueryWrapper.eq(PmgBatParkFloorInfo::getBuildingId,buildingId);
        List<PmgBatParkFloorInfo> floorList = pmgBatParkFloorInfoService.list(floorInfoLambdaQueryWrapper);

        int roomNumber = 0;
        int companyNumber = 0;
        for (PmgBatParkFloorInfo floor : floorList) {
            LambdaQueryWrapper<PmgBatParkRoomInfo> roomInfoLambdaQueryWrapper = Wrappers.lambdaQuery();
            roomInfoLambdaQueryWrapper.eq(PmgBatParkRoomInfo::getFloorId,floor.getId());
            roomNumber+= pmgBatParkRoomInfoService.count(roomInfoLambdaQueryWrapper);

            roomInfoLambdaQueryWrapper.eq(PmgBatParkRoomInfo::getLeaseStatus,1);
            companyNumber+= pmgBatParkRoomInfoService.count(roomInfoLambdaQueryWrapper);
        }


        buildingFloorInfoVo.setArea(buildingInfo.getBuildingArea());
        //todo 此处为模拟数据
        buildingFloorInfoVo.setBelowArea("230");
        buildingFloorInfoVo.setFloorNumber(floorList.size());
        buildingFloorInfoVo.setRoomNumber(roomNumber);
        //todo 此处为模拟数据
        buildingFloorInfoVo.setElevatorNumber(8);
        buildingFloorInfoVo.setCompanyNumber(companyNumber);
        return buildingFloorInfoVo;
    }


    /**
     * 普通方法 获取首页场景切换时楼层的基本信息
     * @return
     */
    public BuildingFloorInfoVo queryFloorWrapper(Long parkId,Long buildingId,Long floorId){
        BuildingFloorInfoVo buildingFloorInfoVo = new BuildingFloorInfoVo();
        PmgBatParkFloorInfo floorInfo = pmgBatParkFloorInfoService.getById(floorId);

        int roomNumber = 0;
        int companyNumber = 0;
        LambdaQueryWrapper<PmgBatParkRoomInfo> roomInfoLambdaQueryWrapper = Wrappers.lambdaQuery();
        roomInfoLambdaQueryWrapper.eq(PmgBatParkRoomInfo::getFloorId,floorId);
        roomNumber+= pmgBatParkRoomInfoService.count(roomInfoLambdaQueryWrapper);

        roomInfoLambdaQueryWrapper.eq(PmgBatParkRoomInfo::getLeaseStatus,1);
        companyNumber+= pmgBatParkRoomInfoService.count(roomInfoLambdaQueryWrapper);

        //todo 此处为模拟数据
        buildingFloorInfoVo.setArea("290");
        buildingFloorInfoVo.setRoomNumber(roomNumber);
        buildingFloorInfoVo.setCompanyNumber(companyNumber);
        return buildingFloorInfoVo;
    }



    @Override
    public List<PmgBatParkInfo> findListByDeptId(Long deptId) {
        ContextUser user = AuthUtil.getUser();
        Long customerManageId = user.getCustomerManageId();
        LambdaQueryWrapper<PmgBatParkInfo> parkInfoLambdaQueryWrapper = Wrappers.lambdaQuery(PmgBatParkInfo.class);
        parkInfoLambdaQueryWrapper.eq(!CommonConstant.ADMIN_DEPT.equals(String.valueOf(deptId)),PmgBatParkInfo::getOperator,customerManageId);
        return this.list(parkInfoLambdaQueryWrapper);
    }

    @Override
    public PmgBatParkInfo getSpaceTree(Long parkId) {



        //获取园区信息
        PmgBatParkInfo pmgBatParkInfo = baseMapper.selectById(parkId);



        //园区下所以楼栋信息
        List<PropertyBuildings> allBuilding = propertyBuildingsService.getAll(parkId);

        pmgBatParkInfo.setBuildings(allBuilding);


        //循环根据楼栋id获取楼层信息
        allBuilding.forEach(building ->{
            List<PropertyBuildingUnit> buildingUnits = propertyBuildingUnitService.getUnitsByBuildingId(building.getId());
            building.setBuildingUnits(buildingUnits);
            buildingUnits.forEach(unit ->{
                List<PropertyBuildingsLevel> levels = propertyBuildingsLevelService.getLevelsByBuildingAndUnitId(building.getId(), unit.getId());
                levels.forEach(level ->{
                    List<PropertyHouses> rooms = propertyHousesService.getRoomsByBuildingAndLevelId(building.getId(), level.getId());
                    rooms.forEach(room ->{
                        List<PmgBatPointLocationInfo> locations = pmgBatPointLocationInfoService.selectAllLocationPoint(parkId, building.getId(), level.getId(), room.getId());
                        room.setPointLocations(locations);
                    });
                    level.setRooms(rooms);
                });

                unit.setLevels(levels);
            });
            List<PropertyBuildingsLevel> level2 = propertyBuildingsLevelService.getLevelsByBuildingAndUnitId(building.getId(), null);
            level2.forEach(level ->{
                List<PropertyHouses> rooms = propertyHousesService.getRoomsByBuildingAndLevelId(building.getId(), level.getId());
                rooms.forEach(room ->{
                    List<PmgBatPointLocationInfo> locations = pmgBatPointLocationInfoService.selectAllLocationPoint(parkId, building.getId(), level.getId(), room.getId());
                    room.setPointLocations(locations);
                });
                level.setRooms(rooms);
            });
            building.setLevels(level2);


        });


        return pmgBatParkInfo;
    }

    @Override
    public ParkSpaceStatisticsVO getSpaceStatistics(Long parkId) {
        PmgBatParkInfo pmgBatParkInfo = this.getById(parkId);
        if (Func.isEmpty(pmgBatParkInfo)){
            throw new ServiceException("项目不存在！");
        }
        ParkSpaceStatisticsVO parkSpaceStatisticsVO = new ParkSpaceStatisticsVO();
        parkSpaceStatisticsVO.setArea(pmgBatParkInfo.getArea());
        int buildingsCount = propertyBuildingsService.count(new LambdaQueryWrapper<PropertyBuildings>().eq(PropertyBuildings::getParkId, parkId));
        parkSpaceStatisticsVO.setBuildingsCount(buildingsCount);
        int housesCount = propertyHousesService.count(new LambdaQueryWrapper<PropertyHouses>().eq(PropertyHouses::getParkId, parkId));
        parkSpaceStatisticsVO.setHousesCount(housesCount);
        R<List<PmgBatParkParking>> byParkIdNoPermissions = parkingClient.findByParkIdNoPermissions(parkId);
        if (R.isSuccess(byParkIdNoPermissions)&&Func.isNotEmpty(byParkIdNoPermissions.getData())){
            List<PmgBatParkParking> pmgBatParkParkingList = byParkIdNoPermissions.getData();
            parkSpaceStatisticsVO.setParkingCount(pmgBatParkParkingList.size());
            int placeCount = pmgBatParkParkingList.stream().filter(e -> Func.isNotEmpty(e.getTotalPlace())).mapToInt(PmgBatParkParking::getTotalPlace).sum();
            parkSpaceStatisticsVO.setParkingSpacesCount(placeCount);
        }else {
            parkSpaceStatisticsVO.setParkingSpacesCount(0);
            parkSpaceStatisticsVO.setParkingCount(0);
        }
        R<List<SpcStationStatisticsVO>> stationStatisticsByParkId = spcStationFeignClient.findStationStatisticsByParkId(parkId);
        if (R.isSuccess(stationStatisticsByParkId)&&Func.isNotEmpty(stationStatisticsByParkId.getData())){
            List<SpcStationStatisticsVO> stationStatisticsVOS = stationStatisticsByParkId.getData();
            parkSpaceStatisticsVO.setChargingCount(stationStatisticsVOS.size());
            int fastCount = stationStatisticsVOS.stream().filter(e -> Func.isNotEmpty(e.getTerminalFastCount())).mapToInt(SpcStationStatisticsVO::getTerminalFastCount).sum();
            int slowCount = stationStatisticsVOS.stream().filter(e -> Func.isNotEmpty(e.getTerminalSlowCount())).mapToInt(SpcStationStatisticsVO::getTerminalSlowCount).sum();
            parkSpaceStatisticsVO.setTerminalSlowCount(slowCount);
            parkSpaceStatisticsVO.setTerminalFastCount(fastCount);
        }else {
            parkSpaceStatisticsVO.setChargingCount(0);
            parkSpaceStatisticsVO.setTerminalSlowCount(0);
            parkSpaceStatisticsVO.setTerminalFastCount(0);
        }
        return parkSpaceStatisticsVO;
    }
}
