package com.agri.quartz.task;

import com.agri.framework.interceptor.FrontendControlHandler;
import com.agri.system.domain.SysMessage;
import com.agri.system.service.AgriService;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.service.ISysAgriInfoService;
import com.agri.system.service.ISysDtuDataService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
public class AgriTempTask {

    private static final Logger log = LoggerFactory.getLogger(AgriTempTask.class);

    @Autowired
    private ISysDtuDataService dtuDataService;

    @Autowired
    private ISysAgriInfoService agriInfoService;

    private static final String LOCK_KEY = "lock:check:temp:push";
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Value("${spring.mqtt.dtu-ctl-lock-ttl:60}")
    private int lockTtl;

    @Autowired
    private AgriService agriService;

    @Resource
    private FrontendControlHandler frontendControlHandler;

    public void checkTempStatus() {
        if (!acquireLock()) {
            return;
        }
        try {
            List<SysAgriInfo> agriInfos = agriInfoService.findAgriByUser(new SysAgriInfo());
            List<String> imeiList = agriService.queryAllGreenhouseImei(agriInfos);
            if (CollectionUtils.isEmpty(imeiList)) {
                log.info("大棚表无数据，结束推送");
                return;
            }
            Map<String, Object> latestDataMap = queryLatestDtuData(imeiList);
            List<SysAgriInfo> offlineDevices = findOfflineDevices(agriInfos, latestDataMap);
            List<SysMessage> messages = agriService.saveMessage(offlineDevices);
            // 推送离线告警
            frontendControlHandler.sendAlarmMessage(messages);
        } catch (Exception e) {
            log.error("设备在线状态推送任务异常", e);
        } finally {
            releaseLock();
        }
    }
    // 获取分布式锁
    private boolean acquireLock() {
        Boolean lockSuccess = stringRedisTemplate.opsForValue()
                .setIfAbsent(LOCK_KEY, "agriTempTask", lockTtl, TimeUnit.SECONDS);
        if (lockSuccess == null) {
            log.error("获取分布式锁失败：Redis连接异常");
            return false;
        }
        if (!lockSuccess) {
            log.debug("其他节点正在执行，跳过本次推送");
            return false;
        }
        return true;
    }

    // 释放分布式锁
    private void releaseLock() {
        stringRedisTemplate.delete(LOCK_KEY);
    }


    // 查询所有大棚的最新温湿度数据
    private Map<String, Object> queryLatestDtuData(List<String> imeiList) {
        List<Map<String, Object>> dtuDataList = dtuDataService.getLastDtuDataByImeiList(imeiList);
        Map<String, Object> dataMap = new HashMap<>();
        if (CollectionUtils.isEmpty(dtuDataList)) {
            return dataMap;
        }
        for (Map<String, Object> item : dtuDataList) {
            Object imei = item.get("imei");
            if (imei != null) {
                dataMap.put(imei.toString(), item);
            }
        }
        return dataMap;
    }

    // 查找离线设备
    private List<SysAgriInfo> findOfflineDevices(List<SysAgriInfo> agriInfos,
                                                 Map<String, Object> latestDataMap) {
        List<SysAgriInfo> offlineList = new ArrayList<>();
        for (SysAgriInfo agriInfo : agriInfos) {
            if (!latestDataMap.containsKey(agriInfo.getImei())) {
                agriInfo.setTitle("温度离线");
                agriInfo.setMsg("怀疑温度离线！请检查");
                offlineList.add(agriInfo);
                log.info("设备{} 不存在温湿度数据", agriInfo.getImei());
            }
        }
        return offlineList;
    }

}