package com.usky.eg.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usky.common.core.exception.BusinessException;
import com.usky.eg.domain.EgDeviceHeartbeat;
import com.usky.eg.mapper.EgDeviceHeartbeatMapper;
import com.usky.eg.service.EgDeviceHeartbeatService;
import com.usky.common.mybatis.core.AbstractCrudService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 门禁设备心跳表 服务实现类
 * </p>
 *
 * @author fhs
 * @since 2026-02-03
 */
@Service
public class EgDeviceHeartbeatServiceImpl extends AbstractCrudService<EgDeviceHeartbeatMapper, EgDeviceHeartbeat> implements EgDeviceHeartbeatService {

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void heartbeatEscalation(EgDeviceHeartbeat heartbeat) {
        if (StringUtils.isBlank(heartbeat.getDeviceCode())) {
            throw new BusinessException("设备编码不能为空!");
        }
        if (StringUtils.isBlank(heartbeat.getIpAddr())) {
            throw new BusinessException("设备IP不能为空!");
        }
        if (heartbeat.getCreateTime() == null) {
            heartbeat.setCreateTime(LocalDateTime.now());
        }
        if (heartbeat.getDeviceType() == null) {
            throw new BusinessException("设备类型不能为空!");
        }

        // 查询是否存在该设备的心跳记录
        LambdaQueryWrapper<EgDeviceHeartbeat> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EgDeviceHeartbeat::getDeviceCode, heartbeat.getDeviceCode());
        EgDeviceHeartbeat existingHeartbeat = baseMapper.selectOne(queryWrapper);
        
        if (existingHeartbeat != null) {
            // 如果存在，更新记录
            heartbeat.setId(existingHeartbeat.getId());
            baseMapper.updateById(heartbeat);
        } else {
            // 如果不存在，插入新记录
            baseMapper.insert(heartbeat);
        }
    }

    /**
     * 更新设备状态定时任务服务接口
     * 从心跳表中获取设备状态并同步更新
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEgDeviceStatus() {
        try {
            LocalDateTime now = LocalDateTime.now();
            
            // 1. 查询所有当前状态为在线的心跳记录
            LambdaQueryWrapper<EgDeviceHeartbeat> heartbeatQueryWrapper = Wrappers.lambdaQuery();
            heartbeatQueryWrapper.eq(EgDeviceHeartbeat::getDeviceStatus, 1);
            List<EgDeviceHeartbeat> heartbeatList = baseMapper.selectList(heartbeatQueryWrapper);

            // 2. 遍历在线记录，若心跳时间超过5分钟则更新为离线
            for (EgDeviceHeartbeat heartbeat : heartbeatList) {
                LocalDateTime heartbeatTime = heartbeat.getCreateTime();
                if (heartbeatTime != null && !heartbeatTime.isAfter(now.minusMinutes(5))) {
                    // 心跳超时，更新心跳表中的状态为离线
                    LambdaUpdateWrapper<EgDeviceHeartbeat> updateWrapper = Wrappers.lambdaUpdate();
                    updateWrapper.set(EgDeviceHeartbeat::getDeviceStatus, 0)
                            .eq(EgDeviceHeartbeat::getId, heartbeat.getId());
                    baseMapper.update(null, updateWrapper);
                }
            }
        } catch (Exception e) {
            // 定时任务失败不影响主流程，记录日志即可
            throw new BusinessException("更新设备状态失败：" + (e.getMessage() != null ? e.getMessage() : "未知错误"));
        }
    }
}