package com.xy.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xy.collections.list.JArrayList;
import com.xy.collections.list.JList;
import com.xy.entity.MqttCommand;
import com.xy.entity.SysDictRedis;
import com.xy.service.MqttServiceImpl;
import com.xy.sys.EnumDataClearSize;
import com.xy.utils.DataTime;
import com.xy.utils.JobUtils;
import com.xy.utils.RecursionUtils;
import com.xy.utils.SysDictUtils;
import com.xy.utils.enums.MqttCommandStatusEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * 指令定时器
 */
@Slf4j
@Component
@AllArgsConstructor
public class MqttCommandJob {

    private MqttServiceImpl mqttService;

    /**
     * 指令数据清除
     *
     * @return
     */
    @XxlJob("commandClean")
    public ReturnT<String> commandClean() {
        //指令保留的天数
        SysDictRedis sysDictRedis = SysDictUtils.get(EnumDataClearSize.Code.CODE.getCode(), EnumDataClearSize.MQTT_COMMAND_DAY.getCode());
        Integer saveDay = Integer.valueOf(sysDictRedis.getValue());
        String beginTime = DataTime.getStringAround(0, 0, (~(saveDay - 1)), 0, 0, 0);
        LambdaQueryWrapper<MqttCommand> lambdaQueryWrapper = new LambdaQueryWrapper<MqttCommand>()
                .le(MqttCommand::getSendTime, beginTime)
                .last("limit 10000");
        RecursionUtils.recursion(current -> {
            boolean remove = mqttService.remove(lambdaQueryWrapper);
            if (!remove) {
                return false;
            }
            return true;
        });
        return ReturnT.SUCCESS;
    }

    /**
     * 指令执行超时校验
     *
     * @return
     */
    @XxlJob("commandDataCloud")
    public ReturnT<String> commandDataCloud() {
        //指令执行超时分钟数
        SysDictRedis sysDictRedis = SysDictUtils.get(EnumDataClearSize.Code.CODE.getCode(), EnumDataClearSize.MQTT_COMMAND_CLOUD.getCode());
        Integer jobParam = JobUtils.getPrams().gtInt();
        Integer threshold = jobParam != null ? jobParam
                : sysDictRedis != null ? Integer.valueOf(sysDictRedis.getValue())
                : 10;
        LambdaQueryWrapper<MqttCommand> lambdaQueryWrapper = new LambdaQueryWrapper<MqttCommand>()
                .in(MqttCommand::getStatus, Arrays.asList(MqttCommandStatusEnum.COMMAND_SEND.getKey()))
                .le(MqttCommand::getSendTime, DataTime.getStringAround(0, 0, 0, 0, threshold, 0));
        List<MqttCommand> mqttCommands = mqttService.list(lambdaQueryWrapper);
        if (mqttCommands.size() == 0) {
            return ReturnT.SUCCESS;
        }
        JList<MqttCommand> list = new JArrayList<>(mqttCommands);
        //发送但没有回执的数据
        JList<MqttCommand> sends = list.filter().eq(MqttCommand::getStatus, MqttCommandStatusEnum.COMMAND_SEND.getKey()).list();
        sends.forEach(mqttCommand -> mqttCommand.setStatus(Integer.parseInt(MqttCommandStatusEnum.COMMAND_EXC_TIMEOUT.getKey())));
        mqttService.updateBatchById(sends);
        log.info("已处理发送但没有回调通知的指令数据：{}条", sends.size());
        return ReturnT.SUCCESS;
    }
}
