package org.springblade.community.controller.statistic.controller;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;

import org.springblade.common.constant.DeviceConstant;
import org.springblade.common.utils.SerializableUtil;
import org.springblade.community.controller.statistic.constant.RedisConstant;
import org.springblade.community.controller.statistic.entity.*;
import org.springblade.community.controller.statistic.vo.*;

import org.springblade.community.entity.*;
import org.springblade.community.service.*;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;

import org.springblade.device.entity.DoorDevice;
import org.springblade.device.entity.IotDevice;
import org.springblade.device.feign.IDoorDeviceClient;
import org.springblade.device.feign.IIotDeviceClient;
import org.springblade.device.vo.IotDeviceVO;
import org.springblade.enterprise.entity.Enterprise;
import org.springblade.enterprise.entity.Staff;
import org.springblade.enterprise.feign.IEnterpriseClient;
import org.springblade.enterprise.feign.IStaffClient;
import org.springblade.enterprise.vo.EnterpriseVO;
import org.springblade.estate.entity.*;
import org.springblade.estate.feign.*;
import org.springblade.estate.vo.AccessRecordVO;
import org.springblade.estate.vo.CarEnterRecordVO;
import org.springblade.estate.vo.CarOutRecordVO;
import org.springblade.estate.vo.TemperatureRecordVO;
import org.springblade.person.entity.HouseUser;
import org.springblade.person.entity.KeyPeople;
import org.springblade.person.feign.IHouseUserClient;
import org.springblade.person.feign.IKeyPeopleClient;
import org.springblade.system.entity.DictBiz;
import org.springblade.system.expand.entity.TenantType;
import org.springblade.system.expand.feign.IOrgPositionClient;
import org.springblade.system.expand.feign.ITenantTypeClient;
import org.springblade.system.expand.util.QueryWrapperUtil;
import org.springblade.system.feign.IDictBizClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

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


/**
 * 园区统计接口
 */
@RestController
@AllArgsConstructor
@RequestMapping("/statistics")
@Api(value = "大屏统计", tags = "大屏统计")
public class StatisticsController extends BladeController {

