package com.kym.service.impl;

import com.kym.entity.MonitorLog;
import com.kym.entity.WashDevice;
import com.kym.entity.common.RedisKeys;
import com.kym.service.*;
import com.kym.service.awoara.AwoaraService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * 设备健康探测服务实现
 *
 * @author skyline
 */
@Slf4j
@Service
public class DeviceHealthProbeServiceImpl implements DeviceHealthProbeService {

    private final WashDeviceService washDeviceService;
    private final MonitorLogService monitorLogService;
    private final AwoaraService awoaraService;
    private final StringRedisTemplate stringRedisTemplate;
    private final FaultNotificationService faultNotificationService;

    public DeviceHealthProbeServiceImpl(WashDeviceService washDeviceService,
                                        MonitorLogService monitorLogService,
                                        AwoaraService awoaraService,
                                        StringRedisTemplate stringRedisTemplate,
                                        FaultNotificationService faultNotificationService) {
        this.washDeviceService = washDeviceService;
        this.monitorLogService = monitorLogService;
        this.awoaraService = awoaraService;
        this.stringRedisTemplate = stringRedisTemplate;
        this.faultNotificationService = faultNotificationService;
    }

    @Override
    public boolean probeAndRecover(WashDevice device) {
        try {
            awoaraService.queryState(device.getProductKey(), device.getDeviceName());
            log.info("设备探测成功，触发恢复: deviceId={}, deviceName={}", device.getId(), device.getDeviceName());
            recoverDevice(device);
            return true;
        } catch (Exception e) {
            log.debug("设备探测失败（仍离线）: deviceId={}, deviceName={}, error={}",
                    device.getId(), device.getDeviceName(), e.getMessage());
            return false;
        }
    }

    private void recoverDevice(WashDevice device) {
        var deviceId = device.getId().toString();
        var deviceName = device.getDeviceName();

        // 更新设备状态为空闲
        washDeviceService.lambdaUpdate()
                .set(WashDevice::getState, WashDevice.STATE_空闲)
                .eq(WashDevice::getId, device.getId())
                .update();

        // 清除离线标记
        stringRedisTemplate.delete(RedisKeys.OFFLINE + deviceId);

        // 恢复监控日志
        var unrecoveredLog = monitorLogService.lambdaQuery()
                .eq(MonitorLog::getSn, deviceName)
                .eq(MonitorLog::getIsRecover, MonitorLog.IS_RECOVER_未恢复)
                .orderByDesc(MonitorLog::getOfflineTime)
                .last("limit 1")
                .one();
        if (unrecoveredLog != null) {
            monitorLogService.lambdaUpdate()
                    .set(MonitorLog::getIsRecover, MonitorLog.IS_RECOVER_已恢复)
                    .set(MonitorLog::getRecoverTime, LocalDateTime.now())
                    .eq(MonitorLog::getId, unrecoveredLog.getId())
                    .update();
        }

        // 恢复故障记录并发送通知
        faultNotificationService.handleOnlineRecovery(device.getStationId(), deviceName);
    }
}
