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.ExcelResultEnum;
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.entity.DispatchTask;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.device.api.constant.DeviceConstants;
import com.sptg.device.api.dto.AccessCardSimpleDto;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.feigns.DeviceFeign;
import com.sptg.device.api.vo.AccessUserCardPushDevicesTask;
import com.sptg.device.api.vo.AccessUserCardPushDevicesVO;
import com.sptg.device.api.vo.DeviceVO;
import com.sptg.device.api.vo.ManualPushDevicesTask;
import com.sptg.estate.api.dto.AccessCardDto;
import com.sptg.estate.api.dto.AccessRecordsDto;
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.AccessCardMapper;
import com.sptg.estate.biz.service.*;
import lombok.AllArgsConstructor;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * title: UserCardServiceImpl
 * package: com.sptg.estate.biz.security.impl
 * description: 门禁卡 服务层实现类
 */
@Service
@AllArgsConstructor
public class AccessCardServiceImpl extends ServiceImpl<AccessCardMapper, AccessCard> implements AccessCardServiceInterface {

    private final UserServiceInterface userServiceInterface;

    private final RoomServiceInterface roomServiceInterface;

    private final UnitServiceInterface unitServiceInterface;

    private final ResidentialServiceInterface residentialServiceInterface;

    private final DeviceFeign deviceFeign;

    @Override
    public ResultBean<Page<AccessCard>> showAccessCardList(AccessCardDto accessCardDto) {
        Wrapper<AccessCard> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);

        //过滤用户类型,服务人员类型
        List<Integer> typeList = new ArrayList<>();
        typeList.add(OperationConstant.ZERO);
        typeList.add(OperationConstant.FOUR);
        wrapper.notIn("i_type", typeList);