	private final IAgencyService agencyService;
	private final IResidentialService residentialService;
	private final IUnitService unitService;
	private final IRoomService roomService;
	private final IKeyPeopleClient keyPeopleClient;
	private final IParkingLotClient parkingLotClient;
	private final IParkingSpaceClient parkingSpaceClient;
	private final IIotDeviceClient iotDeviceClient;
	private final IDictBizClient dictBizClient;
	private final IHouseUserClient houseUserClient;
	private final IBuildingService buildingService;
	private final IOrgPositionClient orgPositionClient;
	private final IDoorDeviceClient doorDeviceClient;
	private final ICarEnterRecordClient carEnterRecordClient;
	private final ICarOutRecordClient carOutRecordClient;
	private final ITenantTypeClient tenantTypeClient;
	private final IEnterpriseClient enterpriseClient;
	private final IStaffClient staffClient;
	private final IServerUserClient serverUserClient;
	private final RedisTemplate<String,String> redisTemplate;
	private final ICarClient carClient;
	private final IAccessRecordClient accessRecordClient;
	/**
	 * 园区全景页面统计
	 */
	@GetMapping("/community")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "园区全景页面统计")
	@Transactional
	@ApiIgnore
	public CommunityStatistics community(BladeUser bladeUser){
		CommunityStatistics communityStatistics = new CommunityStatistics();
		//园区
		LambdaQueryWrapper<Agency> agencyLambdaQueryWrapper = new QueryWrapperUtil<Agency>().getBasicQueryWrapper(Agency::getOrgPosition,new Agency(),bladeUser,orgPositionClient);
		//园区列表
		communityStatistics.setAgencies(this.agencyService.list(agencyLambdaQueryWrapper));
		//园区统计
		communityStatistics.setAgencyCount(this.agencyService.count(agencyLambdaQueryWrapper));
		//小区
		LambdaQueryWrapper<Residential> residentialLambdaQueryWrapper = new QueryWrapperUtil<Residential>().getBasicQueryWrapper(Residential::getOrgPosition,new Residential(),bladeUser,orgPositionClient);
		communityStatistics.setResidentialCount(this.residentialService.count(residentialLambdaQueryWrapper));
		//楼栋
		LambdaQueryWrapper<Building> buildingLambdaQueryWrapper = new QueryWrapperUtil<Building>().getBasicQueryWrapper(Building::getOrgPosition,new Building(),bladeUser,orgPositionClient);
		communityStatistics.setBuildingCount(this.buildingService.count(buildingLambdaQueryWrapper));
		//单元
		LambdaQueryWrapper<Unit> unitLambdaQueryWrapper = new QueryWrapperUtil<Unit>().getBasicQueryWrapper(Unit::getOrgPosition,new Unit(),bladeUser,orgPositionClient);
		communityStatistics.setUnitCount(this.unitService.count(unitLambdaQueryWrapper));
		//房间
		LambdaQueryWrapper<Room> roomLambdaQueryWrapper = new QueryWrapperUtil<Room>().getBasicQueryWrapper(Room::getOrgPosition,new Room(),bladeUser,orgPositionClient);
		communityStatistics.setRoomCount(this.roomService.count(roomLambdaQueryWrapper));
		//车位
		communityStatistics.setParkingSpaceCount(this.parkingSpaceClient.list(new ParkingSpace()).size());
		//设备
		communityStatistics.setDeviceCount(this.iotDeviceClient.list(new IotDevice()).size());
		//人口
		communityStatistics.setPersonCount(this.houseUserClient.list(new HouseUser()).size());
		//常住人口
		HouseUser floatPeople = new HouseUser();
		floatPeople.setType(3);
		//流动人口
		Integer floatPeopleNum = this.houseUserClient.list(floatPeople).size();
		communityStatistics.setFloatPeopleCount(floatPeopleNum);
		communityStatistics.setPermanentPeopleCount(communityStatistics.getPersonCount() - floatPeopleNum);

		return communityStatistics;
	}

	/**
	 * 园区态势页面统计
	 */
	@GetMapping("/agency")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "园区态势统计")
	@Transactional
	@ApiIgnore
	public AgencyStatistics agency(Agency agency, BladeUser bladeUser){
//		String redisKey ="screen:"+ RedisConstant.AGENCY+":"+agency.getId();

		Agency agencyById = this.agencyService.getById(agency.getId());
		Assert.notNull(agencyById,"该园区不存在");
		AgencyStatistics agencyStatistics = new AgencyStatistics();
		List<Residential> residentials = this.residentialService.list(Condition.getQueryWrapper(new Residential()).lambda().eq(Residential::getAgencyId, agencyById.getId()));
		agencyStatistics.setResidentials(residentials);

		//楼栋和车位
		int buildingCount  = 0;
		int parkSpaceCount = 0;
		for(Residential residential : residentials){
			int count1 = this.buildingService.count(Condition.getQueryWrapper(new Building()).lambda().eq(Building::getResidentialId, residential.getId()));
			buildingCount = buildingCount + count1;
			ParkingSpace search = new ParkingSpace();
			search.setResidentialId(residential.getId());
			int count2 = this.parkingSpaceClient.list(search).size();
			parkSpaceCount = parkSpaceCount + count2;
		}

		// 楼宇数
		agencyStatistics.setBuildingCount(StringUtils.isEmpty(buildingCount + "") ? 0 : buildingCount);

		// 停车位数
		agencyStatistics.setParkingSpaceCount(StringUtils.isEmpty(parkSpaceCount + "") ? 0 : parkSpaceCount);

		//园区户数
		LambdaQueryWrapper<Room> roomLambdaQueryWrapper = new QueryWrapperUtil<Room>().getBasicQueryWrapper(Room::getOrgPosition,new Room(),bladeUser,orgPositionClient);
		roomLambdaQueryWrapper.eq(Room::getAgencyId,agencyById.getId());
		Integer roomCount = this.roomService.count(roomLambdaQueryWrapper);
		agencyStatistics.setRoomCount(roomCount);

		//园区人口
		HouseUser searchHU = new HouseUser();
		searchHU.setAgencyId(agencyById.getId());
		Integer personCount = this.houseUserClient.list(searchHU).size();
		agencyStatistics.setPersonCount(personCount);

		//业主人员
		HouseUser searchOwner = new HouseUser();
		searchOwner.setType(1);
		searchOwner.setAgencyId(agencyById.getId());
		Integer ownerCount = this.houseUserClient.list(searchOwner).size();
		agencyStatistics.setOwnerCount(ownerCount);

		//租客人员
		HouseUser searchTenant = new HouseUser();
		searchTenant.setType(3);
		searchTenant.setAgencyId(agencyById.getId());
		Integer tenantCount = this.houseUserClient.list(searchTenant).size();
		agencyStatistics.setTenantCount(StringUtils.isEmpty(tenantCount + "") ? 0 : tenantCount);

		//重点人员
		Integer keyPersonCount = this.keyPeopleClient.list(new KeyPeople()).size();

//		设备状态1 正常 2 告警 3失联 4 停用(弃用) 5待布防

		//正常设备
		Map safeIotDevice = new HashMap<>();

		safeIotDevice.put("deviceStatus",DeviceConstant.DeviceStatus.NORMAL.getValue());
		safeIotDevice.put("orgPosition",agencyById.getOrgPosition());
		Integer safetyCount = this.iotDeviceClient.listMap(safeIotDevice).size();
		agencyStatistics.setSafetyDeviceCount(StringUtils.isEmpty(safetyCount + "") ? 0 : safetyCount);

		//警告设备
		Map warningIotDevice = new HashMap<>();

		warningIotDevice.put("deviceStatus",DeviceConstant.DeviceStatus.ALARM.getValue());
		warningIotDevice.put("orgPosition",agencyById.getOrgPosition());
		Integer warningDeviceCount = this.iotDeviceClient.listMap(warningIotDevice).size();
		agencyStatistics.setWarningDeviceCount(warningDeviceCount);

		//失联设备
		Map missingIotDevice = new HashMap<>();

		missingIotDevice.put("deviceStatus",DeviceConstant.DeviceStatus.MISSING.getValue());
		missingIotDevice.put("orgPosition",agencyById.getOrgPosition());
		Integer missingDeviceCount = this.iotDeviceClient.listMap(missingIotDevice).size();
		agencyStatistics.setWarningDeviceCount(missingDeviceCount);

		//停用设备
		Map stopIotDevice = new HashMap<>();

		stopIotDevice.put("deviceStatus",DeviceConstant.DeviceStatus.ABANDON.getValue());
		stopIotDevice.put("orgPosition",agencyById.getOrgPosition());
		Integer stopUseDeviceCount = this.iotDeviceClient.listMap(stopIotDevice).size();
		agencyStatistics.setWarningDeviceCount(stopUseDeviceCount);

		//待布防设备
		Map tobeDefendIotDevice = new HashMap<>();

		tobeDefendIotDevice.put("deviceStatus",DeviceConstant.DeviceStatus.DAIBUFANG.getValue());
		tobeDefendIotDevice.put("orgPosition",agencyById.getOrgPosition());
		Integer tobeDefendDeviceCount = this.iotDeviceClient.listMap(tobeDefendIotDevice).size();
		agencyStatistics.setWarningDeviceCount(tobeDefendDeviceCount);

		//企业数
		Integer enterpriseCount = this.enterpriseClient.list(new Enterprise()).size();
		agencyStatistics.setEnterpriseCount(StringUtils.isEmpty(enterpriseCount + "") ? 0 : enterpriseCount);

		//企业列表
		List<EnterpriseVO> enterpriseList = this.enterpriseClient.list(new Enterprise());
		agencyStatistics.setEnterpriseList(enterpriseList);

		//员工数
//		Integer staffCount = this.enterpriseStaffClient.list(new EnterpriseStaff()).size();
//		agencyStatistics.setStaffCount(staffCount);

		return agencyStatistics;
	}

	/**
	 * 园区态势页面统计
	 */
	@GetMapping("/residential/index")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "小区态势统计")
	@Transactional
	@ApiIgnore
	public ResidentialStatistics residential(Residential residential){
		ResidentialStatistics residentialStatistics = new ResidentialStatistics();
		Residential residential1 = residentialService.getById(residential.getId());
		String tenantId =null;
		if(residential1 != null){
			tenantId =residential1.getTenantId();
		}

		if(null != tenantId){
			TenantType searchTenantType = new TenantType();
			searchTenantType.setTenantId(tenantId);
			TenantType tenantType = tenantTypeClient.detail(searchTenantType);
			if(null != tenantType){
				if(tenantType.getTenantType() == 1){
					Enterprise searchEnterprise = new Enterprise();
					searchEnterprise.setResidentialId(residential.getId());
					Integer enterpriseCount = this.enterpriseClient.list(searchEnterprise).size();
					residentialStatistics.setEnterpriseCount(enterpriseCount);
					Staff search = new Staff();
					search.setResidentialId(residential.getId());
//					Integer enterpriseStaffCount = this.enterpriseStaffClient.list(search).size();
//					residentialStatistics.setEnterpriseStaffCount(enterpriseStaffCount);
					Map map = new HashMap();
					map.put("residentialId",residential.getId());
					Integer devicesCount = iotDeviceClient.listMap(map).size();
					residentialStatistics.setDevicesCount(devicesCount);
					Car searchCar = new Car();
					searchCar.setResidentialId(residential.getId());
					Integer carCount = carClient.list(searchCar).size();
					residentialStatistics.setCarCount(carCount);
				}
			}
		}
		Residential residentialById = this.residentialService.getById(residential.getId());
		Assert.notNull(residentialById,"该小区不存在");

		//小区户数
		Integer roomCount = this.roomService.count(Condition.getQueryWrapper(
			new Room()).lambda().eq(Room::getResidentialId,residentialById.getId()));
		residentialStatistics.setRoomCount(roomCount);
		//楼宇总数
		Integer buildingCount = this.buildingService.count(Condition.getQueryWrapper(
			new Building()).lambda().eq(Building::getResidentialId,residentialById.getId()));
		residentialStatistics.setBuildingCount(buildingCount);
		//小区人口
		HouseUser searchHU = new HouseUser();
		searchHU.setResidentialId(residentialById.getId());
		Integer personCount = this.houseUserClient.list(searchHU).size();
		residentialStatistics.setPersonCount(personCount);
		//小区车位
		ParkingSpace searchPs = new ParkingSpace();
		searchPs.setResidentialId(residentialById.getId());
		Integer parkingSpaceCount = this.parkingSpaceClient.list(searchPs).size();
		residentialStatistics.setParkingLotCount(parkingSpaceCount);
		//业主人员
		HouseUser owner = new HouseUser();
		owner.setResidentialId(residentialById.getId());
		owner.setType(1);
		Integer ownerCount = this.houseUserClient.list(owner).size();
		residentialStatistics.setOwnerCount(ownerCount);
		//租客人员
		HouseUser tenant = new HouseUser();
		tenant.setResidentialId(residentialById.getId());
		tenant.setType(3);
		Integer tenantCount = this.houseUserClient.list(tenant).size();
		residentialStatistics.setTenantCount(tenantCount);
		return residentialStatistics;
	}

	/**
	 * 园区态势人员管理
	 */
	@GetMapping("/residential/person")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "园区态势人员管理")
	@Transactional
	@ApiIgnore
	public ResidentialStatistics personsByResidential(Residential residential){

		return null;
	}

	/**
	 * 园区态势车辆管理
	 */
	@GetMapping("/residential/car")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "园区态势车辆管理")
	@Transactional
	@ApiIgnore
	public CarStatistics carByResidential(Residential residential){
		Residential residentialById = this.residentialService.getById(residential.getId());
		Assert.notNull(residentialById,"该小区不存在");
		CarStatistics carStatistics = new CarStatistics();
		//车位总数
		ParkingLot searchPL = new ParkingLot();
		searchPL.setResidentialId(residentialById.getId());
		Integer parkingLotCount = this.parkingLotClient.list(searchPL).size();
		carStatistics.setParkingLotCount(parkingLotCount);
		//已使用车位
		Integer userParkingCount = 0;
//			this.parkingLotService.count(Condition.getQueryWrapper(
//			new ParkingLot()).lambda().eq(ParkingLot::getResidentialId,residentialById.getId()).isNotNull(ParkingLot::getSpaceTotal));
		//空闲车位
		Integer freeParkingCount = 0;
//			this.parkingLotService.count(Condition.getQueryWrapper(
//			new ParkingLot()).lambda().eq(ParkingLot::getResidentialId,residentialById.getId()).isNull(ParkingLot::getSpaceTotal));
		return carStatistics;
	}

	/**
	 * 园区态势房屋管理
	 */
	@GetMapping("/residential/room")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "园区态势房屋管理")
	@Transactional
	@ApiIgnore
	public CarStatistics roomByResidential(Residential residential){

		return null;
	}

	/**
	 * 园区态势设备管理
	 */
	@GetMapping("/residential/device")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "园区态势设备管理")
	@Transactional
	@ApiIgnore
	public DeviceStatistics deviceByResidential(Residential residential, Long deviceType){
		Residential residentialById = this.residentialService.getById(residential.getId());
		Assert.notNull(residentialById,"该小区不存在");
		DeviceStatistics deviceStatistics = new DeviceStatistics();

		List<DictBiz> deviceTypes = this.dictBizClient.getList("device_type").getData();

//		List<ResidentialDeviceType> residentialDeviceTypes = this.residentialDeviceTypeService.getBaseMapper().selectList(new QueryWrapper<>(new ResidentialDeviceType()).lambda().eq(ResidentialDeviceType::getResidentialId, residentialById.getId()));
		deviceTypes.forEach(dictBiz -> {
			//获取设备类型的图标
			LambdaQueryWrapper<IotDevice> IotDeviceLambdaQueryWrapper = Condition.getQueryWrapper(new IotDevice()).lambda();
			SingleDeviceStatistics singleDeviceStatistics = new SingleDeviceStatistics();
			//设备类型名称
			singleDeviceStatistics.setDeviceTypeName(dictBiz.getDictValue());
			//设备类型
			singleDeviceStatistics.setDeviceType(dictBiz.getDictKey());

			Map iotDeviceMap = new HashMap();
			//过滤经纬度为空的数据
			iotDeviceMap.put("latitudeLongitude",".%,%.");
			//过滤小区的id
			iotDeviceMap.put("residentialId",residentialById.getId());
			//过滤设备类型
			iotDeviceMap.put("deviceType",dictBiz.getDictValue());
			//设备正常数
			iotDeviceMap.put("deviceStatus",DeviceConstant.DeviceStatus.NORMAL.getValue());
			Integer normalCount = this.iotDeviceClient.listMap(iotDeviceMap).size();
			singleDeviceStatistics.setNormalCount(normalCount);
			//设备异常数
			iotDeviceMap.put("deviceStatus",DeviceConstant.DeviceStatus.ALARM.getValue());
			Integer alertCount = this.iotDeviceClient.listMap(iotDeviceMap).size();
			singleDeviceStatistics.setAlertCount(alertCount);
			//存入返回对象
			deviceStatistics.getSingleDeviceStatisticsList().add(singleDeviceStatistics);
		});
		this.getIotDeviceList(deviceStatistics,residentialById.getId(),deviceType);
		//在线设备
		Map isOnlineMap = new HashMap();
		isOnlineMap.put("residentialId",residentialById.getId());
		isOnlineMap.put("latitudeLongitude",".%,%.");
		isOnlineMap.put("defenseStatus",1);
		Integer onlineCount = this.iotDeviceClient.listMap(isOnlineMap).size();
		deviceStatistics.setOnlineCount(onlineCount);
		//离线设备
		isOnlineMap.put("defenseStatus",2);
		Integer offlineCount = this.iotDeviceClient.listMap(isOnlineMap).size();
		deviceStatistics.setOfflineCount(offlineCount);
		//告警设备
		isOnlineMap.remove("defenseStatus");
		isOnlineMap.put("deviceStatus",DeviceConstant.DeviceStatus.ALARM.getValue());
		Integer alertCount = this.iotDeviceClient.listMap(isOnlineMap).size();
		deviceStatistics.setAlertCount(alertCount);


		return deviceStatistics;
	}

	public void getIotDeviceList(DeviceStatistics deviceStatistics, Long residentialId, Long deviceType){

		Map iotDeviceMap = new HashMap();
		iotDeviceMap.put("residentialId",residentialId);
		if (deviceType == null){
			Integer IotDeviceCount = this.iotDeviceClient.listMap(iotDeviceMap).size();
			deviceStatistics.setSmartDeviceCount(IotDeviceCount);
			//过滤经纬度为空的数据
			iotDeviceMap.put("latitudeLongitude",".%,%.");
			List<IotDeviceVO> iotDeviceList = this.iotDeviceClient.listMap(iotDeviceMap);
			deviceStatistics.setSmartDeviceList(iotDeviceList);
		}else {
			iotDeviceMap.put("deviceType",deviceType);
			Integer IotDeviceCount = this.iotDeviceClient.listMap(iotDeviceMap).size();
			deviceStatistics.setSmartDeviceCount(IotDeviceCount);
			//过滤经纬度为空的数据
			iotDeviceMap.put("latitudeLongitude",".%,%.");
			List<IotDeviceVO> iotDeviceList = this.iotDeviceClient.listMap(iotDeviceMap);
			deviceStatistics.setSmartDeviceList(iotDeviceList);
		}
	};

	/**
	 * 大屏物业统计
	 */
	@GetMapping("/screen/estate/static")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "大屏物业统计")
	@Transactional
	public R<EstateStaticVO> getScreenEstateStatic(String codeOrgPosition, BladeUser bladeUser) throws Exception {

		//判断是否有缓存
		String redisKey ="screen:"+ bladeUser.getUserId()+":"+ RedisConstant.ESTATE_STATIC+":"+codeOrgPosition;
		String value = redisTemplate.opsForValue().get(redisKey);
		if(value != null){
			EstateStaticVO estateStaticVO1 = (EstateStaticVO) SerializableUtil.deserializeToObject(value);
			return R.data(estateStaticVO1);
		}

		EstateStaticVO estateStaticVO = new EstateStaticVO();

		//*************************物业统计**************************//
		//园区总数
		LambdaQueryWrapper<Agency> agencyLambdaQueryWrapper = new  QueryWrapperUtil<Agency>().getBasicQueryWrapper(Agency::getOrgPosition,new Agency(),bladeUser,orgPositionClient);
		agencyLambdaQueryWrapper.like(Agency::getOrgPosition,codeOrgPosition);
		List<Agency> agencies = agencyService.getBaseMapper().selectList(agencyLambdaQueryWrapper);
		int agencyCount =agencies.size();

		//小区列表
		LambdaQueryWrapper<Residential> residentialWrapper = new QueryWrapperUtil<Residential>().getBasicQueryWrapper(Residential::getOrgPosition, new Residential(), bladeUser, orgPositionClient);
		residentialWrapper.like(Residential::getOrgPosition,codeOrgPosition);
		List<Residential> residentialList = residentialService.getBaseMapper().selectList(residentialWrapper);
		//小区总数
		int residentialCount =residentialList.size();
		//楼栋总数
		int buildingCount = 0;
		//单元总数
		int unitCount =0;
		//楼层总数
		int floorCount =0;
		//房间总数
		int roomCount = 0;

		for(int i = 0;i<residentialList.size();i++){
			Residential residential1 = residentialList.get(i);
			buildingCount = buildingCount + residential1.getBuildingCount();
			unitCount = unitCount + residential1.getUnitCount();
			floorCount = floorCount + residential1.getFloorCount();
			roomCount = roomCount + residential1.getRoomCount();
		}

		//住户总数

		Map searchHuAndIotDevice = new HashMap();
		searchHuAndIotDevice.put("orgPosition",codeOrgPosition);
		int userCount = this.houseUserClient.listMap(searchHuAndIotDevice).size();

		//智能设备总数

		LambdaQueryWrapper<IotDevice> IotDeviceLambdaQueryWrapper = new QueryWrapperUtil<IotDevice>().getBasicQueryWrapper(IotDevice::getOrgPosition,new IotDevice(),bladeUser,orgPositionClient);
		IotDeviceLambdaQueryWrapper.like(IotDevice::getOrgPosition,codeOrgPosition);
		int deviceCount = this.iotDeviceClient.listMap(searchHuAndIotDevice).size();



		estateStaticVO.setAgencyCount(agencyCount);
		estateStaticVO.setResidentialCount(residentialCount);
		estateStaticVO.setBuildingCount(buildingCount);
		estateStaticVO.setUnitCount(unitCount);
		estateStaticVO.setFloorCount(floorCount);
		estateStaticVO.setRoomCount(roomCount);
		estateStaticVO.setUserCount(userCount);
		estateStaticVO.setDeviceCount(deviceCount);
		estateStaticVO.setAgencyList(agencies);

		try {
			redisTemplate.opsForValue().set(redisKey,SerializableUtil.serializeToString(estateStaticVO));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return R.data(estateStaticVO);
	}


	/**
	 * 大屏智能设备分类统计
	 */
	@GetMapping("/screen/smartDevice/static")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "大屏智能设备分类统计")
	@Transactional
	public R<SmartDeviceStaticVO> IotDeviceStaticVOR(@RequestParam(value = "deviceType",required = false) String deviceType, @RequestParam("codeOrgPosition") String codeOrgPosition, BladeUser bladeUser) throws Exception {

		String redisKey = "screen:"+bladeUser.getUserId()+":"+RedisConstant.SMARTDEVICE_STATIC+":"+codeOrgPosition+":"+deviceType;
		String value = redisTemplate.opsForValue().get(redisKey);
		if(value != null){
			SmartDeviceStaticVO IotDeviceStaticVO1 =(SmartDeviceStaticVO) SerializableUtil.deserializeToObject(value);
			return R.data(IotDeviceStaticVO1);
		}


		SmartDeviceStaticVO IotDeviceStaticVO = new SmartDeviceStaticVO();
		if(deviceType == null ){
			List<IotDevice> IotDevices = new ArrayList<>();
			List<DictBiz> deviceTypeList = this.dictBizClient.getList("device_type").getData();

			for (int i=0;i<deviceTypeList.size();i++){
				DictBiz dictBiz = deviceTypeList.get(i);
				SingleTypeSmartDeviceVO singleTypeIotDeviceVO = new SingleTypeSmartDeviceVO();
				singleTypeIotDeviceVO.setDeviceType(dictBiz.getDictKey());
				singleTypeIotDeviceVO.setDeviceTypeName(dictBiz.getDictValue());

				Map iotDevice = new HashMap();
				iotDevice.put("orgPosition",codeOrgPosition);
				iotDevice.put("deviceType",dictBiz.getDictKey());
				iotDevice.put("latitudeLongitude",".%,%.");

				List<IotDevice> IotDevices1 = iotDeviceClient.listMap(iotDevice);
				int count = IotDevices1.size();
				singleTypeIotDeviceVO.setDeviceCount(count);
				IotDeviceStaticVO.getSingleTypeSmartDeviceVOList().add(singleTypeIotDeviceVO);
				IotDevices.addAll(IotDevices1);

			}
			IotDeviceStaticVO.setSmartDeviceList(IotDevices);
		}else {
			List<DictBiz> deviceTypeList = this.dictBizClient.getList("device_type").getData();

			for (int i = 0; i < deviceTypeList.size(); i++) {
				DictBiz dictBiz = deviceTypeList.get(i);

				SingleTypeSmartDeviceVO singleTypeIotDeviceVO = new SingleTypeSmartDeviceVO();
				singleTypeIotDeviceVO.setDeviceType(dictBiz.getDictKey());
				singleTypeIotDeviceVO.setDeviceTypeName(dictBiz.getDictValue());

				Map iotDevice = new HashMap();
				iotDevice.put("orgPosition",codeOrgPosition);
				iotDevice.put("deviceType",dictBiz.getDictKey());
				iotDevice.put("latitudeLongitude",".%,%.");

				int count = 0;
				if (dictBiz.getDictKey().equals(deviceType)) {
					List<IotDevice> IotDeviceList = this.iotDeviceClient.listMap(iotDevice);
					IotDeviceStaticVO.setSmartDeviceList(IotDeviceList);
					count = IotDeviceList.size();
				} else {
					count = this.iotDeviceClient.listMap(iotDevice).size();
				}

				singleTypeIotDeviceVO.setDeviceCount(count);
				if(count!=0){
					IotDeviceStaticVO.getSingleTypeSmartDeviceVOList().add(singleTypeIotDeviceVO);
				}

			}
		}

		redisTemplate.opsForValue().set(redisKey,SerializableUtil.serializeToString(IotDeviceStaticVO));
		return R.data(IotDeviceStaticVO);
	}

	/**
	 * 大屏地磁、视频云设备、人脸设备统计
	 */
	@GetMapping("/screen/MultiStatic/static")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "大屏地磁、视频云设备、人脸设备统计")
	@Transactional
	public R<MultiStaticVO> multiStaticVOR(String codeOrgPosition, BladeUser bladeUser) throws Exception {

		String redisKey = "screen:"+bladeUser.getUserId()+":"+RedisConstant.MULTISTATIC+":"+codeOrgPosition;
		String value = redisTemplate.opsForValue().get(redisKey);
		if(value != null){
			MultiStaticVO multiStaticVO1 = (MultiStaticVO)SerializableUtil.deserializeToObject(value);
			return R.data(multiStaticVO1);
		}


		MultiStaticVO multiStaticVO = new MultiStaticVO();

		//********************视频云设备统计**************************//

		//***************************人脸设备****************************//

		//小区总数
		LambdaQueryWrapper<Residential> residentialWrapper = new QueryWrapperUtil<Residential>().getBasicQueryWrapper(Residential::getOrgPosition, new Residential(), bladeUser, orgPositionClient);
		residentialWrapper.like(Residential::getOrgPosition,codeOrgPosition);
		int residentialCount =residentialService.count(residentialWrapper);
		//住户总数
		Map huMap = new HashMap();
		huMap.put("orgPosition",codeOrgPosition);

		int userCount = houseUserClient.listMap(huMap).size();


		Map doorDevice = new HashMap();
		doorDevice.put("orgPosition",codeOrgPosition);
		doorDeviceClient.listMap(doorDevice);
		//人脸总数
		int faceCount = userCount;
		//人脸设备总数
		List<DoorDevice> doorDeviceList = this.doorDeviceClient.listMap(doorDevice);
		int faceDeviceCount = doorDeviceList.size();
		List<Long> hasInstallResidentialId= doorDeviceList.stream().map(DoorDevice::getResidentialId).distinct().collect(Collectors.toList());
		//已安装人脸设备小区数
		int hasInstallResidentialCount = hasInstallResidentialId.size();
		//未安装人脸设备小区数
		int unInstallResidentialCount = residentialCount - hasInstallResidentialCount;

		//赋值
		FaceDeviceStaticVO faceDeviceStaticVO = new FaceDeviceStaticVO();
		faceDeviceStaticVO.setFaceCount(faceCount);
		faceDeviceStaticVO.setFaceDeviceCount(faceDeviceCount);
		faceDeviceStaticVO.setHasInstallResidentialCount(hasInstallResidentialCount);
		faceDeviceStaticVO.setUnInstallResidentialCount(unInstallResidentialCount);

		multiStaticVO.setFaceDeviceStaticVO(faceDeviceStaticVO);

		//**********************地磁统计***********************//

		//地磁总数100007

		IotDevice iotDevice = new IotDevice();
		iotDevice.setDeviceType("100007");
		int parkingDeviceCount  = this.iotDeviceClient.list(iotDevice).size();

		//停车抓拍数
		//进车抓拍
		int carRecordCount = 0;



		//车辆总数
		int carCount = 0;


		//车位数
		int parkingCount = 0;

		//停车场数
		int parkingLotCount =0;


		ParkingStaticVO parkingStaticVO = new ParkingStaticVO();

		parkingStaticVO.setParkingDeviceCount(parkingDeviceCount);
		parkingStaticVO.setCarCount(carCount);
		parkingStaticVO.setCarRecordCount(carRecordCount);
		parkingStaticVO.setParkingCount(parkingCount);
		parkingStaticVO.setParkingLotCount(parkingLotCount);

		multiStaticVO.setParkingStaticVO(parkingStaticVO);


		//*************告警**********************//
		int totalAlarmCount = 42;
		int deviceAlarmCount = 16 ;

		int reportAlarmCount = 14;

		int peopleAlarmCount = 12;

		AlarmOrderVO alarmOrderVO = new AlarmOrderVO();
		alarmOrderVO.setDeviceAlarmCount(deviceAlarmCount);
		alarmOrderVO.setPeopleAlarmCount(peopleAlarmCount);
		alarmOrderVO.setReportAlarmCount(reportAlarmCount);
		alarmOrderVO.setTotalAlarmCount(totalAlarmCount);

		multiStaticVO.setAlarmOrderVO(alarmOrderVO);

//		redisTemplate.opsForValue().set(redisKey,SerializableUtil.serializeToString(multiStaticVO));

		redisTemplate.opsForValue().set(redisKey,SerializableUtil.serializeToString(multiStaticVO));
		return R.data(multiStaticVO);
	}

	/**
	 * 	园区当日动态数据
	 * */
	@GetMapping("/screen/park/todayData")
	@ApiOperation("园区当日动态数据")
	public R<ParkTodayDataVO> todayData(@RequestParam("tenantId") String tenantId,
										@RequestParam(value = "agencyId",required = false) String agencyId,
										@RequestParam(value = "enterpriseId",required = false) String enterpriseId,
										@RequestParam(value = "residentialId",required = false) String residentialId){
		AccessRecordVO accessRecord = new AccessRecordVO();
		accessRecord.setAgencyId(agencyId != null ? Long.valueOf(agencyId) :null);

		accessRecord.setResidentialId(residentialId != null ?Long.valueOf(residentialId): null);
		accessRecord.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		//内部车出场记录
		CarOutRecordVO carOutRecordInside = new CarOutRecordVO();
		carOutRecordInside.setAgencyId(agencyId != null ? Long.valueOf(agencyId) : null);
		carOutRecordInside.setResidentialId(residentialId != null ? Long.valueOf(residentialId) : null);
		carOutRecordInside.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		carOutRecordInside.setOutSide(false);
		//内部车入场记录
		CarEnterRecordVO carEnterRecordInside = new CarEnterRecordVO();
		carEnterRecordInside.setAgencyId(agencyId != null ? Long.valueOf(agencyId) : null);
		carEnterRecordInside.setResidentialId(residentialId != null ? Long.valueOf(residentialId) : null);
		carEnterRecordInside.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		carEnterRecordInside.setOutSide(false);
		//外部车出场记录
		CarOutRecordVO carOutRecordOutside = new CarOutRecordVO();
		carOutRecordOutside.setAgencyId(agencyId != null ? Long.valueOf(agencyId) : null);
		carOutRecordOutside.setResidentialId(residentialId != null ? Long.valueOf(residentialId) : null);
		carOutRecordOutside.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		carOutRecordOutside.setOutSide(true);
		//外部车入场记录
		CarEnterRecordVO carEnterRecordOutSide = new CarEnterRecordVO();
		carEnterRecordOutSide.setAgencyId(agencyId != null ? Long.valueOf(agencyId) : null);
		carEnterRecordOutSide.setResidentialId(residentialId != null ? Long.valueOf(residentialId) : null);
		carEnterRecordOutSide.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		carEnterRecordOutSide.setOutSide(true);
		ParkTodayDataVO result = new ParkTodayDataVO.ParkTodayDataVOBuilder()
			.withPeopleNum(accessRecordClient.count(accessRecord))
			.withDepartCarOfInside(carOutRecordClient.count(carOutRecordInside))
			.withDepartCarOfOutside(carOutRecordClient.count(carOutRecordOutside))
			.withEnterCarOfInside(carEnterRecordClient.count(carEnterRecordInside))
			.withEnterCarOfOutside(carEnterRecordClient.count(carEnterRecordOutSide))
			.build();
		return R.data(result);
	}

	/**
	 * 	园区当日体温统计
	 * */
	@GetMapping("/screen/park/todayTemperature")
	@ApiOperation("园区当日体温统计")
	public R<ParkTodayTemperatureVO> todayTemperature(){
		TemperatureRecordVO exceptionCount = new TemperatureRecordVO();
		exceptionCount.setIsException(1);
		TemperatureRecordVO outSideCount = new TemperatureRecordVO();
//		outSideCount.setOut(true);
		TemperatureRecordVO inSideCount = new TemperatureRecordVO();
//		inSideCount.setOut(false);
		return R.data(
			new ParkTodayTemperatureVO.ParkTodayTemperatureVOBuilder()
//				.withExceptionCount(temperatureRecordClient.countToday(exceptionCount)
				.withExceptionCount(100
				)
//				.withOutsideCount(temperatureRecordClient.countToday(outSideCount))
				.withOutsideCount(100)
//				.withInsideCount(temperatureRecordClient.countToday(inSideCount))
				.withInsideCount(100)
				.build()
		);
	}

	/**
	 * 	园区车辆出入趋势
	 * */
	@GetMapping("/screen/park/carTendency")
	@ApiOperation("园区车辆出入趋势")
	public R<CarTendencyVO> carTendency(@RequestParam("tenantId") String tenantId,
										@RequestParam(value = "agencyId",required = false) String agencyId,
										@RequestParam(value = "enterpriseId",required = false) String enterpriseId,
										@RequestParam(value = "residentialId",required = false) String residentialId){
		/*获取近5日日期列表*/
		Date today = new Date();
		List<String> dateList = new ArrayList<>();
		dateList.add(DateUtil.formatDate(today));
		dateList.add(DateUtil.formatDate(DateUtil.offsetDay(today,-1)));
		dateList.add(DateUtil.formatDate(DateUtil.offsetDay(today,-2)));
		dateList.add(DateUtil.formatDate(DateUtil.offsetDay(today,-3)));
		dateList.add(DateUtil.formatDate(DateUtil.offsetDay(today,-4)));

		/*获取近5日车辆出入记录*/
		//内部进场车辆
		List<Integer> enterCarOfInside = new ArrayList<>();
		//外部进场车辆
		List<Integer> enterCarOfOutside = new ArrayList<>();
		//内部出场车辆
		List<Integer> departCarOfInside = new ArrayList<>();
		//外部出场车辆
		List<Integer> departCarOfOutside = new ArrayList<>();
		//人员出入记录
		List<Integer> peopleNumList = new ArrayList<>();


		AccessRecordVO accessRecord = new AccessRecordVO();
		accessRecord.setAgencyId(agencyId != null ? Long.valueOf(agencyId) :null);

		accessRecord.setResidentialId(residentialId != null ?Long.valueOf(residentialId): null);
		accessRecord.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		//内部车出场记录
		CarOutRecordVO carOutRecordInside = new CarOutRecordVO();
		carOutRecordInside.setAgencyId(agencyId != null ? Long.valueOf(agencyId) : null);
		carOutRecordInside.setResidentialId(residentialId != null ? Long.valueOf(residentialId) : null);
		carOutRecordInside.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		carOutRecordInside.setOutSide(false);
		//内部车入场记录
		CarEnterRecordVO carEnterRecordInside = new CarEnterRecordVO();
		carEnterRecordInside.setAgencyId(agencyId != null ? Long.valueOf(agencyId) : null);
		carEnterRecordInside.setResidentialId(residentialId != null ? Long.valueOf(residentialId) : null);
		carEnterRecordInside.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		carEnterRecordInside.setOutSide(false);
		//外部车出场记录
		CarOutRecordVO carOutRecordOutside = new CarOutRecordVO();
		carOutRecordOutside.setAgencyId(agencyId != null ? Long.valueOf(agencyId) : null);
		carOutRecordOutside.setResidentialId(residentialId != null ? Long.valueOf(residentialId) : null);
		carOutRecordOutside.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		carOutRecordOutside.setOutSide(true);
		//外部车入场记录
		CarEnterRecordVO carEnterRecordOutSide = new CarEnterRecordVO();
		carEnterRecordOutSide.setAgencyId(agencyId != null ? Long.valueOf(agencyId) : null);
		carEnterRecordOutSide.setResidentialId(residentialId != null ? Long.valueOf(residentialId) : null);
		carEnterRecordOutSide.setEnterpriseId(enterpriseId != null ? Long.valueOf(enterpriseId) : null);
		carEnterRecordOutSide.setOutSide(true);
		/*并行流获取各日期数据*/
		dateList.stream().forEach(item -> {
			enterCarOfInside.add(carEnterRecordClient.count(carEnterRecordInside));
			enterCarOfOutside.add(carEnterRecordClient.count(carEnterRecordOutSide));
			departCarOfInside.add(carOutRecordClient.count(carOutRecordInside));
			departCarOfOutside.add(carOutRecordClient.count(carOutRecordOutside));
			accessRecord.setCreateTimeLike(item);
			peopleNumList.add( accessRecordClient.count(accessRecord));
		});

		return R.data(
			new CarTendencyVO.CarTendencyVOBuilder()
				.withDateList(dateList)
				.withDepartCarOfInside(departCarOfInside)
				.withDepartCarOfOutside(departCarOfOutside)
				.withEnterCarOfInside(enterCarOfInside)
				.withEnterCarOfOutside(enterCarOfOutside)
				.withPeopleNUm(peopleNumList)
				.build()
		);
	}


	/**
	 * 	园区/社区数据统计
	 * */
	@GetMapping("/dataStat")
	@ApiOperation("园区/社区数据统计")
	public R<DataStaticVO> dataStat(@RequestParam(value = "agencyType", required = false) Integer agencyType, BladeUser bladeUser){
		List<Agency> agencyList = agencyService.list(new LambdaQueryWrapper<Agency>().eq(Agency::getAgencyType, agencyType));
		int agencyCount = agencyList.size();
		List<Long> agencyIdList = agencyList.stream().map(Agency::getId).collect(Collectors.toList());
		int residentialCount = residentialService.count(new LambdaQueryWrapper<Residential>().in(agencyList.size() > 0, Residential::getAgencyId, agencyIdList));
		int buildingCount = buildingService.count(new LambdaQueryWrapper<Building>().in(Building::getAgencyId, agencyIdList));
		Integer enterpriseCount = enterpriseClient.count(bladeUser.getTenantId());
		Integer staffCount = staffClient.count(bladeUser.getTenantId());
		Integer serverUserCount = serverUserClient.count(bladeUser.getTenantId());
		HouseUser houseUser = new HouseUser();
		houseUser.setTenantId(bladeUser.getTenantId());
		Integer houseUserCount = houseUserClient.count(houseUser);
		return R.data(DataStaticVO.builder()
			.agencyList(agencyList)
			.agencyCount(agencyCount)
			.residentialCount(residentialCount)
			.buildingCount(buildingCount)
			.enterpriseCount(enterpriseCount)
			.staffCount(staffCount)
			.serverUserCount(serverUserCount)
			.houseUserCount(houseUserCount)
			.build());
	}

}
