package org.springblade.timedtask;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springblade.community.accessrecord.entity.AccessRecord;
import org.springblade.community.accessrecord.service.IAccessRecordService;
import org.springblade.community.agency.entity.Agency;
import org.springblade.community.agency.service.IAgencyService;
import org.springblade.community.houseuser.entity.Houseuser;
import org.springblade.community.houseuser.service.IHouseuserService;
import org.springblade.community.residential.entity.Residential;
import org.springblade.community.residential.service.IResidentialService;
import org.springblade.community.staff.entity.EnterpriseStaff;
import org.springblade.community.staff.service.IEnterpriseStaffService;
import org.springblade.core.log.logger.BladeLogger;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.estate.guest.entity.Guest;
import org.springblade.estate.guest.service.IGuestService;
import org.springblade.modules.system.service.IParamService;
import org.springblade.openinterface.facedevice.qinlin.beans.QinLinApiResultBean;
import org.springblade.openinterface.facedevice.qinlin.util.BASE64DecodedMultipartFile;
import org.springblade.openinterface.facedevice.qinlin.util.QinLinHttpUtil;
import org.springblade.openinterface.facedevice.qinlin.vo.QLinOpenRecord;
import org.springblade.openinterface.facedevice.qinlin.vo.QLinQuery;
import org.springblade.smartapplication.facedevice.entity.FaceDevice;
import org.springblade.smartapplication.facedevice.service.IFaceDeviceService;
import org.springblade.smartapplication.facedevice.vo.FaceDeviceVO;
import org.springblade.system.tenanttype.entity.TenantType;
import org.springblade.system.tenanttype.service.ITenantTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zwx
 * @create 2021/1/14 17:17
 */
@Slf4j
@Component
@EnableScheduling
@AllArgsConstructor
@Profile({"prod"})
@RestController
@RequestMapping("door/open")
public class FaceDeviceOpenRecordTask {

	private final static String REDIS_KEY = "blade.qinlin.openRecord.query.quartz";
	private final RedisTemplate redisTemplate;
	private final IFaceDeviceService faceDeviceService;
	private final IEnterpriseStaffService enterpriseStaffService;
	private final IHouseuserService houseuserService;
	private final IAgencyService agencyService;
	private final ITenantTypeService tenantTypeService;
	private final IResidentialService residentialService;
	private final IAccessRecordService accessRecordService;
	private final QinLinHttpUtil qinLinHttpUtil;
	private final IGuestService guestService;
	private final IParamService paramService;

	@Scheduled(cron = "0 */10 * * * ?")
	public void getQLOpenLogs() {
		int page = 0;
		Query query = new Query();
		query.setSize(50);

		Date endDate = new Date();
		Calendar cd = Calendar.getInstance();
		cd.setTime(endDate);
		cd.add(Calendar.MINUTE, -10);
		Date startDate = cd.getTime();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String startTime = sdf.format(startDate);
		String endTime = sdf.format(endDate);
		while (true) {
			try {
				page = page + 1;
				query.setCurrent(page);
				//  分页获取任务
				LambdaQueryWrapper<FaceDevice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
				lambdaQueryWrapper.orderByDesc(FaceDevice::getCreateTime);
				IPage<FaceDevice> devicePageR = faceDeviceService.page(Condition.getPage(query), lambdaQueryWrapper);
				List<FaceDevice> faceDeviceList = devicePageR.getRecords();
				if (faceDeviceList == null || faceDeviceList.size() == 0){
					//  结束循环
					log.info("====================开门纪录定时获取结束====================");
					break;
				}
				for(FaceDevice faceDevice : faceDeviceList){
					if(faceDevice.getDeviceFactory().equals("qinlin")){
						//  获取用户通行记录--通过设备ID
						QLinQuery qLinQuery = new QLinQuery();
						qLinQuery.setDeviceId(faceDevice.getMacAddress());
						qLinQuery.setStartTime(startTime);
						qLinQuery.setEndTime(endTime);
						QinLinApiResultBean<List<QLinOpenRecord>> qinLinApiResultBean = qinLinHttpUtil.getLogs(qLinQuery);
						log.info("=====================人员出入记录=====================");
						log.info(JsonUtil.toJson(qinLinApiResultBean));
						if(qinLinApiResultBean.getCode().equals(0)){
							List<QLinOpenRecord> list = qinLinApiResultBean.getData();
							for(QLinOpenRecord record : list){
								try{
									createOpenRecord(record);
								}catch (Exception e){
									e.printStackTrace();
									continue;
								}
							}
						}
					}
				}
			}catch (Exception e){
				e.printStackTrace();
				continue;
			}
		}
	}