        //根据机构
        if (StringUtils.isNotBlank(accessCardDto.getOrgPosition())) {
            wrapper.like("s_org_position", accessCardDto.getOrgPosition(), SqlLike.RIGHT);
        }
        //根据物业
        if (StringUtils.isNotBlank(accessCardDto.getEstatePosition())) {
            wrapper.like("s_estate_position", accessCardDto.getEstatePosition(), SqlLike.RIGHT);
        }
        //根据开门卡号
        if (StringUtils.isNotBlank(accessCardDto.getCardNo())) {
            wrapper.like("s_card_no", accessCardDto.getCardNo());
        }
        //根据时间日期
        if (null != accessCardDto.getBeginDate()) {
            wrapper.ge("t_begin_date", accessCardDto.getBeginDate());
        }
        if (null != accessCardDto.getEndDate()) {
            wrapper.le("t_end_date", accessCardDto.getEndDate());
        }
        if (accessCardDto.getResidentialId() != null) {
            wrapper.eq("l_residential_id", accessCardDto.getResidentialId());
        }
        if (accessCardDto.getUnitId() != null) {
            wrapper.eq("l_unit_id", accessCardDto.getUnitId());
        }
        if (accessCardDto.getRoomId() != null) {
            wrapper.eq("l_room_id", accessCardDto.getRoomId());
        }
        //  排序字段
        if (accessCardDto.getSortField() != null && accessCardDto.getSortOrder() != null) {
            wrapper.orderBy(accessCardDto.getSortField(), accessCardDto.getSortOrder().equals("asc"));
        } else {
            //  排序字段 时间降序
            wrapper.orderBy("t_create_date", false);
        }
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectPage(accessCardDto.getPage(), wrapper));
    }

    @Override
    public ResultBean<Page<AccessCard>> showCardList(AccessCardDto accessCardDto) {
        Wrapper wrapper = new EntityWrapper();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);

        if (null != accessCardDto.getResidentialId()) {
            wrapper.eq("l_residential_id", accessCardDto.getResidentialId());
        }
        if (null != accessCardDto.getUnitId()) {
            wrapper.eq("l_unit_id", accessCardDto.getUnitId());

        }
        if (null != accessCardDto.getRoomId()) {
            wrapper.eq("l_room_id", accessCardDto.getRoomId());
        }
        if (StringUtils.isNotEmpty(accessCardDto.getUserName())) {
            wrapper.like("s_user_name", accessCardDto.getUserName(), SqlLike.DEFAULT);
        }
        if (StringUtils.isNotEmpty(accessCardDto.getCardNo())) {
            wrapper.like("s_card_no", accessCardDto.getCardNo(), SqlLike.RIGHT);
        }
        if (null != accessCardDto.getBeginDate()) {
            wrapper.ge("t_begin_date", accessCardDto.getBeginDate());
        }
        if (null != accessCardDto.getEndDate()) {
            wrapper.le("t_end_date", accessCardDto.getEndDate());
        }

        //  排序字段
        if (accessCardDto.getSortField() != null && accessCardDto.getSortOrder() != null) {
            wrapper.orderBy(accessCardDto.getSortField(), accessCardDto.getSortOrder().equals("asc"));
        } else {
            //  排序字段 时间降序
            wrapper.orderBy("t_create_date", false);
        }
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectPage(accessCardDto.getPage(), wrapper));
    }

    @Override
    public ResultBean<Boolean> addAccessCard(AccessCardDto accessCardDto) {
        if (null != accessCardDto.getType()) {
            //  住户
            if (OperationConstant.ZERO == accessCardDto.getType()) {
                User user = this.userServiceInterface.findUserById(Long.valueOf(accessCardDto.getUserId()));
                accessCardDto.setOrgPosition(user.getOrgPosition());
                accessCardDto.setEstatePosition(user.getEstatePosition());
                accessCardDto.setRoomId(user.getRoomId());
                accessCardDto.setRoomName(user.getRoomName());
                accessCardDto.setUnitId(user.getUnitId());
                accessCardDto.setUnitName(user.getUnitName());
                accessCardDto.setRootOrgId(user.getRootOrgId());
            }

            //  房间
            if (OperationConstant.ONE == accessCardDto.getType()) {
                Room room = this.roomServiceInterface.findRoomById(accessCardDto.getRoomId());
                accessCardDto.setUnitId(room.getUnitId());
                accessCardDto.setOrgPosition(room.getOrgPosition());
                accessCardDto.setEstatePosition(room.getEstatePosition());
                accessCardDto.setRootOrgId(room.getRootOrgId());
            }
            //  单元
            if (OperationConstant.TWO == accessCardDto.getType()) {
                Unit unit = this.unitServiceInterface.findUnitById(accessCardDto.getUnitId());
                accessCardDto.setOrgPosition(unit.getOrgPosition());
                accessCardDto.setEstatePosition(unit.getEstatePosition());
                accessCardDto.setRootOrgId(unit.getRootOrgId());
            }
            //  小区
            if (OperationConstant.THREE == accessCardDto.getType()) {
                Residential residential = this.residentialServiceInterface.findResidentialById(accessCardDto.getResidentialId());
                accessCardDto.setOrgPosition(residential.getOrgPosition());
                accessCardDto.setEstatePosition(residential.getEstatePosition());
                accessCardDto.setRootOrgId(residential.getRootOrgId());
            }
        }
        if (OperationConstant.ZERO == accessCardDto.getType()) {
            List<AccessCard> userCardList = this.findAccessCardByCondition(accessCardDto);
            if (null != userCardList && !userCardList.isEmpty()) {
                return new ResultBean<>(EstateEnum.USER_CARD_DATA_EXISTES);
            }
        }
        accessCardDto.setCreateDate(new Date());
        accessCardDto.setStatus(OperationConstant.ZERO);
        accessCardDto.setCardEnable(OperationConstant.ONE);
        if (this.insert(accessCardDto)) {
            Integer deviceAccessType = accessCardDto.getDeviceAccessType();
            if (deviceAccessType != null && deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)) {
                this.sendPushCard(accessCardDto, deviceAccessType, OperationConstant.ONE);
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            } else {
                this.sendPushCard(accessCardDto);
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    public ResultBean<Boolean> pushAccessCardBatch(List<AccessCardDto> accessCardDtoList) {
        this.pushCardBatch(accessCardDtoList);
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    /**
     * 功能描述:新增门禁卡（但不下发到设备上）
     *
     * @param accessCardDto 门禁卡业务对象
     * @return
     */
    @Override
    public ResultBean<AccessCard> simpleAddAccessCard(AccessCardDto accessCardDto) {
        if (null != accessCardDto.getType()) {
            //  住户
            if (OperationConstant.ZERO == accessCardDto.getType()) {
                User user = this.userServiceInterface.findUserById(Long.valueOf(accessCardDto.getUserId()));
                accessCardDto.setOrgPosition(user.getOrgPosition());
                accessCardDto.setRoomId(user.getRoomId());
                accessCardDto.setRoomName(user.getRoomName());
                accessCardDto.setUnitId(user.getUnitId());
                accessCardDto.setUnitName(user.getUnitName());
                accessCardDto.setRootOrgId(user.getRootOrgId());
                accessCardDto.setEstatePosition(user.getEstatePosition());
            }

            //  房间
            if (OperationConstant.ONE == accessCardDto.getType()) {
                Room room = this.roomServiceInterface.findRoomById(accessCardDto.getRoomId());
                accessCardDto.setUnitId(room.getUnitId());
                accessCardDto.setOrgPosition(room.getOrgPosition());
                accessCardDto.setRootOrgId(room.getRootOrgId());
                accessCardDto.setEstatePosition(room.getEstatePosition());
            }
            //  单元
            if (OperationConstant.TWO == accessCardDto.getType()) {
                Unit unit = this.unitServiceInterface.findUnitById(accessCardDto.getUnitId());
                accessCardDto.setOrgPosition(unit.getOrgPosition());
                accessCardDto.setRootOrgId(unit.getRootOrgId());
                accessCardDto.setEstatePosition(unit.getEstatePosition());
            }
            //  小区
            if (OperationConstant.THREE == accessCardDto.getType()) {
                Residential residential = this.residentialServiceInterface.findResidentialById(accessCardDto.getResidentialId());
                accessCardDto.setOrgPosition(residential.getOrgPosition());
                accessCardDto.setRootOrgId(residential.getRootOrgId());
                accessCardDto.setEstatePosition(residential.getEstatePosition());
            }
        }
        if (OperationConstant.ZERO == accessCardDto.getType()) {
            List<AccessCard> userCardList = this.findAccessCardByCondition(accessCardDto);
            if (null != userCardList && !userCardList.isEmpty()) {
                return new ResultBean<>(EstateEnum.USER_CARD_DATA_EXISTES);
            }
        }
        accessCardDto.setCreateDate(new Date());
        accessCardDto.setStatus(OperationConstant.ZERO);
        accessCardDto.setCardEnable(OperationConstant.ZERO); //未下发
        if (this.insert(accessCardDto)) {

            return new ResultBean<>(ResultEnum.SUCCESS, accessCardDto);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    /**
     * @param devicesAccessPushVO 住户门禁卡业务对象
     * @return
     */
    @Override
    public ResultBean<Boolean> sendAccessUserCard(DevicesAccessPushVO devicesAccessPushVO) {
        AccessCardDto accessCardDto = devicesAccessPushVO.getAccessCardDto();
        //原数据
        AccessCard accessCard = this.findAccessCardById(accessCardDto.getId());
        if (null == accessCardDto) return new ResultBean<>(ResultEnum.ERROR, false);
        //特殊授权下发
        if (devicesAccessPushVO.getOperType().equals(OperationConstant.ONE)) {
            List<Long> deviceIdList = devicesAccessPushVO.getDeviceIdList();
            ManualPushDevicesTask task = new ManualPushDevicesTask();
            task.setDeviceIdList(deviceIdList);
            task.setData(accessCard);
            task.setOperType(OperationConstant.ONE);
            this.manualSendPushCardToDevices(task);
            if (accessCard.getCardEnable() != null && accessCard.getCardEnable() == 0) {
                accessCard.setCardEnable(OperationConstant.ONE);
                boolean isUpDateCardEnable = this.updateById(accessCard);
                if (!isUpDateCardEnable) {
                    return new ResultBean<>(ResultEnum.ERROR);
                }
            }
        } else if (devicesAccessPushVO.getOperType().equals(OperationConstant.TWO)) {       //门禁卡禁用
            accessCard.setCardEnable(OperationConstant.TWO);
            if (this.updateById(accessCard)) {
                this.sendRemoveCard(accessCard);
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            }
        } else if (devicesAccessPushVO.getOperType().equals(OperationConstant.THREE)) {
            List<Long> deviceIdList = devicesAccessPushVO.getDeviceIdList();
            ManualPushDevicesTask task = new ManualPushDevicesTask();
            task.setDeviceIdList(deviceIdList);
            task.setData(accessCard);
            task.setOperType(OperationConstant.ONE);
            this.manualSendPushCardToDevices(task);
            if (accessCard.getCardEnable() != null && accessCard.getCardEnable() == 0) {
                accessCard.setCardEnable(OperationConstant.ONE);
                boolean isUpDateCardEnable = this.updateById(accessCard);
                if (!isUpDateCardEnable) {
                    return new ResultBean<>(ResultEnum.ERROR);
                }
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    @Override
    public AccessCard findAccessCardById(Long id) {
        Wrapper<AccessCard> wrapper = new EntityWrapper<>();
        wrapper.eq("l_id", id);
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        return this.selectOne(wrapper);
    }

    @Override
    public ResultBean<Boolean> updateAccessCard(AccessCardDto accessCardDto) {
        if (OperationConstant.ZERO == accessCardDto.getType()) {
            List<AccessCard> userCardList = this.findAccessCardByCondition(accessCardDto);
            if (null != userCardList && !userCardList.isEmpty()) {
                return new ResultBean<>(EstateEnum.USER_CARD_DATA_EXISTES);
            }
        }
        //  获取原数据
        AccessCard dbCard = this.selectById(accessCardDto.getId());
        //当前时间
        Date currentBeginDate = accessCardDto.getBeginDate();
        Date currentEndDate = accessCardDto.getEndDate();
        //结束时间
        Date oldBeginDate = dbCard.getBeginDate();
        Date oldEndDate = dbCard.getEndDate();
        //判断时间是否改变
        boolean isUpdateTime = false;
        if (currentBeginDate != null && currentEndDate != null && oldBeginDate != null && oldEndDate != null) {
            if (currentBeginDate.compareTo(oldBeginDate) != 0 || currentEndDate.compareTo(oldEndDate) != 0) {
                isUpdateTime = true;
            }
        }
        if (isUpdateTime) {
            dbCard.setBeginDate(accessCardDto.getBeginDate());
            dbCard.setEndDate(accessCardDto.getEndDate());
            dbCard.setCardEnable(OperationConstant.ONE);
            if (this.updateById(dbCard)) {
                Integer deviceAccessType = accessCardDto.getDeviceAccessType();
                if (deviceAccessType != null && deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)) {
                    this.sendPushCard(dbCard, deviceAccessType, OperationConstant.TWO);
                    return new ResultBean<>(ResultEnum.SUCCESS, true);
                } else {
                    this.sendPushCard(dbCard);
                    return new ResultBean<>(ResultEnum.SUCCESS, true);
                }
            }
        }
        if (!accessCardDto.getCardNo().equals(dbCard.getCardNo())) {
            AccessCard noNameCard = new AccessCard();
            BeanUtils.copyProperties(dbCard, noNameCard);
            noNameCard.setUserId(null);//变成不记名卡,新增一张不记名卡
            noNameCard.setUserName(null);
            if (noNameCard.getRoomId() != null) {
                noNameCard.setType(OperationConstant.ONE);
            } else if (noNameCard.getUnitId() != null) {
                noNameCard.setType(OperationConstant.TWO);
            } else if (noNameCard.getResidentialId() != null) {
                noNameCard.setType(OperationConstant.THREE);
            }
            if (this.updateById(noNameCard)) {
                dbCard.setCardNo(accessCardDto.getCardNo());
                dbCard.setBeginDate(accessCardDto.getBeginDate());
                dbCard.setEndDate(accessCardDto.getEndDate());
                dbCard.setCardEnable(OperationConstant.ONE);
                dbCard.setId(null);
                if (this.insert(dbCard)) { //新增一张记名卡，然后下发
                    Integer deviceAccessType = accessCardDto.getDeviceAccessType();
                    if (deviceAccessType != null && deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)) {
                        //下发新卡号
                        this.sendPushCard(dbCard, deviceAccessType, OperationConstant.TWO);
                        return new ResultBean<>(ResultEnum.SUCCESS, true);
                    } else {
                        this.sendPushCard(dbCard);
                        return new ResultBean<>(ResultEnum.SUCCESS, true);
                    }
                } else {
                    return new ResultBean<>(ResultEnum.SUCCESS, true);
                }
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS,true);
    }

    public ResultBean<Boolean> updateAccessCard(AccessCardDto accessCardDto, Integer deviceAccessType) {
        if (OperationConstant.ZERO == accessCardDto.getType()) {
            List<AccessCard> userCardList = this.findAccessCardByCondition(accessCardDto);
            if (null != userCardList && !userCardList.isEmpty()) {
                return new ResultBean<>(EstateEnum.USER_CARD_DATA_EXISTES);
            }
        }
        //  获取原数据
        AccessCard dbCard = this.selectById(accessCardDto.getId());
        //当前时间
        Date currentBeginDate = accessCardDto.getBeginDate();
        Date currentEndDate = accessCardDto.getEndDate();
        //结束时间
        Date oldBeginDate = dbCard.getBeginDate();
        Date oldEndDate = dbCard.getEndDate();
        //判断时间是否改变
        boolean isUpdateTime = false;
        if (currentBeginDate != null && currentEndDate != null && oldBeginDate != null && oldEndDate != null) {
            if (currentBeginDate.compareTo(oldBeginDate) != 0 || currentEndDate.compareTo(oldEndDate) != 0) {
                isUpdateTime = true;
            }
        }
        if ((!accessCardDto.getCardNo().equals(dbCard.getCardNo())) || isUpdateTime) {
            dbCard.setCardNo(accessCardDto.getCardNo());
            dbCard.setBeginDate(accessCardDto.getBeginDate());
            dbCard.setEndDate(accessCardDto.getEndDate());
            if (this.updateById(dbCard)) {
                // 下发卡号
                this.sendPushCard(dbCard);
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            }
        } else {
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    /**
     * 功能描述:编辑门禁卡（但不下发到设备上）
     *
     * @param accessCardDto :门禁卡业务对象
     * @return
     */
    @Override
    public ResultBean<Boolean> simpleUpdateAccessCard(AccessCardDto accessCardDto) {
        if (OperationConstant.ZERO == accessCardDto.getType()) {
            List<AccessCard> userCardList = this.findAccessCardByCondition(accessCardDto);
            if (null != userCardList && !userCardList.isEmpty()) {
                return new ResultBean<>(EstateEnum.USER_CARD_DATA_EXISTES);
            }
        }
        //  获取原数据
        AccessCard dbCard = this.selectById(accessCardDto.getId());
        //当前时间
        Date currentBeginDate = accessCardDto.getBeginDate();
        Date currentEndDate = accessCardDto.getEndDate();
        //结束时间
        Date oldBeginDate = dbCard.getBeginDate();
        Date oldEndDate = dbCard.getEndDate();
        //判断时间是否改变
        boolean isUpdateTime = false;
        if (currentBeginDate != null && currentEndDate != null && oldBeginDate != null && oldEndDate != null) {
            if (currentBeginDate.compareTo(oldBeginDate) != 0 || currentEndDate.compareTo(oldEndDate) != 0) {
                isUpdateTime = true;
            }
        }
        if ((!accessCardDto.getCardNo().equals(dbCard.getCardNo())) || isUpdateTime) {
            dbCard.setCardNo(accessCardDto.getCardNo());
            dbCard.setBeginDate(accessCardDto.getBeginDate());
            dbCard.setEndDate(accessCardDto.getEndDate());
            if (this.updateById(dbCard)) {
                if (accessCardDto.getCardEnable().equals(OperationConstant.ONE)) {
                    //TODO 下发新的卡片
                }
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            }
        } else {
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    public ResultBean<Boolean> deleteAccessCard(AccessCardDto accessCardDto) {
        AccessCard accessCard = this.findAccessCardById(accessCardDto.getId());
        if (null == accessCard) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        accessCard.setStatus(OperationConstant.MINUS_ONE);
        accessCard.setCardEnable(OperationConstant.TWO);
        if (this.updateById(accessCard)) {
            //删除下发卡号
            this.sendRemoveCard(accessCard);
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultBean<Boolean> deleteCardList(AccessCardDto accessCardDto) throws Exception {
        List<String> ids = accessCardDto.getIds();
        List<AccessCardSimpleDto> accessCardSimpleDtoList = new ArrayList<>();
        List<AccessCard> accessCardList = new ArrayList<>();
        for (String id : ids) {
            AccessCard accessCard = this.findAccessCardById(Long.valueOf(id));
            if (null != accessCard) {
                accessCard.setStatus(OperationConstant.MINUS_ONE); //设置成逻辑删除
                AccessCardSimpleDto dto = new AccessCardSimpleDto();
                dto.setId(accessCard.getId());
                dto.setCardNo(accessCard.getCardNo());
                dto.setResidentialId(accessCard.getResidentialId());
                dto.setUnitId(accessCard.getUnitId());

                accessCardList.add(accessCard);
                accessCardSimpleDtoList.add(dto);
            }

        }
        if (accessCardList.size() > 0) {
//            this.sendRemoveCardBatch(ids);
            if (this.updateBatchById(accessCardList, 1000)) {
                this.sendRemoveCardBatch(accessCardSimpleDtoList);
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);

//        List<String> ids = accessCardDto.getIds();
//        String msg;
//        for(String id : ids){
//            AccessCard accessCard = this.findAccessCardById(Long.valueOf(id));
//            if(null == accessCard){
//                msg = "卡号不存在，请核实后重新操作";
//                throw new Exception(msg);
//            }
//            accessCard.setStatus(OperationConstant.MINUS_ONE);
//            if(this.updateById(accessCard)){
//                this.sendRemoveCard(accessCard);
//            }
//        }
//        return new ResultBean<>(ResultEnum.SUCCESS,true);
    }

    @Override
    public List<AccessCard> findAccessCardByCondition(AccessCardDto userCardDto) {
        Wrapper<AccessCard> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);

        //卡号
        if (StringUtils.isNotBlank(userCardDto.getCardNo())) {
            wrapper.like("s_card_no", userCardDto.getCardNo(), SqlLike.DEFAULT);
        }
        /*else{
            //绑定的住户
            if(null != userCardDto.getUserId()){
                wrapper.eq("s_user_id",userCardDto.getUserId());
                if(null!= userCardDto.getType()){
                    wrapper.eq("i_type",userCardDto.getType());
                }
            }
        }*/
        if (null != userCardDto.getUserId()) {
            wrapper.eq("s_user_id", userCardDto.getUserId());
        }
        if (null != userCardDto.getType()) {
            wrapper.eq("i_type", userCardDto.getType());
        }
        //绑定的小区
        if (null != userCardDto.getResidentialId()) {
            wrapper.eq("l_residential_id", userCardDto.getResidentialId());
        }
        //过滤当前 Id
        if (null != userCardDto.getId()) {
            wrapper.notIn("l_id", userCardDto.getId());
        }
        //根据时间日期
        if (null != userCardDto.getBeginDate()) {
            wrapper.ge("t_begin_date", userCardDto.getBeginDate());
        }
        if (null != userCardDto.getEndDate()) {
            wrapper.le("t_end_date", userCardDto.getEndDate());
        }

        return this.selectList(wrapper);
    }

    @Override
    public List<AccessCard> getAccessCardListByCardNo(AccessCardDto accessCardDto) {
        Wrapper wrapper = new EntityWrapper();
        wrapper.eq("i_status", OperationConstant.ZERO);
        if (StringUtils.isNotEmpty(accessCardDto.getCardNo())) {
            wrapper.eq("s_card_no", accessCardDto.getCardNo());
        }
        if (null != accessCardDto.getResidentialId()) {
            wrapper.eq("l_residential_id", accessCardDto.getResidentialId());
        }
        return this.selectList(wrapper);
    }

    @Override
    public List<AccessCard> getAccessCardByUserIdAndType(String userId, int type) {
        Wrapper<AccessCard> wrapper = new EntityWrapper<>();
        wrapper.eq("s_user_id", userId);
        wrapper.eq("i_type", type);
        wrapper.eq("i_status", OperationConstant.ZERO);
        return this.selectList(wrapper);
    }

    @Override
    public List<AccessCard> getAccessCardByIdAndType(long id, int type) {
        Wrapper<AccessCard> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status", OperationConstant.ZERO);
        if (OperationConstant.THREE == type) {
            wrapper.eq("l_residential_id", id);
        }
        if (OperationConstant.TWO == type) {
            wrapper.eq("l_unit_id", id);
        }
        if (OperationConstant.ONE == type) {
            wrapper.eq("l_room_id", id);
        }
        return this.selectList(wrapper);
    }

    @Override
    public boolean deleteAccessCardByUserIdAndType(String userId, int type) {
        List<AccessCard> accessCardList = this.getAccessCardByUserIdAndType(userId, type);
        //未绑定卡 返回成功
        if (null == accessCardList || accessCardList.isEmpty()) {
            return true;
        }
        for (AccessCard accessCard : accessCardList) {
            accessCard.setStatus(OperationConstant.MINUS_ONE);
            if (this.updateById(accessCard)) {
                //删除下发卡号
                this.sendRemoveCard(accessCard);
            }
        }
        return true;
    }

    @Override
    public AccessCard getByCardNoAndXqId(String cardNo, Long xqId) {
        Wrapper<AccessCard> wrapper = new EntityWrapper<>();
        wrapper.eq("s_card_no", cardNo);
        wrapper.eq("l_residential_id", xqId);
        wrapper.notIn("i_status", -1);
        return this.selectOne(wrapper);
    }

    @Override
    public ResultBean<Boolean> addOrUpdateUserCard(AccessCardDto accessCardDto) {
        if (null != accessCardDto.getId()) {
            //删除
            if (StringUtils.isBlank(accessCardDto.getCardNo())) {
                return this.deleteAccessCard(accessCardDto);
            } else {
                return this.updateAccessCard(accessCardDto);
            }
        } else {
            if (StringUtils.isBlank(accessCardDto.getCardNo())) {
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            } else {
                return this.addAccessCard(accessCardDto);
            }
        }
    }

    /**
     * 功能描述:新增或更新（含删除）住户门禁卡（但不下发卡到设备上）
     *
     * @param accessCardDto 门禁卡业务对象
     * @return
     */
    @Override
    public ResultBean<AccessCardDto> simpleAddOrUpdateUserCard(AccessCardDto accessCardDto) {
        if (null != accessCardDto.getId()) {
            //删除
            if (StringUtils.isBlank(accessCardDto.getCardNo())) {
                this.deleteAccessCard(accessCardDto);
                return new ResultBean<>(ResultEnum.SUCCESS, accessCardDto);
            } else {
                //更新
                this.simpleUpdateAccessCard(accessCardDto);
                return new ResultBean<>(ResultEnum.SUCCESS, accessCardDto);
            }
        } else {
            //新增
            if (StringUtils.isBlank(accessCardDto.getCardNo())) {
                return new ResultBean<>(ResultEnum.SUCCESS, accessCardDto);
            } else {
                this.simpleAddAccessCard(accessCardDto);
                return new ResultBean<>(ResultEnum.SUCCESS, accessCardDto);
            }
        }
    }

    @Override
    public ResultBean<AccessCard> findListByPosition(AccessCardDto accessCardDto) {
        Wrapper<AccessCard> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        //根据机构
        if (StringUtils.isNotBlank(accessCardDto.getOrgPosition())) {
            wrapper.like("s_org_position", accessCardDto.getOrgPosition(), SqlLike.RIGHT);
        }
        wrapper.notIn("i_type", OperationConstant.FOUR, OperationConstant.ZERO);
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectList(wrapper));
    }

    @Override
    public ResultBean<Boolean> importAccessCardList(List<AccessCard> list) {
        list = list.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(AccessCard::getCardNo))), ArrayList::new)
        );
        if (this.insertBatch(list, 200)) {
            //批量异步下发卡号，兼容大豪
            this.sendPushCardBatch2(list);
            return new ResultBean<>(ExcelResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ExcelResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean deleteAccessCardByIdAndType(long id, int type) {
        List<AccessCard> accessCardList = this.getAccessCardByIdAndType(id, type);
        //未绑定卡 返回成功
        if (null == accessCardList || accessCardList.isEmpty()) {
            return true;
        }
        for (AccessCard accessCard : accessCardList) {
            accessCard.setStatus(OperationConstant.MINUS_ONE);
            if (this.updateById(accessCard)) {
                //删除下发卡号
                this.sendRemoveCard(accessCard);
            }
        }
        return true;
    }

    @Override
    public ResultBean<Boolean> addOrUpdateServerUserCard(AccessCardDto accessCardDto) {
        if (null != accessCardDto.getId()) {
            if (StringUtils.isBlank(accessCardDto.getCardNo())) {
                //删除
                return this.deleteServerUserCard(accessCardDto);
            } else {
                //修改
                return this.updateServerUserCard(accessCardDto);
            }
        } else {
            if (StringUtils.isBlank(accessCardDto.getCardNo())) {
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            } else {
                //新增
                return this.addServerUserCard(accessCardDto);
            }
        }
    }

    @Override
    public void sendRemoveCard(AccessCard accessCard) {
        //  删除卡号
        DispatchTask dispatchTask = new DispatchTask();
        dispatchTask.setUnitId(accessCard.getUnitId());
        dispatchTask.setXqId(accessCard.getResidentialId());
        dispatchTask.setData(accessCard);
//        this.deviceFeign.removeCard(dispatchTask);
        this.deviceFeign.removePushCard(dispatchTask);
    }

    @Override
    public void sendRemoveCardBatch(List<AccessCardSimpleDto> accessCardSimpleDtoList) {
        this.deviceFeign.removePushCardBatch(accessCardSimpleDtoList);
    }

    @Override
    public void sendPushCard(AccessCard accessCard) {
        //  下发卡号
        DispatchTask dispatchTask = new DispatchTask();
        dispatchTask.setUnitId(accessCard.getUnitId());
        dispatchTask.setXqId(accessCard.getResidentialId());
        dispatchTask.setData(accessCard);
        this.deviceFeign.pushCard(dispatchTask);
    }

    /**
     * @param accessCard
     * @param deviceAccessType
     * @param operType         1：增加，2：更新
     */
    @Override
    public ResultBean<Boolean> sendPushCard(AccessCard accessCard, Integer deviceAccessType, Integer operType) {
        //  下发卡号
        DispatchTask dispatchTask = new DispatchTask();
        dispatchTask.setUnitId(accessCard.getUnitId());
        dispatchTask.setXqId(accessCard.getResidentialId());
        dispatchTask.setData(accessCard);
        if (deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)) {
            return this.deviceFeign.pushCardToUniversalDevices(dispatchTask, operType);
        } else {
            return this.deviceFeign.pushCard(dispatchTask);
        }
    }

    /**
     * @param accessCardDtoList
     */
    @Override
    public void pushCardBatch(List<AccessCardDto> accessCardDtoList) {
        List<AccessCardSimpleDto> list = new ArrayList<>();
        accessCardDtoList.forEach(accessCardDto -> {
            AccessCardSimpleDto dto = new AccessCardSimpleDto();
            dto.setId(accessCardDto.getId());
            dto.setCardNo(accessCardDto.getCardNo());
            dto.setBeginDate(accessCardDto.getBeginDate());
            dto.setEndDate(accessCardDto.getEndDate());
            dto.setResidentialId(accessCardDto.getResidentialId());
            dto.setUnitId(accessCardDto.getUnitId());
            list.add(dto);
        });
        this.deviceFeign.pushCardToUniversalDevicesBatch(list);
    }

    @Override
    public void manualSendPushCardToDevices(ManualPushDevicesTask task) {
        //  下发卡号
        this.deviceFeign.manualPushUserCardToDevices(task);
    }

    /**
     * 修改门禁卡的状态为黑名单状态,同时删除用户信息
     *
     * @param id
     * @return
     */
    @Override
    public ResultBean<Boolean> updateBlackCard(Long id) {
        AccessCard accessCard = this.selectById(id);
        //判断该门禁卡是否是记名，如果是记名则删除用户信息
        if (null != accessCard.getUserId()) {
            accessCard.setUserId(null);
            accessCard.setUserName(null);
            //确定卡的类型
            if (null != accessCard.getResidentialId()) {
                accessCard.setType(OperationConstant.THREE);
            }
            if (null != accessCard.getUnitId()) {
                accessCard.setType(OperationConstant.TWO);
            }
            if (null != accessCard.getRoomId()) {
                accessCard.setType(OperationConstant.ONE);
            }
        }
        accessCard.setIsBlackCard(OperationConstant.ONE);
        accessCard.setCardEnable(OperationConstant.TWO);
        if (this.updateById(accessCard)) {
            //删除下发卡号
            this.sendRemoveCard(accessCard);
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    /**
     * 修改门禁卡的状态取消黑名单状态
     *
     * @param id
     * @return
     */
    @Override
    public ResultBean<Boolean> cancelBlackCard(Long id) {
        AccessCard accessCard = new AccessCard();
        accessCard.setId(id);
        accessCard.setIsBlackCard(OperationConstant.ZERO);
        return new ResultBean<>(ResultEnum.SUCCESS, this.updateById(accessCard));
    }

    /**
     * 更新数据
     * @param accessCard
     * @return
     */
    @Override
    public ResultBean<Boolean> updateAccessCardById(AccessCard accessCard){
        if (this.updateById(accessCard)){
            //下发卡片
            this.sendPushCard(accessCard);
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    /**
     * 更新数据
     * @param accessCardList
     * @return
     */
    @Override
    public ResultBean<Boolean> updateAccessCardList(List<AccessCard> accessCardList){
        return new ResultBean<>(ResultEnum.SUCCESS,this.updateBatchById(accessCardList));
    }
    public List<AccessCard> findAccessCardByUserIdAndUserName(String userId, String userName) {
        Wrapper<AccessCard> wrapper = new EntityWrapper<>();
        wrapper.eq("s_user_id", userId);
        wrapper.eq("s_user_name", userName);
        wrapper.eq("i_status", OperationConstant.ZERO);
        return this.selectList(wrapper);
    }


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

    /**
     * 功能描述:批量导入异步下发卡
     *
     * @param list 导入对象集合
     */
    @Async
    public void sendPushCardBatch(List<AccessCard> list) {
        int size = list.size();
        for (int i = 0; i < size; i++) {
            AccessCard accessCard = list.get(i);
            //  下发门禁卡号
            DispatchTask task = new DispatchTask();
            task.setXqId(accessCard.getResidentialId());
            task.setUnitId(accessCard.getUnitId());
            task.setData(accessCard);
            this.deviceFeign.pushCard(task);
        }
    }

    /**
     * 功能描述:批量导入异步下发卡，兼容大豪设备
     *
     * @param list 导入对象集合
     */
    @Async
    public void sendPushCardBatch2(List<AccessCard> list) {
        int size = list.size();
        Map<Long, List<AccessCard>> dhMap = new HashMap<>();
        for (int i = 0; i < size; i++) {
            AccessCard accessCard = list.get(i);
            //查出该卡即将发送到的大豪设备
            DeviceVO deviceVO = new DeviceVO();
            deviceVO.setXqId(accessCard.getResidentialId());
            deviceVO.setUnitId(accessCard.getUnitId());
            deviceVO.setFactory(DeviceConstants.DEVICE_FACTORY_DAHAO);
            deviceVO.setInOrNotIn(OperationConstant.ONE);
            List<Device> dhDevices = this.deviceFeign.getListByCondition(deviceVO);
            dhDevices.forEach(device -> {
                if (dhMap.containsKey(device.getId())) {
                    List<AccessCard> accessCards = dhMap.get(device.getId());
                    if (accessCards != null) {
                        accessCards.add(accessCard);
                    } else {
                        accessCards = new ArrayList<>();
                        accessCards.add(accessCard);
                        dhMap.put(device.getId(), accessCards);
                    }
                } else {
                    List<AccessCard> accessCards = new ArrayList<>();
                    accessCards.add(accessCard);
                    dhMap.put(device.getId(), accessCards);
                }
            });
        }
        for (int i = 0; i < size; i++) {
            AccessCard accessCard = list.get(i);
            // 下发门禁卡号，不包含大豪设备
            DispatchTask task = new DispatchTask();
            task.setXqId(accessCard.getResidentialId());
            task.setUnitId(accessCard.getUnitId());
            task.setFactory(DeviceConstants.DEVICE_FACTORY_DAHAO); //表示排除大豪的设备
            task.setData(accessCard);
            this.deviceFeign.pushCardToNoDh(task);
        }
        if (dhMap.keySet().size() > 0) {
            for (Long key : dhMap.keySet()) {
                //  下发门禁卡号到大豪设备
                Device dhDevice = deviceFeign.getEntityById(key);
                DispatchTask task = new DispatchTask();
                task.setSerialNumber(dhDevice.getSerialNumber());
                task.setUnitId(dhDevice.getUnitId());
                task.setXqId(dhDevice.getXqId());
                task.setSerialNumber(dhDevice.getSerialNumber());
                task.setData(dhMap.get(key));
                this.deviceFeign.pushCardsToDHDevice(task);
            }
        }
    }

    /**
     * 功能描述:删除服务人员卡号
     *
     * @param accessCardDto
     * @return ResultBean<Boolean>
     */
    private ResultBean<Boolean> deleteServerUserCard(AccessCardDto accessCardDto) {
        List<AccessCard> accessCardList = this.getAccessCardByUserIdAndType(accessCardDto.getUserId(), accessCardDto.getType());
        //未找到卡
        if (null == accessCardList) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        for (AccessCard accessCard : accessCardList) {
            accessCard.setStatus(OperationConstant.MINUS_ONE);
            if (this.updateById(accessCard)) {
                this.sendRemoveCard(accessCard);
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    /**
     * 功能描述:更新服务人员卡号
     *
     * @param accessCardDto
     * @return ResultBean<Boolean>
     */
    private ResultBean<Boolean> updateServerUserCard(AccessCardDto accessCardDto) {
        List<AccessCard> accessCardList = this.getAccessCardByUserIdAndType(accessCardDto.getUserId(), accessCardDto.getType());
        //未找到卡
        if (null == accessCardList) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        for (AccessCard accessCard : accessCardList) {
            //当前时间
            Date currentBeginDate = accessCardDto.getBeginDate();
            Date currentEndDate = accessCardDto.getEndDate();
            //结束时间
            Date oldBeginDate = accessCard.getBeginDate();
            Date oldEndDate = accessCard.getEndDate();
            //判断时间是否改变
            boolean isUpdateTime = false;
            if (currentBeginDate != null && currentEndDate != null && oldBeginDate != null && oldEndDate != null) {
                if (currentBeginDate.compareTo(oldBeginDate) != 0 || currentEndDate.compareTo(oldEndDate) != 0) {
                    isUpdateTime = true;
                }
            }
            if ((!accessCardDto.getCardNo().equals(accessCard.getCardNo())) || isUpdateTime) {
                AccessCard noNameCard = new AccessCard();
                BeanUtils.copyProperties(accessCard, noNameCard);
                noNameCard.setUserId(null);//变成不记名卡,新增一张不记名卡
                noNameCard.setUserName(null);
                if (noNameCard.getRoomId() != null) {
                    noNameCard.setType(OperationConstant.ONE);
                } else if (noNameCard.getUnitId() != null) {
                    noNameCard.setType(OperationConstant.TWO);
                } else if (noNameCard.getResidentialId() != null) {
                    noNameCard.setType(OperationConstant.THREE);
                }
                if (this.updateById(noNameCard)) {
                    accessCard.setCardNo(accessCardDto.getCardNo());
                    accessCard.setBeginDate(accessCardDto.getBeginDate());
                    accessCard.setEndDate(accessCardDto.getEndDate());
                    accessCard.setCardEnable(OperationConstant.ONE);
                    accessCard.setId(null);
                    if (this.insert(accessCard)) { //新增一张记名卡，然后下发
                        //下发新卡号
                        this.sendPushCard(accessCard, DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.TWO);
                        return new ResultBean<>(ResultEnum.SUCCESS, true);
                    }
                }
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    /**
     * 功能描述:添加服务人员卡号
     *
     * @param accessCardDto
     * @return ResultBean<Boolean>
     */
    private ResultBean<Boolean> addServerUserCard(AccessCardDto accessCardDto) {
        List<ServerUserDetail> detailList = accessCardDto.getDetailList();
        accessCardDto.setCreateDate(new Date());
        accessCardDto.setStatus(OperationConstant.ZERO);
        //设置卡为启用状态
        accessCardDto.setCardEnable(OperationConstant.ONE);
        if (null != detailList && !detailList.isEmpty()) {
            for (ServerUserDetail serverUserDetail : detailList) {
                Unit unit = this.unitServiceInterface.findUnitById(serverUserDetail.getUnitId());
                accessCardDto.setUnitId(unit.getId());
                accessCardDto.setUnitName(unit.getName());
                accessCardDto.setOrgPosition(unit.getOrgPosition());
                accessCardDto.setRootOrgId(unit.getRootOrgId());
                if (this.insert(accessCardDto)) {
                    //  下发卡号
                    Integer deviceAccessType = accessCardDto.getDeviceAccessType();
                    if (deviceAccessType != null && deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)) {
                        this.sendPushCard(accessCardDto, deviceAccessType, OperationConstant.ONE);
                    } else {
                        this.sendPushCard(accessCardDto);
                    }
                }
            }
        } else {
            if (this.insert(accessCardDto)) {
                //  下发卡号
                Integer deviceAccessType = accessCardDto.getDeviceAccessType();
                if (deviceAccessType != null && deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)) {
                    this.sendPushCard(accessCardDto, deviceAccessType, OperationConstant.ONE);
                } else {
                    //  下发卡号
                    this.sendPushCard(accessCardDto);
                }
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    /**
     * 根据小区ID，获取小区下的所有设备
     *
     * @param xqIdList
     * @return
     */
    private List<Long> getDeviceIdByXqs(List<Long> xqIdList) {
        List<Long> deviceIdList = new ArrayList<>();
        xqIdList.forEach(xqId -> {
            List<Device> deviceList = this.deviceFeign.getListByXqId(xqId);
            deviceList.forEach(device -> deviceIdList.add(device.getId()));
        });
        return deviceIdList;
    }

    /**
     * 根据单元ID，获取单元下的所有设备
     *
     * @param unitIdList
     * @return
     */
    private List<Long> getDeviceIdByUnits(List<Long> unitIdList) {
        List<Device> deviceList = this.deviceFeign.getListByUnitIds(unitIdList);
        return deviceList.stream().map(Device::getId).collect(Collectors.toList());
    }



}
