/*
 *      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.enterprise.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springblade.common.constant.CommonConstant;
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.dto.DispatchTask;
import org.springblade.device.dto.UserInfoDto;
import org.springblade.device.entity.DoorDevice;
import org.springblade.device.feign.IDoorDeviceClient;
import org.springblade.device.vo.DoorDeviceVO;
import org.springblade.enterprise.entity.Staff;
import org.springblade.enterprise.service.IUserService;
import org.springblade.enterprise.vo.StaffVO;
import org.springblade.enterprise.mapper.StaffMapper;
import org.springblade.enterprise.service.IStaffService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.enterprise.wrapper.StaffWrapper;
import org.springblade.estate.entity.CarOutRecord;
import org.springblade.estate.feign.IUserAccessPermissionsClient;
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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *  服务实现类
 *
 * @author BladeX
 * @since 2021-03-30
 */
@Service
public class StaffServiceImpl extends BaseServiceImpl<StaffMapper, Staff> implements IStaffService, IUserService<Staff> {

	@Autowired
	private IDoorDeviceClient doorDeviceClient;
	@Autowired
	private IDoorDeviceButtClient doorDeviceButtClient;
	@Autowired
	private IUserAccessPermissionsClient userAccessPermissionsClient;



	@Override
	public IPage<StaffVO> selectStaffPage(IPage<StaffVO> page, StaffVO staff) {
		return page.setRecords(baseMapper.selectStaffPage(page, staff));
	}

	@Override
	public boolean review(Staff enterpriseStaff) {
		LambdaUpdateWrapper<Staff> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.set(Staff::getAuditStatus, enterpriseStaff.getAuditStatus());
		updateWrapper.eq(Staff::getIsDeleted, BladeConstant.DB_NOT_DELETED);
		int update = baseMapper.update(enterpriseStaff, updateWrapper);
		if(update > 0){
			return true;
		}else{
			return false;
		}
	}

	@Override
	public Integer getCountByEnterpriseId(Long enterpriseId) {
		LambdaQueryWrapper<Staff> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(Staff::getEnterpriseId, enterpriseId);
		Integer count = baseMapper.selectCount(queryWrapper);
		return count > 0? count : 0;
	}

	@Override
	public R pushAddUserFace(Long staffId) {
		Staff staff = StaffWrapper.build().entityVO(this.getById(staffId));
		if (staff != null) {
			List<DoorDeviceVO> deviceList = doorDeviceClient.getListByAgencyAndResidential(staff.getAgencyId(), staff.getResidentialId());
			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.ENTERPRISE_STAFF_FLAG.getValue() + staffId.toString());
				userDeviceDTO.setUserFaceUrl(staff.getFaceUrl());
				userDeviceDTO.setUserName(staff.getRealName());
				userDeviceDTO.setTargetType(1);
				userDeviceDTO.setAddOrUpdate(1);
				R result = doorDeviceButtClient.pushFaceToDevices(userDeviceDTO);
				return result;
			}else{
				return R.fail("请先添加设备");
			}
		}else{
			return R.fail("员工信息不存在");
		}
	}

	@Override
	public R pushUpdateUserFace(Long staffId) {
		Staff staff = StaffWrapper.build().entityVO(this.getById(staffId));
		if (staff != null) {
			List<DoorDeviceVO> deviceList = doorDeviceClient.getListByAgencyAndResidential(staff.getAgencyId(), staff.getResidentialId());
			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.ENTERPRISE_STAFF_FLAG.getValue() + staffId.toString());
				userDeviceDTO.setUserFaceUrl(staff.getFaceUrl());
				userDeviceDTO.setUserName(staff.getRealName());
				userDeviceDTO.setTargetType(1);
				userDeviceDTO.setAddOrUpdate(2);
				R result = doorDeviceButtClient.pushFaceToDevices(userDeviceDTO);
				return result;
			}else{
				return R.fail("请先添加设备");
			}
		}else{
			return R.fail("员工信息不存在");
		}
	}

	@Override
	public R deleteUserFace(Long staffId) {
		Staff staff = this.getById(staffId);
		if (staff != null) {
			List<DoorDeviceVO> deviceList = doorDeviceClient.getListByAgencyAndResidential(staff.getAgencyId(), staff.getResidentialId());
			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.ENTERPRISE_STAFF_FLAG.getValue() + staffId.toString());
				R result = doorDeviceButtClient.deleteFaceToDevices(userDeviceDTO);
				return result;
			}else{
				return R.fail("请先添加设备");
			}
		}else{
			return R.fail("员工信息不存在");
		}
	}

	@Override
	public R deleteUser(Long staffId) {
		userAccessPermissionsClient.deleteFace(staffId.toString(), CommonConstant.UserFlag.ENTERPRISE_STAFF_FLAG.getValue());
		this.removeById(staffId);
		return R.status(true);
	}

	@Override
	public Integer staffStat() {
		BladeUser bladeUser = AuthUtil.getUser();
		QueryWrapper<Staff> queryWrapper = Condition.getQueryWrapper(new HashMap<>(), Staff.class);
		if(!bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID)){  //超管
			return this.count(queryWrapper.lambda().eq(Staff::getTenantId, bladeUser.getTenantId()));
		}else{
			return this.count(queryWrapper);
		}
	}

	@Override
	public R pushAddFace(Staff staff, Map<String, String> extendMap) {
		DispatchTask task = new DispatchTask();
		task.setXqId(staff.getResidentialId());
		UserInfoDto userInfoDto = new UserInfoDto();
		userInfoDto.setFaceUrl(staff.getFaceUrl());
		userInfoDto.setId(CommonConstant.UserFlag.ENTERPRISE_STAFF_FLAG.getValue() + staff.getId());
		userInfoDto.setIdCard(userInfoDto.getIdCard());
		task.setData(userInfoDto);
		R result = doorDeviceClient.pushUserFace(task, 1);
		if(result.isSuccess()){
			return R.success("人脸下发成功");
		}else{
			return R.fail("人脸下发失败");
		}
	}

	@Override
	public R pushDelFace(List<Staff> userInfoList, Map<String, String> extendMap) {
		for(Staff enterpriseStaff : userInfoList){
			if(StringUtil.isNotBlank(enterpriseStaff.getFaceUrl())){
				UserInfoDto dto = new UserInfoDto();
				dto.setId(CommonConstant.UserFlag.ENTERPRISE_STAFF_FLAG.getValue() + enterpriseStaff.getId());
				dto.setFaceCodeList(new ArrayList<>(0));
				DispatchTask task = new DispatchTask();
				task.setXqId(enterpriseStaff.getResidentialId());
				task.setData(dto);
				doorDeviceClient.pushUserFace(task, 2);
			}
		}
		return R.success("删除人脸成功");
	}
}
