package com.ruoyi.ems.record.service.impl;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.ems.record.mapper.TWTempertureDataMapper;
import com.ruoyi.ems.record.domain.TWTempertureData;
import com.ruoyi.ems.record.service.ITWTempertureDataService;

/**
 * 物联网实时数据Service业务层处理
 *
 * @author Caoql
 * @date 2024-08-21
 */
@Service
public class TWTempertureDataServiceImpl implements ITWTempertureDataService
{
    @Autowired
    private TWTempertureDataMapper tWTempertureDataMapper;

    /**
     * 查询物联网实时数据
     *
     * @param objid 物联网实时数据主键
     * @return 物联网实时数据
     */
    @Override
    public TWTempertureData selectTWTempertureDataByObjid(Long objid)
    {
        return tWTempertureDataMapper.selectTWTempertureDataByObjid(objid);
    }

    /**
     * 查询物联网实时数据列表
     *
     * @param tWTempertureData 物联网实时数据
     * @return 物联网实时数据
     */
    @Override
    public List<TWTempertureData> selectTWTempertureDataList(TWTempertureData tWTempertureData)
    {
        return tWTempertureDataMapper.selectTWTempertureDataList(tWTempertureData);
    }

    /**
     * 新增物联网实时数据
     *
     * @param tWTempertureData 物联网实时数据
     * @return 结果
     */
    @Override
    public int insertTWTempertureData(TWTempertureData tWTempertureData)
    {
        return tWTempertureDataMapper.insertTWTempertureData(tWTempertureData);
    }

    /**
     * 修改物联网实时数据
     *
     * @param tWTempertureData 物联网实时数据
     * @return 结果
     */
    @Override
    public int updateTWTempertureData(TWTempertureData tWTempertureData)
    {
        return tWTempertureDataMapper.updateTWTempertureData(tWTempertureData);
    }

    /**
     * 批量删除物联网实时数据
     *
     * @param objids 需要删除的物联网实时数据主键
     * @return 结果
     */
    @Override
    public int deleteTWTempertureDataByObjids(Long[] objids)
    {
        return tWTempertureDataMapper.deleteTWTempertureDataByObjids(objids);
    }

    /**
     * 删除物联网实时数据信息
     *
     * @param objid 物联网实时数据主键
     * @return 结果
     */
    @Override
    public int deleteTWTempertureDataByObjid(Long objid)
    {
        return tWTempertureDataMapper.deleteTWTempertureDataByObjid(objid);
    }

    /**
     * 查询实时物联网数据
     * @param tWTempertureData
     * @return
     */
    @Override
    public List<TWTempertureData> selectIotInstantList(TWTempertureData tWTempertureData) {
        return tWTempertureDataMapper.selectIotInstantList(tWTempertureData);
    }

    /**
     * 根据设备编号查询实时物联网设备监控数据
     * @param monitorId
     * @return
     */
    @Override
    public TWTempertureData selectIotInstantMinitoringData(String monitorId) {
        return tWTempertureDataMapper.selectIotInstantMinitoringData(monitorId);
    }

    /**
     * 查询物联网实时分组数据列表
     * @param tWTempertureData
     * @return
     */
    @Override
    public List<TWTempertureData> selectLastTWTempertureDataList(TWTempertureData tWTempertureData) {
        // 按monitorName分组并获取每个分组的最新记录
        return tWTempertureDataMapper.selectLastTWTempertureDataList(tWTempertureData);
    }

  /**
   * 查询最新的温度数据。
   * @param tWTempertureData 需要查询的温度数据对象。
   * @return 如果数据库中存在对应的温度数据，返回包含最新数据的列表；如果不存在或查询过程中发生异常，返回空列表。
   */
  @Override
  public List<TWTempertureData> selectLastTWTempertureData(TWTempertureData tWTempertureData) {
      try {
          // 从数据库中查询数据列表
          List<TWTempertureData> twlist = tWTempertureDataMapper.selectLastTWTempertureData(tWTempertureData);
          if (twlist == null || twlist.isEmpty()) {
              // 如果查询结果为空或列表为空，返回一个空列表
              return Collections.emptyList();
          }

          // 创建一个新的TWTempertureData对象用于存储最终的数据
          TWTempertureData data = new TWTempertureData();
          // 获取列表的反向迭代器，从最后一个元素开始遍历
          ListIterator<TWTempertureData> iterator = twlist.listIterator(twlist.size());
          while (iterator.hasPrevious()) {
              // 获取当前元素
              TWTempertureData t = iterator.previous();
              // 如果当前元素的tempreture属性不为空，则设置到data对象中
              setIfNotNull(t, data, "tempreture");
              // 如果当前元素的humidity属性不为空，则设置到data对象中
              setIfNotNull(t, data, "humidity");
              // 如果当前元素的illuminance属性不为空，则设置到data对象中
              setIfNotNull(t, data, "illuminance");
              // 如果当前元素的noise属性不为空，则设置到data对象中
              setIfNotNull(t, data, "noise");
              // 设置PM值到data对象中
              setPmValues(t, data);
          }

          // 返回包含最终数据的单元素列表
          return Collections.singletonList(data);
      } catch (Exception e) {
          // 异常处理，打印堆栈跟踪并返回空列表
          e.printStackTrace();
          return Collections.emptyList();
      }
  }


    /**
     * 将源对象中指定字段的值设置到目标对象的相应字段中，如果该值不为空且目标对象的对应字段为空。
     *
     * @param source 源对象，从中获取字段值
     * @param target 目标对象，将字段值设置到此对象中
     * @param fieldName 要操作的字段名称
     */
    private void setIfNotNull(TWTempertureData source, TWTempertureData target, String fieldName) {
        try {
            // 获取源对象中指定字段的getter方法
            Method getMethod = TWTempertureData.class.getMethod("get" + capitalize(fieldName));
            // 获取目标对象中指定字段的setter方法，参数类型与getter方法返回类型一致
            Method setMethod = TWTempertureData.class.getMethod("set" + capitalize(fieldName), getMethod.getReturnType());
            // 调用getter方法获取源对象中的字段值
            Object value = getMethod.invoke(source);
            // 如果字段值不为空且目标对象中的对应字段值为空，则调用setter方法将值设置到目标对象中
            if (value != null && getMethod.invoke(target) == null) {
                setMethod.invoke(target, value);
            }
        } catch (Exception e) {
            // 捕获并打印异常信息
            e.printStackTrace();
        }
    }

    /**
     * 设置PM值。
     * @param source 源TWTempertureData对象，用于提供PM值。
     * @param target 目标TWTempertureData对象，用于接收PM值。
     */
    private void setPmValues(TWTempertureData source, TWTempertureData target) {
        setIfNotNull(source, target, "pm1");
        if (target.getPm1() == null) {
            setIfNotNull(source, target, "pm2");
        }
        if (target.getPm2() == null) {
            setIfNotNull(source, target, "pm10");
        }
    }

    /**
     * 将字符串的首字母大写。
     *
     * @param str 要处理的字符串
     * @return 首字母大写的字符串，如果输入为空或长度为0，则返回原字符串
     */
    private String capitalize(String str) {
        // 如果字符串为null或者长度为0，直接返回原字符串
        if (str == null || str.length() == 0) {
            return str;
        }
        // 将字符串的第一个字符转换为大写，并与剩余部分拼接后返回
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

}
