package com.ruoyi.task.bill;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.iot.domain.IotDeviceInfo;
import com.ruoyi.iot.service.IotService;
import com.ruoyi.ss.device.domain.enums.DeviceOnlineStatus;
import com.ruoyi.ss.suit.domain.enums.SuitFeeType;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.dto.EndUseDTO;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.system.domain.enums.config.ConfigKey;
import com.ruoyi.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author wjh
 * 2024/9/19
 */
@Component
@Slf4j
public class BillMonitorTask {

    @Autowired
    private TransactionBillService transactionBillService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IotService iotService;

    /**
     * 关闭低功率的订单
     */
    public void autoCloseLowPower() {
        // 获取关闭冷却时间
        int cd = sysConfigService.getInt(ConfigKey.ORDER_AUTO_CLOSE_CD);
        LocalDateTime createTimeEnd = LocalDateTime.now().minusMinutes(cd); // 获取冷却时间之前的时间

        // 获取开启了低功率关闭，且未结束的电量订单
        TransactionBillQuery query = new TransactionBillQuery();
        query.setSuitEnableLowPowerClose(true);
        query.setType(TransactionBillType.RECHARGE.getType());
        query.setStatusList(TransactionBillStatus.canClose());
        query.setCreateTimeEnd(createTimeEnd);
        query.setIsFinished(false);
        query.setSuitFeeTypes(SuitFeeType.rechargeCountList());
        List<TransactionBillVO> list = transactionBillService.selectSmTransactionBillList(query);

        // 从OneNet获取设备信息
        if (CollectionUtils.isEmptyElement(list)) {
            log.info("无低功率订单");
            return;
        }
        for (TransactionBillVO bill : list) {
            if (bill.getSuitLowPower() == null) {
                log.warn("关闭低功率订单时，订单最低功率值为空:{}", bill.getBillNo());
                continue;
            }
            try {
                // 判断设备是否在线
                DeviceOnlineStatus online = iotService.getOnlineStatus(bill);
                if (!DeviceOnlineStatus.ONLINE.equals(online)) {
                    log.warn("关闭低功率订单{}时，设备未在线", bill.getBillNo());
                    continue;
                }

                IotDeviceInfo deviceInfo = iotService.getDeviceInfo(bill);
                // 判断是否低功率，若低于指定功率，则关闭订单
                if (deviceInfo != null && deviceInfo.getP() != null && deviceInfo.getP().compareTo(bill.getSuitLowPower()) < 0) {
                    EndUseDTO dto = new EndUseDTO();
                    dto.setBillId(bill.getBillId());
                    dto.setTotalEle(deviceInfo.getW());
                    transactionBillService.endUse(dto, true);
                }
            } catch (Exception e) {
                log.warn("关闭低功率订单{}出错：{}", bill.getBillNo(), e.getMessage());
            }
        }
    }

    /**
     * 更新电量订单结束时间
     */
    public void updateEleFinishTime(String startTime) {
        // 查询指定时间后已结束的电量订单
        TransactionBillQuery query = new TransactionBillQuery();
        query.setType(TransactionBillType.RECHARGE.getType());
        query.setCreateTimeStart(DateUtils.toLocalDateTime(startTime));
        query.setIsFinished(true);
        query.setSuitFeeType(SuitFeeType.COUNT.getType());
        query.setIsNullSuitEndTime(true);
        List<TransactionBillVO> list = transactionBillService.selectSmTransactionBillList(query);

        if (CollectionUtils.isEmptyElement(list)) {
            log.info("暂无结束的电量订单");
            return;
        }
        // 更新结束时间
        List<Long> billIds = list.stream().map(TransactionBillVO::getBillId).filter(Objects::nonNull).collect(Collectors.toList());
        int update = transactionBillService.batchUpdateSuitEndTime(billIds, LocalDateTime.now());
        log.info("更新结束时间: update= {}" , update);
    }

}
