/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.estate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.constant.DeviceConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.device.entity.DoorDevice;
import org.springblade.device.feign.IDoorDeviceClient;
import org.springblade.enterprise.entity.Staff;
import org.springblade.estate.entity.GuestRecord;
import org.springblade.estate.service.IUserAccessPermissionsService;
import org.springblade.estate.vo.GuestRecordVO;
import org.springblade.estate.mapper.GuestRecordMapper;
import org.springblade.estate.service.IGuestRecordService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.estate.wrapper.GuestRecordWrapper;
import org.springblade.third.doordevice.dto.UserDeviceDTO;
import org.springblade.third.doordevice.feign.IDoorDeviceButtClient;
import org.springblade.third.dto.DeviceDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.util.Assert;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 *  服务实现类
 *
 * @author BladeX
 * @since 2021-03-30
 */
@Service
@Slf4j
public class GuestRecordServiceImpl extends BaseServiceImpl<GuestRecordMapper, GuestRecord> implements IGuestRecordService {

	@Autowired
	private IDoorDeviceClient doorDeviceClient;
	@Autowired
	private IDoorDeviceButtClient doorDeviceButtClient;
	@Autowired
	private IUserAccessPermissionsService userAccessPermissionsService;

	@Override
	public IPage<GuestRecordVO> selectGuestPage(IPage<GuestRecordVO> page, GuestRecordVO guest) {
		return page.setRecords(baseMapper.selectGuestPage(page, guest));
	}

	@Override
	public R audit(Long guestId, Integer checkState, String opinion) {
		GuestRecord guestRecord = this.getById(guestId);
		Assert.notNull(guestRecord, "访客记录不存在，审核失败");
		guestRecord.setAuditStatus(checkState);
		guestRecord.setOpinion(opinion);
		boolean result = this.updateById(guestRecord);
		if (result && guestRecord.getAuditStatus() == 1 && StringUtil.isNotBlank(guestRecord.getFaceUrl())) {//若审核通过，下发访客信息到门禁设备，如果访客有人脸信息也下发到门禁设备
			return this.pushFace(guestId);
		}
		return R.status(true);
	}

	@Override
	public R pushFace(Long guestId) {
		GuestRecord guestRecord = GuestRecordWrapper.build().entityVO(this.getById(guestId));
		Assert.notNull(guestRecord, "访客记录不存在");
		Long agencyId = guestRecord.getAgencyId();
		List<DoorDevice> faceDeviceList = doorDeviceClient.getListByAgencyId(agencyId);
		if (faceDeviceList == null || faceDeviceList.size() <= 0) {
			log.error("园区访客信息下发到设备时找不到设备","访客信息" + guestRecord.toString());
			return R.status(true);
		}
		List<DeviceDTO> deviceDTOList = faceDeviceList.stream().map(item -> {
			DeviceDTO deviceDTO = new DeviceDTO();
			deviceDTO.setSerialNum(item.getSerialNum());
			deviceDTO.setFactory(item.getDeviceFactory());
			return deviceDTO;
		}).collect(Collectors.toList());
		UserDeviceDTO userDeviceDTO = new UserDeviceDTO();
		userDeviceDTO.setTargetType(2);
		userDeviceDTO.setUserName(guestRecord.getGuestName());
		userDeviceDTO.setDeviceList(deviceDTOList);
		userDeviceDTO.setUserFaceUrl(guestRecord.getFaceUrl());
		userDeviceDTO.setUserId(CommonConstant.UserFlag.GUEST_FLAG.getValue() + guestRecord.getId());
		userDeviceDTO.setAddOrUpdate(1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		userDeviceDTO.setStartTime(sdf.format(guestRecord.getBeginTime()));
		userDeviceDTO.setEndTime(sdf.format(guestRecord.getEndTime()));
		return doorDeviceButtClient.pushFaceToDevices(userDeviceDTO);
	}

	@Override
	public R deleteFace(Long guestId) {
		GuestRecord guestRecord = this.getById(guestId);
		if (guestRecord != null) {
			List<DoorDevice> deviceList = doorDeviceClient.getListByAgencyId(guestRecord.getAgencyId());
			if(deviceList != null && deviceList.size() > 0){
				List<DeviceDTO> deviceDTOList = deviceList.stream().map(item -> {
					DeviceDTO deviceDTO = new DeviceDTO();
					deviceDTO.setSerialNum(item.getSerialNum());
					deviceDTO.setFactory(item.getDeviceFactory());
					return deviceDTO;
				}).collect(Collectors.toList());
				UserDeviceDTO userDeviceDTO = new UserDeviceDTO();
				userDeviceDTO.setDeviceList(deviceDTOList);
				userDeviceDTO.setUserId(CommonConstant.UserFlag.GUEST_FLAG.getValue() + guestRecord.getId());
				R result = doorDeviceButtClient.deleteFaceToDevices(userDeviceDTO);
				return result;
			}else{
				return R.fail("请先添加设备");
			}
		}else{
			return R.fail("访客记录不存在");
		}
	}

	@Override
	public Integer guestStat(String beginDate, String endDate) {
		BladeUser bladeUser = AuthUtil.getUser();
		QueryWrapper<GuestRecord> queryWrapper = Condition.getQueryWrapper(new HashMap<>(), GuestRecord.class);
		if(!bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID)){  //超管
			queryWrapper.lambda().eq(GuestRecord::getTenantId, bladeUser.getTenantId());
		}else{

		}
		if(StringUtil.isNotBlank(beginDate) && StringUtil.isNotBlank(endDate)){
			queryWrapper.lambda().ge(GuestRecord::getBeginTime, beginDate);
			queryWrapper.lambda().le(GuestRecord::getEndTime, endDate);
		}else{
			queryWrapper.lambda().ge(GuestRecord::getBeginTime, new Date());
			queryWrapper.lambda().le(GuestRecord::getEndTime, new Date());
		}
		return this.count(queryWrapper);
	}

	@Override
	public R deleteGuestRecord(Long id) {
		userAccessPermissionsService.deleteFace(id.toString(), CommonConstant.UserFlag.GUEST_FLAG.getValue());
		this.removeById(id);
		return R.status(true);
	}

}