	@GetMapping("/createOpenRecord")
	private void createOpenRecord(@RequestBody QLinOpenRecord qLinOpenRecord){
		if(qLinOpenRecord.getUserId().startsWith("QL")){
			return;
		}
		Long userId = Long.parseLong(qLinOpenRecord.getUserId());
		String mac = qLinOpenRecord.getDeviceId();
		FaceDevice faceDevice = this.faceDeviceService.selectByMacAddress(mac);
		Long agencyId = faceDevice.getAgencyId();
		Agency agency = this.agencyService.getById(agencyId);

		Long residentialId = faceDevice.getResidentialId();
		Residential residential = this.residentialService.getById(residentialId);
		String residentialName = residential.getName();
		TenantType tenantType = tenantTypeService.getByTenantId(agency.getTenantId());
		Integer type = tenantType.getTenantType();
		String agencyName = agency.getAgencyName();
//		Long residentialId = null;
//		String residentialName = null;
		Houseuser houseuser = null;
		EnterpriseStaff staff = null;
		Guest guest = null;
		String userName = null;
		Integer agencyType = null;
		AccessRecord accessRecord = new AccessRecord();
		if(type == 0){ //社区出入记录
			if(userId == null){
				return ;
			}else{
				houseuser = this.houseuserService.getByOldIdAndResidentialId(userId.toString().substring(3), residentialId);
				if(houseuser == null){
					guest = this.guestService.getById(userId);
					if(guest == null){
						return;
					}else{
						userId = guest.getId();

					}
				}else{
					userId = houseuser.getId();
				}
				userId = houseuser.getId();
				agencyType = 0;
			}
		}else{ //园区出入记录
			staff = this.enterpriseStaffService.getById(Long.valueOf(userId));
			if(staff == null){
				guest = this.guestService.getById(Long.valueOf(userId));
				if(guest == null){
					return;
				}else{
					userId = guest.getId();
				}
			}
			agencyType = 1;
		}
		if(houseuser != null || staff != null || guest != null){
			if(houseuser != null){
//				residentialId = houseuser.getResidentialId();
				userName = houseuser.getName();
				accessRecord.setUserName(houseuser.getName());
				agencyType = 0;
			}else if(staff != null){
//				residentialId = staff.getResidentialId();
				userName = staff.getRealName();
				agencyType = 1;
				accessRecord.setEnterpriseId(staff.getEnterpriseId());
				accessRecord.setEnterpriseName(staff.getEnterpriseName());
			}else if(guest != null){
				if(agencyType == 1){
					accessRecord.setEnterpriseId(guest.getEnterpriseId());
					accessRecord.setEnterpriseName(guest.getEnterpriseName());
				}else{
					userName = guest.getGuestName();
					accessRecord.setUserName(guest.getGuestName());
				}
			}
//			Residential residential = this.residentialService.getById(residentialId);
//			residentialName = residential.getName();
			accessRecord.setAgencyId(agencyId);
			accessRecord.setAgencyName(agencyName);
			accessRecord.setResidentialId(residentialId);
			accessRecord.setResidentialName(residentialName);
			accessRecord.setAgencyType(agencyType);
			accessRecord.setUserId(userId);
			accessRecord.setUserName(userName);
			accessRecord.setDeviceId(faceDevice.getId());
			accessRecord.setDeviceMac(faceDevice.getMacAddress());
			accessRecord.setDeviceAddress(faceDevice.getAddress());
			accessRecord.setOpenTime(qLinOpenRecord.getOpenTime());
			accessRecord.setOpenType(qLinOpenRecord.getOpenType());
			accessRecord.setTemperature(qLinOpenRecord.getTemperature());
			accessRecord.setFaceUrl(qLinOpenRecord.getRealFaceUrl());
			accessRecord.setOrgPosition(residential.getOrgPosition());
			accessRecord.setTenantId(residential.getTenantId());
			this.accessRecordService.save(accessRecord);
			log.info("=============人员出入记录写入成功====================");
		}else{
			log.error("openDoorRecord", "【houseUser和staff都不存在】-->" + JsonUtil.toJson(qLinOpenRecord));
		}
	}

