package com.sptg.estate.biz.service.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.constant.UserFlagConstant;
import com.sptg.common.core.entity.DispatchTask;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.device.api.constant.DeviceConstants;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.feigns.DeviceFeign;
import com.sptg.device.api.vo.AccessUserFacePushDevicesTask;
import com.sptg.device.api.vo.ManualPushDevicesTask;
import com.sptg.estate.api.dto.AccessCardDto;
import com.sptg.estate.api.dto.ServerUserDto;
import com.sptg.estate.api.dto.UserDto;
import com.sptg.estate.api.dto.UserInfoDto;
import com.sptg.estate.api.entity.*;
import com.sptg.estate.api.enums.EstateEnum;
import com.sptg.estate.api.vo.DevicesAccessPushVO;
import com.sptg.estate.biz.mapper.ServerUserMapper;
import com.sptg.estate.biz.service.*;
import com.sptg.permissions.api.feigns.ConfFeign;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * title: ServerUserServiceImpl
 * package: com.sptg.estate.biz.security.impl
 * description: 服务人员-服务层实现层
 */
@Service
@AllArgsConstructor
public class ServerUserServiceImpl extends ServiceImpl<ServerUserMapper, ServerUser> implements ServerUserServiceInterface {

    private final ServerUserFaceImageServiceInterface serverUserFaceImageServiceInterface;

    private final AccessCardServiceInterface accessCardServiceInterface;
    private final DeviceFeign deviceFeign;
    private final ConfFeign confFeign;
    private final ServerUserDetailServiceInterface serverUserDetailServiceInterface;
    private final AccessFacePushRecordsServiceInterface accessFacePushRecordsServiceInterface;
    private final AccessCardPushRecordsServiceInterface accessCardPushRecordsServiceInterface;

