package com.ruoyi.system.iot.service.impl;

import com.ruoyi.common.utils.NumberUtils;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.ss.device.domain.enums.DeviceOutageWay;
import com.ruoyi.system.iot.constants.ReceiveConstants;
import com.ruoyi.system.iot.domain.CurrentDatastream;
import com.ruoyi.system.iot.domain.CurrentDeviceData;
import com.ruoyi.system.iot.domain.IotDeviceInfo;
import com.ruoyi.system.iot.service.IotConverter;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author qzz
 * 2024/9/29
 */
@Service
public class IotConverterImpl implements IotConverter {
    @Override
    public IotDeviceInfo toIotDeviceInfo(CurrentDeviceData data1, CurrentDeviceData data2) {
        if (data1 == null && data2 == null) {
            return null;
        }

        // 获取数据点，让不为空的排在前面
        List<CurrentDatastream> ds1 = data1 == null ? data2.getDatastreams() : data1.getDatastreams();
        List<CurrentDatastream> ds2 = data2 == null ? data1.getDatastreams() : data2.getDatastreams();

        String mac = null;
        try {
            mac = data1.getTitle();
        } catch (Exception e) {
            mac = data2.getTitle();
        }

        if (CollectionUtils.isNotEmptyElement(ds1)) {
            return this.toIotDeviceInfo(ds1, ds2, mac);
        } else if (CollectionUtils.isNotEmptyElement(ds2)) {
            return this.toIotDeviceInfo(ds2, ds1, mac);
        }

        return null;
    }

    private IotDeviceInfo toIotDeviceInfo(List<CurrentDatastream> ds1, List<CurrentDatastream> ds2, String mac) {
        if (CollectionUtils.isEmptyElement(ds1) && CollectionUtils.isEmptyElement(ds2)) {
            return null;
        }

        IotDeviceInfo device = IotDeviceInfo.newDefaultInstance();
        device.setMac(mac);

        for (CurrentDatastream stream : ds1) {
            String id = stream.getId(); // 数据点ID
            String value = stream.getValue().toString();    // 数据点取值，取最新的值
            Date at = stream.getAt();
            if (ds2 != null) {
                CurrentDatastream stream2 = ds2.stream().filter(item -> Objects.equals(item.getId(), stream.getId())).findFirst().orElse(null);
                if (stream2 != null && stream2.getAt().getTime() > stream.getAt().getTime()) {
                    value = stream2.getValue().toString();
                    at = stream2.getAt();
                }
            }

            switch (id) {
                case ReceiveConstants.DS_V:
                    device.setV(NumberUtils.nonNullDecimal(value));
                    break;
                case ReceiveConstants.DS_P:
                    device.setP(NumberUtils.nonNullDecimal(value));
                    break;
                case ReceiveConstants.DS_A:
                    device.setA(NumberUtils.nonNullDecimal(value));
                    break;
                case ReceiveConstants.DS_W:
                    device.setW(NumberUtils.nonNullDecimal(value).divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP));
                    break;
                case ReceiveConstants.DS_S:
                    device.setS(Integer.valueOf(value).toString());
                    break;
                case ReceiveConstants.DS_M:
                    device.setM(NumberUtils.nonNullDecimal(value).divide(new BigDecimal(1000),  2, RoundingMode.HALF_UP));
                    break;
                case ReceiveConstants.DS_SET:
                    DeviceOutageWay deviceOutageWay = DeviceOutageWay.parse(value);
                    device.setSet(deviceOutageWay.getValue());
                    break;
                case ReceiveConstants.DS_TIME:
                    device.setTime(NumberUtils.nonNullDecimal(value));
                    device.setAt(at);
                    break;
                case ReceiveConstants.DS_FW:
                    device.setModel(value);
                    break;
                case ReceiveConstants.DS_SSID:
                    device.setWifi(value);
                    break;
                case ReceiveConstants.DS_VER:
                    device.setVersion(value);
                    break;
                default:
                    break;
            }
        }
        return device;
    }
}