	@RequestMapping(value = "/sync")
	public void doorOpen(@RequestBody List<QLinOpenRecord> list){
		String mac = "FE32EC000553,FE32EC001127,FE32EC001085,FE32EC000303,FE32EC001177,FE32EC000801";
		List<QLinOpenRecord> qLinOpenRecordList = new ArrayList<>();
		for (int i = 0; i < list.size(); i++){
			QLinOpenRecord data = list.get(i);
			String userId = data.getUserId();
			if(mac.contains(data.getDeviceId()) && userId.startsWith("102")){
				String openType = data.getOpenType();
				if(openType.equals("1")){
					//获取人脸图片
					QinLinApiResultBean<String> faceResult = this.qinLinHttpUtil.getLogsFaceUrl(data.getFaceUrl());
					String realFaceUrl = faceResult.getData();
					if(StringUtils.isNotBlank(realFaceUrl)){
						URL faceUrl = URLUtil.toUrlForHttp(realFaceUrl);
						try{
							InputStream stream = (InputStream) URLUtil.getStream(faceUrl);
							byte[] bytes = IoUtil.readBytes(stream);
							String base64 = "data:image/png;base64," + Base64.getEncoder().encodeToString(bytes);
							//图片上传
							MultipartFile multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(base64);
							R<String> stringR = this.qinLinHttpUtil.putFile(multipartFile);
							data.setRealFaceUrl(stringR.getData());
						}catch (Exception e){
							data.setRealFaceUrl(realFaceUrl);
							e.printStackTrace();
						}
					}
				}
				qLinOpenRecordList.add(data);
			}
		}
		qLinOpenRecordList.forEach(record ->{
			createOpenRecord(record);
		});
	}

	@GetMapping("/getQLOpenLogsTest")
	public R<List<QLinOpenRecord>> getQLOpenLogsTest() {
		Integer openRecordTime = Integer.parseInt(paramService.getValue("openRecordTime"));
		int page = 0;
		Query query = new Query();
		query.setSize(100);

		Date endDate = new Date();
		Calendar cd = Calendar.getInstance();
		cd.setTime(endDate);
		cd.add(Calendar.MINUTE, -openRecordTime);
		Date startDate = cd.getTime();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String startTime = sdf.format(startDate);
		String endTime = sdf.format(endDate);
		while (true) {
			try {
				page = page + 1;
				query.setCurrent(page);
				//  分页获取任务
				LambdaQueryWrapper<FaceDevice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
				lambdaQueryWrapper.orderByDesc(FaceDevice::getCreateTime);
				IPage<FaceDevice> devicePageR = faceDeviceService.page(Condition.getPage(query), lambdaQueryWrapper);
				List<FaceDevice> faceDeviceList = devicePageR.getRecords();
//				String macList = faceDeviceList.stream().map(FaceDevice::getMacAddress).collect(Collectors.joining(","));
//				bladeLogger.debug("查询设备开门记录", macList);
				if (faceDeviceList == null || faceDeviceList.size() == 0){
					//  结束循环
					log.info("====================开门纪录定时获取开始====================");
					log.info("====================找不到设备====================");
					break;
				}
				String deviceIds = faceDeviceList.stream().map(FaceDevice::getMacAddress).collect(Collectors.joining(","));
				for(FaceDevice faceDevice : faceDeviceList){
					if(faceDevice.getDeviceFactory().equals("qinlin")){
						//  获取用户通行记录--通过设备ID
						QLinQuery qLinQuery = new QLinQuery();
						qLinQuery.setDeviceId(faceDevice.getMacAddress());
						qLinQuery.setStartTime(startTime);
						qLinQuery.setEndTime(endTime);
						QinLinApiResultBean<List<QLinOpenRecord>> qinLinApiResultBean = qinLinHttpUtil.getLogs(qLinQuery);
						log.info("=====================人员出入记录=====================");
						log.info(JsonUtil.toJson(qinLinApiResultBean));
						if(qinLinApiResultBean.getCode().equals(0)){
							List<QLinOpenRecord> list = qinLinApiResultBean.getData();
							log.info(JSON.toJSONString(list));
							list.forEach(record ->{
								createOpenRecord(record);
							});
						}
					}
				}
			}catch (Exception e){
				e.printStackTrace();
				break;
			}
		}
		return R.success("同步开门成功");
	}

}