    @Override
    public Page<ServerUser> showServerUserList(ServerUserDto serverUserDto) {
        Page<ServerUser> page = serverUserDto.getPage();
        //条件
        EntityWrapper<ServerUser> wrapper = new EntityWrapper<ServerUser>();
        //名字
        String name = serverUserDto.getName();
        //电话
        String tel = serverUserDto.getTel();
        //身份证
        String idCard = serverUserDto.getIdCard();
        //人员类型
        Integer type = serverUserDto.getType();
        //是否启用
        Integer enable = serverUserDto.getIsEnable();
        //机构
        Long orgId = serverUserDto.getOrgId();
        //根机构
        Long rootOrgId = serverUserDto.getRootOrgId();
        //机构位置
        String orgPosition = serverUserDto.getOrgPosition();
        //物业位置
        String estPosition = serverUserDto.getEstatePosition();
        if (StringUtils.isNotBlank(name)) {
            wrapper.like("s_name", name);
        }

        if (StringUtils.isNotBlank(tel)) {
            wrapper.like("s_tel", tel);
        }
        if (serverUserDto.getResidentialId() != null) {
            wrapper.eq("l_residential_id", serverUserDto.getResidentialId());
        }
        if (StringUtils.isNotBlank(idCard)) {
            wrapper.like("s_id_card", idCard);
        }
        if (type != null) {
            wrapper.eq("i_type", type);
        }

        if (enable != null) {
            wrapper.eq("i_is_enable", enable);
        }
        //正常状态
        wrapper.eq("i_status", OperationConstant.ZERO);
        if (orgId != null) {
            wrapper.eq("l_org_id", orgId);
        }
        if (rootOrgId != null) {
            wrapper.eq("l_root_org_id", rootOrgId);
        }
        if (StringUtils.isNotBlank(orgPosition)) {
            wrapper.like("s_org_position", orgPosition, SqlLike.RIGHT);
        }
        if (StringUtils.isNotBlank(estPosition)) {
            wrapper.like("s_estate_position", estPosition, SqlLike.RIGHT);
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionProvince())) {
            wrapper.eq("s_region_province", serverUserDto.getRegionProvince());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionCity())) {
            wrapper.eq("s_region_city", serverUserDto.getRegionCity());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionArea())) {
            wrapper.eq("s_region_area", serverUserDto.getRegionArea());
        }
        //  排序字段
        if (serverUserDto.getSortField() != null && serverUserDto.getSortOrder() != null) {
            wrapper.orderBy(serverUserDto.getSortField(), serverUserDto.getSortOrder().equals("asc"));
        } else {
            //  排序字段 时间降序
            wrapper.orderBy("t_create_date", false);
        }
        page = this.selectPage(page, wrapper);
        return page;
    }

    @Override
    public ResultBean<Page<ServerUser>> pagingByServerUserIds(ServerUserDto serverUserDto) {
        Wrapper<ServerUser> wrapper = new EntityWrapper<>();
        if (serverUserDto.getIds() != null && serverUserDto.getIds().size() > 0) {
            wrapper.in("l_id", serverUserDto.getIds());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionProvince())) {
            wrapper.eq("s_region_province", serverUserDto.getRegionProvince());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionCity())) {
            wrapper.eq("s_region_city", serverUserDto.getRegionCity());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionArea())) {
            wrapper.eq("s_region_area", serverUserDto.getRegionArea());
        }
        if (null != serverUserDto.getResidentialId()) {
            wrapper.eq("l_residential_id", serverUserDto.getResidentialId());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getName())) {
            wrapper.like("s_name", serverUserDto.getName(), SqlLike.DEFAULT);
        }
        if (StringUtils.isNotEmpty(serverUserDto.getTel())) {
            wrapper.like("s_tel", serverUserDto.getTel(), SqlLike.RIGHT);
        }
        if (null != serverUserDto.getType()) {
            wrapper.eq("i_type", serverUserDto.getType());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getIdCard())) {
            wrapper.like("s_id_card", serverUserDto.getIdCard(), SqlLike.RIGHT);
        }
        if (null != serverUserDto.getIsEnable()) {
            wrapper.eq("i_is_enable", serverUserDto.getIsEnable());
        }
        wrapper.eq("i_status", OperationConstant.ZERO);
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectPage(serverUserDto.getPage(), wrapper));
    }

    @Override
    public ServerUser findServerUserById(long id) {
        if (id <= 0) {
            return null;
        }
        EntityWrapper<ServerUser> wrapper = new EntityWrapper<ServerUser>();
        //主键
        wrapper.eq("l_id", id);
        //删除状态：0正常
        wrapper.eq("i_status", OperationConstant.ZERO);
        ServerUser serverUser = this.selectOne(wrapper);
        return serverUser;
    }

    @Override
    public ResultBean<Boolean> deleteServerUser(long id) {
        ServerUser serverUser = this.selectById(id);
        Assert.notNull(serverUser, "服务人员不存在,请核实后重新操作");
        //删除
        serverUser.setStatus(OperationConstant.MINUS_ONE);
        boolean result = this.updateById(serverUser);
        if (result) {
            //是否关联单元
            List<ServerUserDetail> detailList = this.serverUserDetailServiceInterface.findServerUserDetailList(id);
            //删除下发人脸
            if (null != detailList && !detailList.isEmpty()) {
                for (ServerUserDetail serverUserDetail : detailList) {
                    this.pushServerUserFace(serverUser, new ArrayList<>(0), serverUserDetail.getUnitId());
                }
            } else {
                this.pushServerUserFace(serverUser, new ArrayList<>(0), null);
            }
            //删除卡号(已经包含删除下发卡号)
            this.accessCardServiceInterface.deleteAccessCardByUserIdAndType(serverUser.getId().toString(), OperationConstant.FOUR);
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteServerUserList(ServerUserDto serverUserDto) {
        List<String> ids = serverUserDto.getIds();
        for (String id : ids) {
            ServerUser serverUser = this.selectById(id);
            Assert.notNull(serverUser, "服务人员不存在,请核实后重新操作");
            //是否关联单元
            List<ServerUserDetail> detailList = this.serverUserDetailServiceInterface.findServerUserDetailList(serverUser.getId());
            //删除下发人脸
            if (null != detailList && !detailList.isEmpty()) {
                for (ServerUserDetail serverUserDetail : detailList) {
                    this.pushServerUserFace(serverUser, new ArrayList<>(0), serverUserDetail.getUnitId());
                }
            } else {
                this.pushServerUserFace(serverUser, new ArrayList<>(0), null);
            }
            //删除卡号(已经包含删除下发卡号)
            serverUser.setStatus(OperationConstant.MINUS_ONE);
            if (this.updateById(serverUser)) {
                this.accessCardServiceInterface.deleteAccessCardByUserIdAndType(id, OperationConstant.FOUR);
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean updateIsEnable(long id, int isEnable) {
        Integer count = this.baseMapper.updateIsEnable(id, isEnable);

        boolean enable = count != null && count > 0 ? true : false;
        if (enable) {
            ServerUser serverUser = this.selectById(id);
            //是否关联单元
            List<ServerUserDetail> detailList = this.serverUserDetailServiceInterface.findServerUserDetailList(id);
            //人脸
            List<Map<String, Object>> serverUserFaceMapList = serverUserFaceImageServiceInterface.selectFaceCodeByUserId(id);
            //卡号
            List<AccessCard> accessCardList = accessCardServiceInterface.getAccessCardByUserIdAndType(String.valueOf(id), OperationConstant.FOUR);
            if (isEnable == 0) {
                //启用服务人员
                if (serverUserFaceMapList != null && !serverUserFaceMapList.isEmpty()) {
                    if (null != detailList && !detailList.isEmpty()) {
                        for (ServerUserDetail serverUserDetail : detailList) {
                            this.pushServerUserFace(serverUser, serverUserFaceMapList, serverUserDetail.getUnitId());
                        }
                    } else {
                        this.pushServerUserFace(serverUser, serverUserFaceMapList, null);
                    }
                }
                //下发卡号
                if (null != accessCardList && !accessCardList.isEmpty()) {
                    for (AccessCard accessCard : accessCardList) {
                        this.accessCardServiceInterface.sendPushCard(accessCard);
                    }
                }
            } else if (isEnable == 1) {
                //禁用服务人员
                if (serverUserFaceMapList != null && !serverUserFaceMapList.isEmpty()) {
                    //删除下发人脸
                    if (null != detailList && !detailList.isEmpty()) {
                        for (ServerUserDetail serverUserDetail : detailList) {
                            this.pushServerUserFace(serverUser, new ArrayList<>(0), serverUserDetail.getUnitId());
                        }
                    } else {
                        this.pushServerUserFace(serverUser, new ArrayList<>(0), null);
                    }
                }
                //删除下发卡号
                if (null != accessCardList && !accessCardList.isEmpty()) {
                    for (AccessCard accessCard : accessCardList) {
                        this.accessCardServiceInterface.sendRemoveCard(accessCard);
                    }
                }
            }
        }
        return enable;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public ResultBean<Boolean> addOrEditOpenPermission(ServerUser dto) {
        Long serverUserId = dto.getId();
        ServerUser serverUser = this.selectById(serverUserId);
        if (null == serverUser) {
            return new ResultBean<>(ResultEnum.ERROR, false);
        }
        Integer isEnable = serverUser.getIsEnable();
        if (isEnable != null && isEnable == OperationConstant.ONE) {
            //禁用状态不能修改
            return new ResultBean<>(EstateEnum.IS_NOT_ENABLE, false);
        }

        Map<String,String> logMap = new HashMap<>();
        //小区
        if (!StringUtils.isEmpty(serverUser.getResidentialName())){
            logMap.put("xqName",serverUser.getResidentialName());
        }else {
            logMap.put("xqName",null);
        }
        //单元
        if (!StringUtils.isEmpty(serverUser.getUnitName())){
            logMap.put("unitName",serverUser.getUnitName());
        }else {
            logMap.put("unitName",null);
        }
        //房间
        if (!StringUtils.isEmpty(serverUser.getRoomName())){
            logMap.put("roomName",serverUser.getRoomName());
        }else {
            logMap.put("roomName",null);
        }
        //用户名
        if (!StringUtils.isEmpty(serverUser.getName())){
            logMap.put("userName",serverUser.getName());
        }else {
            logMap.put("userName",null);
        }

        boolean result;
        boolean isUpdateOrAddOrDelete = false;
        boolean isUpdate = false;
        boolean isDelete = false;
        ResultBean<Boolean> resultBean;
        List<Map<String, Object>> userFaceList = new ArrayList<>();
        List<ServerUserDetail> detailList = this.serverUserDetailServiceInterface.findServerUserDetailList(serverUserId);

        //下发人脸
        if (dto.getOpenPermissionType() == 1) {
            ServerUserFaceImage serverUserFaceImage = dto.getServerUserFaceImage();
            if (null != serverUserFaceImage.getId()) {
                //删除
                if (StringUtils.isBlank(serverUserFaceImage.getImageUri())) {
                    result = serverUserFaceImageServiceInterface.deleteById(serverUserFaceImage.getId());
                    if (result) {
                        isUpdateOrAddOrDelete = true;
                        isDelete = true;
                        userFaceList = new ArrayList<>(0);
                    }
                } else {
                    //修改
                    ServerUserFaceImage dbServerUserFaceImage = serverUserFaceImageServiceInterface.selectById(serverUserFaceImage.getId());
                    dbServerUserFaceImage.setImageUri(serverUserFaceImage.getImageUri());
                    dbServerUserFaceImage.setFaceCode(serverUserFaceImage.getFaceCode());
                    dbServerUserFaceImage.setBeginDate(serverUserFaceImage.getBeginDate());
                    dbServerUserFaceImage.setEndDate(serverUserFaceImage.getEndDate());
                    result = serverUserFaceImageServiceInterface.updateById(serverUserFaceImage);
                    if (result) {
                        isUpdateOrAddOrDelete = true;
                        isUpdate = true;
                        userFaceList = this.getUserFaceList(serverUserFaceImage);
                    }

                }
            } else {
                if (StringUtils.isBlank(serverUserFaceImage.getImageUri())) {
                    result = true;
                } else {
                    //新增
                    result = serverUserFaceImageServiceInterface.insert(serverUserFaceImage);
                    if (result) {
                        isUpdateOrAddOrDelete = true;
                        isUpdate = false;
                        userFaceList = this.getUserFaceList(serverUserFaceImage);
                        //修改服务人员人脸状态为待启用
                        serverUser.setFaceEnable(OperationConstant.ONE);
                        this.updateById(serverUser);
                    }
                }
            }
            //是否关联单元
            if (isUpdateOrAddOrDelete) {
                Integer deviceAccessType = dto.getDeviceAccessType();
                if (deviceAccessType != null && deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)) {
                    Integer operType = !isUpdate ? OperationConstant.ONE : OperationConstant.TWO;
                    if (isDelete) {
                        operType = OperationConstant.THREE;
                    }
                    if (null != detailList && !detailList.isEmpty()) {
                        for (ServerUserDetail serverUserDetail : detailList) {
                            this.pushServerUserFaceToUniversalDevices(serverUser, serverUserFaceImage, userFaceList, serverUserDetail.getUnitId(), operType, logMap);
                        }
                    } else {
                        this.pushServerUserFaceToUniversalDevices(serverUser, serverUserFaceImage, userFaceList, null, operType,logMap);
                    }
                } else {
                    if (null != detailList && !detailList.isEmpty()) {
                        for (ServerUserDetail serverUserDetail : detailList) {
                            this.pushServerUserFace(serverUser, userFaceList, serverUserDetail.getUnitId());
                        }
                    } else {
                        this.pushServerUserFace(serverUser, userFaceList, null);
                    }
                }
            }
            return new ResultBean<>(ResultEnum.SUCCESS, result);
        }

        //下发门禁卡
        if (dto.getOpenPermissionType() == 2) {
            AccessCard accessCard = dto.getAccessCard();

            if (null != accessCard) {
                resultBean = this.accessCardServiceInterface.addOrUpdateServerUserCard(this.copyAccessCardDto(accessCard, serverUser, detailList, dto.getDeviceAccessType()));
            } else {
                resultBean = new ResultBean<>(ResultEnum.ERROR, false);
            }
            return resultBean;
        }
        return null;
    }

    /**
     * 手动下发人脸、门禁到指定设备上
     *
     * @param devicesAccessPushVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public ResultBean<Boolean> accessDevicesManualPush(DevicesAccessPushVO devicesAccessPushVO) {
        ResultBean<Boolean> resultBean = null;
        Integer operType = devicesAccessPushVO.getOperType();
        Integer pushMaterial = devicesAccessPushVO.getPushMaterial();
        Long serverUserId = devicesAccessPushVO.getUserId();
        ServerUser serverUser = findServerUserById(serverUserId);
        if (null == serverUser) {
            return new ResultBean<>(ResultEnum.ERROR, false);
        } else {
            Integer isEnable = serverUser.getIsEnable();
            if (isEnable != null && isEnable == OperationConstant.ONE) {
                //禁用开关处于禁用状态下不能修改
                return new ResultBean<>(EstateEnum.IS_NOT_ENABLE, false);
            }
        }
        List<Long> deviceIdList = devicesAccessPushVO.getDeviceIdList();
        List<ServerUserDetail> serverUserDetailList = serverUserDetailServiceInterface.findServerUserDetailList(serverUserId);
        List<AccessCard> cards = accessCardServiceInterface.getAccessCardByUserIdAndType(String.valueOf(serverUserId), OperationConstant.FOUR);
        if (operType.equals(OperationConstant.ONE)) { //特殊授权下发
            switch (pushMaterial) {
                case 0: //人脸和门禁卡同时下发到设备
                    List<ServerUserFaceImage> faceList0 = serverUserFaceImageServiceInterface.selectByServerUserId(serverUserId);
                    Assert.notEmpty(faceList0, "该服务人员人脸信息不存在");
                    Assert.notEmpty(cards, "该服务人员未设置任何门禁卡");
                    Assert.notEmpty(serverUserDetailList, "该服务人员服务范围不在设备所在的单元");
                    Boolean checkPass0 = this.checkXqUnitDevicePermission(serverUser, serverUserDetailList, deviceIdList);
                    if (checkPass0) {
                        ServerUserFaceImage face0 = faceList0.get(0); //前端控制人脸只能传一张
                        List<Map<String, Object>> userFaceList0 = this.getUserFaceList(face0);

                        serverUser.setFaceEnable(OperationConstant.ONE); //已启用状态
                        this.updateById(serverUser);
                        //--------------下发人脸---------------------//
                        this.manualPushServerUserFaceToDevices(deviceIdList, face0, serverUser, userFaceList0, true);

                        AccessCard accessCard = cards.get(0);
                        accessCard.setCardEnable(OperationConstant.ONE);
                        this.accessCardServiceInterface.updateById(accessCard);
                        //----------------下发门禁卡-------------------//
                        resultBean = this.manualPushServerCardToDevices(cards.get(0), deviceIdList, true);

                    }
                    break;
                case 1: //仅人脸下发到设备
                    List<ServerUserFaceImage> faceList1 = serverUserFaceImageServiceInterface.selectByServerUserId(serverUserId);
                    Assert.notEmpty(faceList1, "该服务人员人脸信息不存在");
                    Assert.notEmpty(serverUserDetailList, "该服务人员服务范围不存在设备所在的单元");
                    Boolean checkPass1 = this.checkXqUnitDevicePermission(serverUser, serverUserDetailList, deviceIdList);
                    if (checkPass1) {
                        ServerUserFaceImage face1 = faceList1.get(0); //前端控制人脸只能传一张
                        List<Map<String, Object>> userFaceList1 = this.getUserFaceList(face1);
                        serverUser.setFaceEnable(OperationConstant.ONE); //已启用状态
                        this.updateById(serverUser);
                        //--------------下发人脸---------------------//
                        resultBean = this.manualPushServerUserFaceToDevices(deviceIdList, face1, serverUser, userFaceList1, true);
                    }
                    break;
                case 2: //仅门禁卡下发到设备
                    Assert.notEmpty(cards, "该服务人员未设置任何门禁卡");
                    List<ServerUserDetail> serverUserDetailList2 = serverUserDetailServiceInterface.findServerUserDetailList(serverUserId);
                    Boolean checkPass2 = this.checkXqUnitDevicePermission(serverUser, serverUserDetailList2, deviceIdList);
                    if (checkPass2) {
                        AccessCard accessCard = cards.get(0);
                        accessCard.setCardEnable(OperationConstant.ONE);
                        this.accessCardServiceInterface.updateById(accessCard);
                        //--------------下发门禁卡---------------------//
                        resultBean = this.manualPushServerCardToDevices(cards.get(0), deviceIdList, true);
                    }
                    break;
                default:
                    break;
            }
        } else if (operType.equals(OperationConstant.TWO)) { //门禁禁用
            //通用设备ID数组
            Assert.notEmpty(cards, "该服务人员未设置任何门禁卡");
            List<ServerUserFaceImage> faceList1 = serverUserFaceImageServiceInterface.selectByServerUserId(serverUserId);
            Assert.notEmpty(faceList1, "该服务人员人脸信息不存在");
            List<Long> enableDeviceIdList = new ArrayList<>();
            List<Device> deviceList = this.deviceFeign.getSpecialListByPathUse(serverUser.getResidentialId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL);
            //添加普通设备位置的设备
            if (deviceList != null && deviceList.size() > 0) {
                deviceList.forEach(device -> enableDeviceIdList.add(device.getId()));
            }
            //添加特殊设备位置的设备
            ResultBean<AccessFacePushRecords> faceResult = this.accessFacePushRecordsServiceInterface.getListByUserId(serverUserId, OperationConstant.FOUR, null);
            List<AccessFacePushRecords> faceRecords = faceResult.getList();
            List<Long> faceDeviceIdList = enableDeviceIdList;
            if (faceRecords != null && faceRecords.size() > 0) {
                faceRecords.forEach(records -> faceDeviceIdList.add(records.getDeviceId()));
            }
            serverUser.setFaceEnable(OperationConstant.TWO); //已启用状态
            //禁用人脸
            this.manualPushServerUserFaceToDevices(faceDeviceIdList, faceList1.get(0), serverUser, new ArrayList<>(0), false);
            if (this.updateById(serverUser)) {
                resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
            } else {
                resultBean = new ResultBean<>(ResultEnum.SUCCESS, false);
            }

            ResultBean<AccessCardPushRecords> cardResult = this.accessCardPushRecordsServiceInterface.getListByUserId(serverUserId, OperationConstant.FOUR, null);
            List<AccessCardPushRecords> cardRecords = cardResult.getList();
            List<Long> cardDeviceIdList = enableDeviceIdList;
            if (cardRecords != null && cardRecords.size() > 0) {
                cardRecords.forEach(record -> cardDeviceIdList.add(record.getDeviceId()));
            }
            //禁用门禁卡
            AccessCard accessCard = cards.get(0);
            accessCard.setCardEnable(OperationConstant.TWO);
            this.manualPushServerCardToDevices(accessCard, cardDeviceIdList, false);
            if (accessCardServiceInterface.updateById(accessCard)) {
                resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
            } else {
                resultBean = new ResultBean<>(ResultEnum.ERROR, false);
            }
        } else if (operType.equals(OperationConstant.THREE)) { //人脸门禁启用或重新启用
            List<ServerUserFaceImage> enablefaceList = serverUserFaceImageServiceInterface.selectByServerUserId(serverUserId);
            Assert.notEmpty(enablefaceList, "该服务人员人脸信息不存在");
            List<Map<String, Object>> userFaceList = this.getUserFaceList(enablefaceList.get(0));
            List<Long> enableDeviceIdList = new ArrayList<>();
            //添加普通设备位置的设备
            List<Device> deviceList = this.deviceFeign.getSpecialListByPathUse(serverUser.getResidentialId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL);
            if (deviceList != null && deviceList.size() > 0) {
                deviceList.forEach(device -> enableDeviceIdList.add(device.getId()));
            }
            //添加特殊设备位置的设备
            ResultBean<AccessFacePushRecords> faceResult = this.accessFacePushRecordsServiceInterface.getListByUserId(serverUserId, OperationConstant.FOUR, OperationConstant.TWO);
            List<AccessFacePushRecords> faceRecords = faceResult.getList();
            if (faceRecords != null && faceRecords.size() > 0) {
                faceRecords.forEach(record -> enableDeviceIdList.add(record.getDeviceId()));
            }
            if (enableDeviceIdList.size() > 0) {
                resultBean = this.manualPushServerUserFaceToDevices(enableDeviceIdList, enablefaceList.get(0), serverUser, userFaceList, true);
                //设置人脸状态为启用
                if (resultBean.getData()) {
                    serverUser.setFaceEnable(OperationConstant.ONE);
                    this.updateById(serverUser);
                }
            } else { //启用下发到一般授权设备上
                //是否关联单元
                List<ServerUserDetail> detailList = this.serverUserDetailServiceInterface.findServerUserDetailList(serverUserId);

                Map<String,String> logMap = new HashMap<>();
                //小区
                if (!StringUtils.isEmpty(serverUser.getResidentialName())){
                    logMap.put("xqName",serverUser.getResidentialName());
                }else {
                    logMap.put("xqName",null);
                }
                //单元
                if (!StringUtils.isEmpty(serverUser.getUnitName())){
                    logMap.put("unitName",serverUser.getUnitName());
                }else {
                    logMap.put("unitName",null);
                }
                //房间
                if (!StringUtils.isEmpty(serverUser.getRoomName())){
                    logMap.put("roomName",serverUser.getRoomName());
                }else {
                    logMap.put("roomName",null);
                }
                //用户名
                if (!StringUtils.isEmpty(serverUser.getName())){
                    logMap.put("userName",serverUser.getName());
                }else {
                    logMap.put("userName",null);
                }

                if (null != detailList && !detailList.isEmpty()) {
                    for (ServerUserDetail serverUserDetail : detailList) {
                        this.pushServerUserFaceToUniversalDevices(serverUser, enablefaceList.get(0), userFaceList, serverUserDetail.getUnitId(), OperationConstant.ONE,logMap);
                    }
                } else {
                    pushServerUserFaceToUniversalDevices(serverUser, enablefaceList.get(0), userFaceList, null, OperationConstant.ONE,logMap);
                }
                //设置人脸状态为启用
                serverUser.setFaceEnable(OperationConstant.ONE);
                if (this.updateById(serverUser)) {
                    resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
                } else {
                    resultBean = new ResultBean<>(ResultEnum.ERROR, false);
                }
            }
        } else if (operType.equals(OperationConstant.FIVE)) { //人脸门禁禁用
            //通用设备ID数组
//            Assert.notEmpty(cards, "该服务人员未设置任何门禁卡");
            List<ServerUserFaceImage> faceList1 = serverUserFaceImageServiceInterface.selectByServerUserId(serverUserId);
            Assert.notEmpty(faceList1, "该服务人员人脸信息不存在");
            List<Long> enableDeviceIdList = new ArrayList<>();
            List<Device> deviceList = this.deviceFeign.getSpecialListByPathUse(serverUser.getResidentialId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL);
            //添加普通设备位置的设备
            if (deviceList != null && deviceList.size() > 0) {
                deviceList.forEach(device -> enableDeviceIdList.add(device.getId()));
            }
            //添加特殊设备位置的设备
            ResultBean<AccessFacePushRecords> faceResult = this.accessFacePushRecordsServiceInterface.getListByUserId(serverUserId, OperationConstant.FOUR, null);
            List<AccessFacePushRecords> faceRecords = faceResult.getList();
            List<Long> faceDeviceIdList = enableDeviceIdList;
            if (faceRecords != null && faceRecords.size() > 0) {
                faceRecords.forEach(records -> faceDeviceIdList.add(records.getDeviceId()));
            }
            serverUser.setFaceEnable(OperationConstant.TWO); //已禁用状态
            //禁用人脸
            this.manualPushServerUserFaceToDevices(faceDeviceIdList, faceList1.get(0), serverUser, new ArrayList<>(0), false);
            if (this.updateById(serverUser)) {
                resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
            } else {
                resultBean = new ResultBean<>(ResultEnum.SUCCESS, false);
            }
        } else if (operType.equals(OperationConstant.FOUR)) { //门禁卡启用或重启用
            List<AccessCard> cardList = this.accessCardServiceInterface.getAccessCardByUserIdAndType(String.valueOf(serverUserId), OperationConstant.FOUR);
            Assert.notEmpty(cardList, "该服务人员没有门禁卡信息，无需禁用");
            List<Long> enableDeviceIdList = new ArrayList<>();
            List<Device> deviceList = this.deviceFeign.getSpecialListByPathUse(serverUser.getResidentialId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL);
            //添加普通设备位置的设备
            if (deviceList != null && deviceList.size() > 0) {
                deviceList.forEach(device -> enableDeviceIdList.add(device.getId()));
            }
            //添加特殊设备位置的设备
            ResultBean<AccessCardPushRecords> cardPushRecordsResult = this.accessCardPushRecordsServiceInterface.getListByUserId(serverUserId, OperationConstant.FOUR, OperationConstant.TWO);
            List<AccessCardPushRecords> cardPushRecords = cardPushRecordsResult.getList();
            AccessCard accessCard = cardList.get(0);
            if (cardPushRecords != null && cardPushRecords.size() > 0) { //如果有下发记录，则启用下发过的设备
                cardPushRecords.forEach(records -> enableDeviceIdList.add(records.getDeviceId()));
            }
            if (enableDeviceIdList.size() > 0) {
                //TODO
                this.manualPushServerCardToDevices(accessCard, enableDeviceIdList, true);
            } else { //否则下发到一般授权设备
                accessCardServiceInterface.sendPushCard(accessCard, DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.ONE);
            }
            accessCard.setCardEnable(OperationConstant.ONE);
            boolean b = this.accessCardServiceInterface.updateById(accessCard);
            if (b) {
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            } else {
                return new ResultBean<>(ResultEnum.ERROR);
            }
        } else if (operType.equals(OperationConstant.SIX)) { //门禁卡禁用
            //通用设备ID数组
            Assert.notEmpty(cards, "该服务人员未设置任何门禁卡");
            List<Long> enableDeviceIdList = new ArrayList<>();
            List<Device> deviceList = this.deviceFeign.getSpecialListByPathUse(serverUser.getResidentialId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL);
            //添加普通设备位置的设备
            if (deviceList != null && deviceList.size() > 0) {
                deviceList.forEach(device -> enableDeviceIdList.add(device.getId()));
            }
            //添加特殊设备位置的设备
            ResultBean<AccessFacePushRecords> faceResult = this.accessFacePushRecordsServiceInterface.getListByUserId(serverUserId, OperationConstant.FOUR, null);
            List<AccessFacePushRecords> faceRecords = faceResult.getList();
            List<Long> faceDeviceIdList = enableDeviceIdList;
            if (faceRecords != null && faceRecords.size() > 0) {
                faceRecords.forEach(records -> faceDeviceIdList.add(records.getDeviceId()));
            }
            serverUser.setFaceEnable(OperationConstant.TWO); //已启用状态
            ResultBean<AccessCardPushRecords> cardResult = this.accessCardPushRecordsServiceInterface.getListByUserId(serverUserId, OperationConstant.FOUR, null);
            List<AccessCardPushRecords> cardRecords = cardResult.getList();
            List<Long> cardDeviceIdList = enableDeviceIdList;
            if (cardRecords != null && cardRecords.size() > 0) {
                cardRecords.forEach(record -> cardDeviceIdList.add(record.getDeviceId()));
            }
            //禁用门禁卡
            AccessCard accessCard = cards.get(0);
            accessCard.setCardEnable(OperationConstant.TWO);
            this.manualPushServerCardToDevices(accessCard, cardDeviceIdList, false);
            if (accessCardServiceInterface.updateById(accessCard)) {
                resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
            } else {
                resultBean = new ResultBean<>(ResultEnum.ERROR, false);
            }
        }
        return resultBean;
    }

    @Override
    public int getServerUserCount(ServerUserDto serverUserDto) {
        EntityWrapper<ServerUser> wrapper = new EntityWrapper<ServerUser>();
        //机构位置
        if (StringUtils.isNotBlank(serverUserDto.getOrgPosition())) {
            wrapper.like("s_org_position", serverUserDto.getOrgPosition(), SqlLike.RIGHT);
        }
        //删除状态：0正常
        wrapper.eq("i_status", OperationConstant.ZERO);
        return this.selectCount(wrapper);
    }

    @Override
    public List<ServerUser> getServerUserByCondition(ServerUserDto serverUserDto) {
        Wrapper<ServerUser> wrapper = new EntityWrapper<>();
        if (serverUserDto.getIds() != null && serverUserDto.getIds().size() > 0) {
                wrapper.in("l_id", serverUserDto.getIds());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionProvince())) {
            wrapper.eq("s_region_province", serverUserDto.getRegionProvince());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionCity())) {
            wrapper.eq("s_region_city", serverUserDto.getRegionCity());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getRegionArea())) {
            wrapper.eq("s_region_area", serverUserDto.getRegionArea());
        }
        if (null != serverUserDto.getResidentialId()) {
            wrapper.eq("l_residential_id", serverUserDto.getResidentialId());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getName())) {
            wrapper.like("s_name", serverUserDto.getName(), SqlLike.DEFAULT);
        }
        if (StringUtils.isNotEmpty(serverUserDto.getTel())) {
            wrapper.like("s_tel", serverUserDto.getTel(), SqlLike.RIGHT);
        }
        if (null != serverUserDto.getType()) {
            wrapper.eq("i_type", serverUserDto.getType());
        }
        if (StringUtils.isNotEmpty(serverUserDto.getIdCard())) {
            wrapper.like("s_id_card", serverUserDto.getIdCard(), SqlLike.RIGHT);
        }
        if (null != serverUserDto.getIsEnable()) {
            wrapper.eq("i_is_enable", serverUserDto.getIsEnable());
        }
        //机构位置
        if (StringUtils.isNotBlank(serverUserDto.getOrgPosition())) {
            wrapper.like("s_org_position", serverUserDto.getOrgPosition(), SqlLike.RIGHT);
        }
        wrapper.eq("i_status", OperationConstant.ZERO);
        return selectList(wrapper);
    }

    /* -------------------------------------------------- 内部方法 -------------------------------------------------- */
    /* -------------------------------------------------------------------------------------------------------------- */

    /**
     * 功能描述:组装出入卡对象
     *
     * @param accessCard
     * @param serverUser
     * @param detailList
     * @return AccessCardDto
     */
    private AccessCardDto copyAccessCardDto(AccessCard accessCard, ServerUser serverUser, List<ServerUserDetail> detailList, Integer deviceAccessType) {
        AccessCardDto accessCardDto = new AccessCardDto();
        accessCardDto.setId(accessCard.getId());
        accessCardDto.setBeginDate(accessCard.getBeginDate());
        accessCardDto.setEndDate(accessCard.getEndDate());
        accessCardDto.setCardNo(accessCard.getCardNo());
        accessCardDto.setUserId(serverUser.getId().toString());
        accessCardDto.setUserName(serverUser.getName());
        accessCardDto.setResidentialId(serverUser.getResidentialId());
        accessCardDto.setResidentialName(serverUser.getResidentialName());
        accessCardDto.setOrgPosition(serverUser.getOrgPosition());
        accessCardDto.setRootOrgId(serverUser.getRootOrgId());
        accessCardDto.setUserId(serverUser.getId().toString());
        accessCardDto.setType(OperationConstant.FOUR);
        accessCardDto.setDetailList(detailList);
        accessCardDto.setCreateAccountId(accessCard.getCreateAccountId());
        //下面为新增参数，用于表示这张卡是发送给什么位置的设备，比如一般授权位置的设备，或者是特殊授权位置的设备
        accessCardDto.setDeviceAccessType(deviceAccessType);
        return accessCardDto;
    }

    /**
     * 功能描述:获取下发人脸对象
     *
     * @param serverUserFaceImage
     * @return List<Map < String, Object>>
     */
    private List<Map<String, Object>> getUserFaceList(ServerUserFaceImage serverUserFaceImage) {
        List<Map<String, Object>> userFaceList = new ArrayList<>();
        String imgHost = this.confFeign.getFileServerHost();
        Map<String, Object> map = new HashMap<>(3);
        map.put("imgSrc", imgHost + serverUserFaceImage.getImageUri());
        map.put("imgMd5", serverUserFaceImage.getFaceCode());
        userFaceList.add(map);
        return userFaceList;
    }

    /**
     * 功能描述:下发服务人员人脸（下发到所有符合小区、单元的设备）
     *
     * @param serverUser
     * @param userFaceList
     * @param unitId
     * @return
     */
    private void pushServerUserFace(ServerUser serverUser, List<Map<String, Object>> userFaceList, Long unitId) {
        //  下发人脸
        UserInfoDto dto = new UserInfoDto();
        dto.setId(UserFlagConstant.SERVER_USER_NUMBER_FLAG + serverUser.getId());
        dto.setFaceCodeList(userFaceList);
        dto.setName(serverUser.getName());
        if (StringUtils.isNotEmpty(serverUser.getResidentialName())){
            dto.setResidentialName(serverUser.getResidentialName());
        }
        DispatchTask task = new DispatchTask();
        task.setData(dto);
        task.setXqId(serverUser.getResidentialId());
        if (null != unitId) {
            task.setUnitId(unitId);
        }
        Map<String,String> logMap = new HashMap<>();
        //小区
        if (!StringUtils.isEmpty(dto.getResidentialName())){
            logMap.put("xqName",dto.getResidentialName());
        }else {
            logMap.put("xqName",null);
        }
        //单元
        if (!StringUtils.isEmpty(serverUser.getUnitName())){
            logMap.put("unitName",serverUser.getUnitName());
        }else {
            logMap.put("unitName",null);
        }
        //房间
        if (!StringUtils.isEmpty(serverUser.getRoomName())){
            logMap.put("roomName",serverUser.getRoomName());
        }else {
            logMap.put("roomName",null);
        }
        //用户名
        if (!StringUtils.isEmpty(serverUser.getName())){
            logMap.put("userName",serverUser.getName());
        }else {
            logMap.put("userName",null);
        }
        //有效期开始时间
        SimpleDateFormat format = new SimpleDateFormat();
        if (null != dto.getBeginDate()){
            logMap.put("beginTime",format.format(dto.getBeginDate()));
        }else {
            logMap.put("beginTime",null);
        }
        //有效期结束时间
        if (null != dto.getEndDate()){
            logMap.put("endTime",format.format(dto.getEndDate()));
        }else {
            logMap.put("endTime",null);
        }
        //人脸
        if (dto.getFaceCodeList().size() > 0){
            List<String> list = new ArrayList<>();
            for (Map m : dto.getFaceCodeList()) {
                if (m.containsKey("imgSrc")){
                    list.add(m.get("imgSrc").toString());
                }
            }
            logMap.put("imgSrc", JsonUtils.listToString(list));
        }else {
            logMap.put("imgSrc",null);
        }
        logMap.put("deleteUser", "true");
        this.deviceFeign.pushUserFace(task,logMap);
    }

    private void pushServerUserFaceToUniversalDevices(ServerUser serverUser, ServerUserFaceImage serverUserFaceImage, List<Map<String, Object>> userFaceList, Long unitId, Integer operType, Map<String,String> map) {
        //  下发人脸
        UserInfoDto dto = new UserInfoDto();
        dto.setId(UserFlagConstant.SERVER_USER_NUMBER_FLAG + serverUser.getId());
        DispatchTask task = new DispatchTask();
        task.setXqId(serverUser.getResidentialId());
        if (null != unitId) {
            task.setUnitId(unitId);
        }
        if(operType.equals(OperationConstant.THREE)){ //表示删除操作
            task.setData(dto);
            this.deviceFeign.deleteUserFaceToUniversalDevices(task, map);
        }else{
            dto.setFaceCodeList(userFaceList);
            dto.setBeginDate(serverUserFaceImage.getBeginDate());
            dto.setEndDate(serverUserFaceImage.getEndDate());
            dto.setName(serverUser.getName());
            task.setData(dto);
            this.deviceFeign.pushUserFaceToUniversalDevices(task, operType, map);
        }
    }

    /**
     * 功能描述:手动下发服务人员人脸到设备（下发到指定的设备）
     *
     * @param deviceIdList
     * @param serverUser
     * @param userFaceList
     * @return
     */
    private ResultBean<Boolean> manualPushServerUserFaceToDevices(List<Long> deviceIdList, ServerUserFaceImage serverUserFaceImage, ServerUser serverUser, List<Map<String, Object>> userFaceList, Boolean isPush) {
        UserInfoDto dto = new UserInfoDto();
        dto.setId(UserFlagConstant.SERVER_USER_NUMBER_FLAG + serverUser.getId());
        ManualPushDevicesTask task = new ManualPushDevicesTask();
        task.setDeviceIdList(deviceIdList);
        task.setOperType(OperationConstant.ONE);
        if (!isPush) {
            task.setOperType(OperationConstant.THREE);
            task.setData(dto);
        }else{
            dto.setFaceCodeList(userFaceList);
            dto.setBeginDate(serverUserFaceImage.getBeginDate());
            dto.setEndDate(serverUserFaceImage.getEndDate());
            dto.setName(serverUser.getName());
            task.setData(dto);
        }
        return this.deviceFeign.manualPushUserFaceToDevices(task);
    }

    /**
     * 功能描述:手动下发服务人员门禁卡到设备（下发到指定的设备）
     *
     * @param accessCard
     * @param deviceIdList
     * @return
     */
    private ResultBean<Boolean> manualPushServerCardToDevices(AccessCard accessCard, List<Long> deviceIdList, Boolean isPush) {
        ManualPushDevicesTask task = new ManualPushDevicesTask();
        task.setDeviceIdList(deviceIdList);
        task.setData(accessCard);
        task.setEnable(isPush);
        task.setOperType(OperationConstant.ONE);
        if (!isPush) {
            task.setOperType(OperationConstant.THREE);
        }
        return this.deviceFeign.manualPushUserCardToDevices(task);
    }

    /**
     * 检查服务人员服务范围是否在所选设备区域
     *
     * @param serverUser
     * @param detailList
     * @param deviceIdList
     * @return
     */
    private Boolean checkXqUnitDevicePermission(ServerUser serverUser, List<ServerUserDetail> detailList, List<Long> deviceIdList) {
        Boolean check = false;
        for (int i = 0; i < deviceIdList.size(); i++) {
            Long deviceId = deviceIdList.get(i);
            Device device = deviceFeign.getEntityById(deviceId);
            Long deviceUnitId = device.getUnitId();
            Long deviceXqId = device.getXqId();
            if (deviceUnitId != null) {
                for (int j = 0; j < detailList.size(); j++) {
                    ServerUserDetail detail = detailList.get(j);
                    if (detail.getUnitId().equals(deviceUnitId)) {
                        check = true;
                        break;
                    } else {
                        continue;
                    }
                }
                if (!check) {
                    Assert.isTrue(check, "该服务人员的服务范围不在部分设备所在的单元");
                    break;
                }
                Long serverXqId = serverUser.getResidentialId();
                if (!serverXqId.equals(deviceXqId)) {
                    check = false;
                    Assert.isTrue(check, "该服务人员的服务范围不在部分设备所在的小区");
                }
            } else {
                Long serverXqId = serverUser.getResidentialId();
                if (!serverXqId.equals(deviceXqId)) {
                    check = false;
                    Assert.isTrue(check, "该服务人员的服务范围不在设备所在的小区");
                } else {
                    check = true;
                }
            }
        }
        return check;
    }
}

