package com.yida.data.device.studentCard.service.impl;


import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.card.EduStudentCard;
import com.yida.data.common.core.entity.card.EduStudentCardFence;
import com.yida.data.common.core.entity.card.EduStudentCardFenceJimi;
import com.yida.data.common.core.entity.card.EduStudentCardFenceStudent;
import com.yida.data.common.core.entity.card.EduStudentCardJimiAccount;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.constant.LockPrefixConstant;
import com.yida.data.common.core.enums.CardDeviceEnum;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.common.core.utils.Asserts;
import com.yida.data.device.studentCard.mapper.EduStudentCardFenceMapper;
import com.yida.data.device.studentCard.mapper.EduStudentCardJimiAccountMapper;
import com.yida.data.device.studentCard.mapper.EduStudentCardMapper;
import com.yida.data.device.studentCard.service.EduStudentCardFenceJimiService;
import com.yida.data.device.studentCard.service.EduStudentCardFenceService;
import com.yida.data.device.studentCard.service.EduStudentCardFenceStudentService;
import com.yida.data.device.studentCard.utils.JimiUtils;
import com.yida.data.device.vo.studentCard.FenceListVO;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * 电子学生证-电子围栏主信息 Service实现
 *
 * @author zhanghaijun
 * @date 2021-08-04 15:07:58
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class EduStudentCardFenceServiceImpl extends ServiceImpl
    <EduStudentCardFenceMapper, EduStudentCardFence> implements EduStudentCardFenceService {

    private final EduStudentCardFenceJimiService eduStudentCardFenceJimiService;
    private final EduStudentCardFenceStudentService eduStudentCardFenceStudentService;
    private final EduStudentCardJimiAccountMapper eduStudentCardJimiAccountMapper;
    private final EduStudentCardMapper eduStudentCardMapper;

    private final JimiUtils jimiUtil;
    private final RedisService redisService;

    @Override
    public void saveFence(EduStudentCardFence fence) {
        EduStudentCard studentCard = eduStudentCardMapper.selectOne(Wrappers.lambdaQuery(new EduStudentCard())
            .eq(EduStudentCard::getSchoolId, fence.getSchoolId())
            .eq(EduStudentCard::getImei, fence.getImei()));
        Asserts.isNotNull(studentCard, "学生证不存在，请刷新后重试");
        Asserts.isTrue(redisService.hasKey(CachePrefixConstant.DEVICE_CARD_ONLINE + studentCard.getImei()), "设备离线中，请稍后重试");
        Asserts.isTrue(baseMapper.countFenceNum(fence.getImei()) < 5, "可创建围栏数已达上限");
        String mcType = studentCard.getMcType();
        // 保存围栏主信息
        saveOrUpdate(fence);
        if (mcType.contains(CardDeviceEnum.JIMI.getValue())) {
            // 删除原有的几米围栏信息
            List<EduStudentCardFenceJimi> delJimiList = null;
            if (fence.getId() != null) {
                delJimiList = eduStudentCardFenceJimiService.list(Wrappers.lambdaQuery(new EduStudentCardFenceJimi())
                    .eq(EduStudentCardFenceJimi::getFenceId, fence.getId()));
                eduStudentCardFenceJimiService.remove(Wrappers.lambdaQuery(new EduStudentCardFenceJimi())
                    .eq(EduStudentCardFenceJimi::getFenceId, fence.getId()));
            }
            // 添加几米平台围栏  保存对应关系
            List<EduStudentCardFenceJimi> saveJimi = new ArrayList<>();
            // 加锁
            Asserts.isTrue(redisService.tryLock(LockPrefixConstant.JIMI_FENCE_LOCK, 5000L), "创建失败，请稍后重试");
            // 获取几米账号
            EduStudentCardJimiAccount account = eduStudentCardJimiAccountMapper.getUseAccount(1);
            Asserts.isNotNull(account, "创建失败，请稍后重试");
            // 开始创建围栏
            try {
                // 家长创建围栏
                EduStudentCardFenceJimi jimiFence = new EduStudentCardFenceJimi();
                jimiFence.setJimiFenceName(StrUtil.uuid());
                jimiFence.setJimiFenceId(jimiUtil.createPlatFence(studentCard.getImei(), jimiFence.getJimiFenceName(),
                    EduStudentCardFence.PLAT_ALARM_TYPE.get(fence.getAlarmType()), fence.getLng(), fence.getLat(),
                    fence.getRadius(), account));
                jimiFence.setFenceId(fence.getId());
                jimiFence.setType(1);
                jimiFence.setJimiAccountId(account.getId());
                saveJimi.add(jimiFence);
                // 更新账号围栏数量
                eduStudentCardJimiAccountMapper.updateJimiAccountFenceNum(account.getId(), 1);
                // 几米围栏
                eduStudentCardFenceJimiService.saveBatch(saveJimi);
            } catch (Exception e) {
                log.error("创建围栏失败", e);
                throw new FebsException("创建失败");
            } finally {
                // 释放锁
                redisService.unlock(LockPrefixConstant.JIMI_FENCE_LOCK);
            }
            // 保存学生与围栏关系
            EduStudentCardFenceStudent fenceStudent = new EduStudentCardFenceStudent();
            fenceStudent.setStudentId(studentCard.getStudentId());
            fenceStudent.setFenceId(fence.getId());
            eduStudentCardFenceStudentService.save(fenceStudent);
            // 删除几米围栏
            if (CollUtil.isNotEmpty(delJimiList)) {
                for (EduStudentCardFenceJimi jimi : delJimiList) {
                    jimiUtil.delPlatFence(jimi.getJimiFenceId(), account);
                }
                eduStudentCardJimiAccountMapper.updateJimiAccountFenceNum(account.getId(), -delJimiList.size());
            }
        } else {
            // 保存学生与围栏关系
            EduStudentCardFenceStudent fenceStudent = new EduStudentCardFenceStudent();
            fenceStudent.setStudentId(studentCard.getStudentId());
            fenceStudent.setFenceId(fence.getId());
            eduStudentCardFenceStudentService.save(fenceStudent);
        }
        redisService.del(CachePrefixConstant.DEVICE_CARD_FENCE_DATA + fence.getImei());
    }

    @Override
    public List<FenceListVO> listFence(Long schoolId, String imei, Integer createType, String name) {
        return baseMapper.listFence(schoolId, imei, createType, name);
    }

    @Override
    public void delFence(List<Long> ids) {
        List<EduStudentCardFenceJimi> jimiList =
            eduStudentCardFenceJimiService.list(Wrappers.lambdaQuery(new EduStudentCardFenceJimi())
                .in(EduStudentCardFenceJimi::getFenceId, ids));
        for (EduStudentCardFenceJimi fenceJimi : jimiList) {
            EduStudentCardJimiAccount account = eduStudentCardJimiAccountMapper
                .selectById(fenceJimi.getJimiAccountId());
            jimiUtil.delPlatFence(fenceJimi.getJimiFenceId(), account);
            eduStudentCardJimiAccountMapper.updateJimiAccountFenceNum(account.getId(), -1);
        }
        eduStudentCardFenceJimiService
            .remove(Wrappers.lambdaQuery(new EduStudentCardFenceJimi()).in(EduStudentCardFenceJimi::getFenceId, ids));
        eduStudentCardFenceStudentService.remove(
            Wrappers.lambdaQuery(new EduStudentCardFenceStudent()).in(EduStudentCardFenceStudent::getFenceId, ids));
        List<EduStudentCard> card = baseMapper.listCardByFence(ids);
        removeByIds(ids);
        redisService
            .del(card.stream().map(x -> CachePrefixConstant.DEVICE_CARD_FENCE_DATA + x.getImei()).toArray(String[]::new));
    }
}
