<template>
  <!-- 炉火参数表单 -->
  <div class="app-container">
    <!-- flex布局容器，开启自动换行 -->
    <div class="params-list">
      <!-- 遍历筛选后的驱动数据键值对 -->
      <div
        v-for="[key, value] in filteredDriveData"
        :key="key"
        :class="['param-item', { blink: blinkKeyMap[key] }]"
      >
        <!-- 上方label -->
        <span class="param-label">{{ formatLabel(key) }}</span>
        <!-- 下方value -->
        <span class="param-value">{{ formatValue(value) }}</span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'FurCurrent',
  props: {
    driveData: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      prevDriveData: {}, // 存储上一次的驱动数据，用于对比变化
      blinkKeyMap: {}, // 每个key独立的闪烁状态（对象形式：{ key1: true, key2: false }）
      timerMap: {} // 每个key独立的定时器缓存，用于清除旧定时器
    }
  },
  // 筛选包含Actual（不区分大小写）的键值对
  computed: {
    filteredDriveData() {
      // 校验
      if (!this.driveData || typeof this.driveData !== 'object') {
        return [];
      }
      return Object.entries(this.driveData).filter(([key]) => {
        return key.toLowerCase().includes('actual');
      });
    }
  },
  watch: {
    driveData: {
      handler(newVal) {
        if (Object.keys(this.prevDriveData).length === 0) {
          // 首次加载数据，仅缓存数据，不触发闪烁
          this.prevDriveData = JSON.parse(JSON.stringify(newVal));
          return;
        }

        // 对比新值和旧值，找出变化的属性名
        Object.entries(newVal).forEach(([key, value]) => {
          // 仅对比已有属性的变化，且仅处理筛选后的key（包含Actual）
          if (this.prevDriveData.hasOwnProperty(key) && key.toLowerCase().includes('actual')) {
            if (this.prevDriveData[key] !== value) {
              this.triggerBlink(key); // 为每个变化的key单独触发闪烁
            }
          }
        });

        // 更新缓存的旧数据
        this.prevDriveData = JSON.parse(JSON.stringify(newVal));
      },
      deep: true
    }
  },
  methods: {
    // 单独触发某个key的闪烁（核心优化：独立控制）
    triggerBlink(key) {
      // 清除该key的旧定时器，避免1秒内多次更新导致定时器叠加
      if (this.timerMap[key]) {
        clearTimeout(this.timerMap[key]);
      }

      // 设置当前key为闪烁状态（触发动画）
      this.$set(this.blinkKeyMap, key, true);

      // 单独为该key设置定时器，到期后关闭闪烁状态
      this.timerMap[key] = setTimeout(() => {
        this.$set(this.blinkKeyMap, key, false);
        // 定时器执行后，清除缓存的定时器ID
        delete this.timerMap[key];
      }, 500); // 闪烁时长可自定义（1秒）
    },
    // 格式化标签名（将驼峰命名转为中文式分段，提升可读性）
    formatLabel(key) {
      if (!key) return '';
      // 驼峰命名转空格分隔
      const result = key.replace(/([A-Z])/g, ' $1');
      // 首字母大写
      return result.charAt(0).toUpperCase() + result.slice(1);
    },
    // 格式化值（数字类型保留4位小数，提升展示美观度）
    formatValue(value) {
      if (typeof value === 'number') {
        return value.toFixed(4);
      }
      return value;
    }
  },
  // 组件销毁时清除所有定时器，避免内存泄漏
  beforeUnmount() {
    Object.values(this.timerMap).forEach(timer => {
      clearTimeout(timer);
    });
  }
}
</script>

<style scoped>
.app-container {
  border-radius: 8px;
  min-height: 100vh;
}

/* flex布局容器 - 开启换行 */
.params-list {
  display: flex;
  flex-wrap: wrap; /* flex自动换行核心属性 */
  gap: 16px; /* 项目之间的间距（水平+垂直） */
  margin-top: 20px;
}

/* 固定宽度的参数项 - 内部上下布局 */
.param-item {
  width: 200px; /* 固定宽度，可根据需求调整 */
  padding: 12px 16px;
  background-color: #ffffff;
  border: 2px solid #e6e6e6;
  border-radius: 6px;
  transition: all 0.3s ease;
  display: flex; /* 内部flex垂直布局 */
  flex-direction: column; /* 垂直排列：label在上，value在下 */
  align-items: flex-start; /* 左对齐，可改为center居中 */
  gap: 8px; /* label和value之间的垂直间距 */
}

.param-label {
  font-weight: 500;
  color: #333333;
  font-size: 14px;
  word-wrap: break-word; /* 超长label自动换行 */
}

.param-value {
  color: #666666;
  font-family: 'Courier New', monospace; /* 等宽字体，数字对齐更美观 */
  font-size: 15px;
}

/* 闪烁动画定义（保留原有动画效果，优化触发逻辑） */
@keyframes borderBlink {
  0% {
    border-color: #4cd964; /* 初始绿色 */
    box-shadow: 0 0 0 0 rgba(76, 217, 100, 0.2);
  }
  50% {
    border-color: #28a745; /* 深绿色 */
    box-shadow: 0 0 8px 2px rgba(76, 217, 100, 0.5);
  }
  100% {
    border-color: #4cd964; /* 恢复初始绿色 */
    box-shadow: 0 0 0 0 rgba(76, 217, 100, 0.2);
  }
}

/* 闪烁样式：每次blink类添加时，动画重新触发 */
.blink {
  border: 2px solid #4cd964; /* 绿色边框 */
  animation: borderBlink 0.5s ease-in-out 1; /* 强制执行1次动画，避免叠加 */
}
</style>