<template>
  <div class="property-manager-container">
    <!-- 页面标题与导航 -->
    <el-page-header
      @back="handleBack"
      content="设备属性管理"
      class="page-header"
    >
      <template #extra>
        <el-breadcrumb separator="/" class="breadcrumb">
          <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
          <el-breadcrumb-item :to="{ path: '/devices' }">设备管理</el-breadcrumb-item>
          <el-breadcrumb-item>属性配置</el-breadcrumb-item>
        </el-breadcrumb>
      </template>
    </el-page-header>

    <div class="main-content">
      <!-- 左侧设备/分类选择面板 -->
      <div class="sidebar">
        <el-card class="sidebar-card">
          <template #header>
            <div class="sidebar-header">
              <h3 class="sidebar-title">设备与分类</h3>
              <el-input
                v-model="searchQuery"
                placeholder="搜索设备或分类..."
                size="small"
                class="search-input"
              >
                <template #prefix>
                  <el-icon class="search-icon"><Search /></el-icon>
                </template>
              </el-input>
            </div>
          </template>

          <el-tree
            ref="deviceTree"
            :data="deviceTreeData"
            :props="treeProps"
            :filter-node-method="filterNode"
            node-key="id"
            default-expand-all
            @node-click="handleNodeSelect"
            class="device-tree"
            :highlight-current="true"
          >
            <!-- 树形节点自定义插槽 -->
            <template #default="{ node, data }">
              <div class="tree-node">
                <el-icon :class="data.type === 'category' ? 'category-icon' : 'device-icon'">
                  <template v-if="data.type === 'category'">
                    <FolderOpened />
                  </template>
                  <template v-else>
                    <Monitor />
                  </template>
                </el-icon>
                <span class="node-label">{{ node.label }}</span>
                <el-badge
                  v-if="data.propertyCount"
                  :value="data.propertyCount"
                  class="property-count-badge"
                  size="small"
                />
              </div>
            </template>
          </el-tree>
        </el-card>
      </div>

      <!-- 右侧属性配置区域 -->
      <div class="property-config-area">
        <!-- 选中项信息与操作 -->
        <div v-if="selectedNode" class="selected-info-bar">
          <div class="selected-info">
            <el-icon :class="selectedNode.type === 'category' ? 'category-icon' : 'device-icon'">
              <template v-if="selectedNode.type === 'category'">
                <FolderOpened />
              </template>
              <template v-else>
                <Monitor />
              </template>
            </el-icon>
            <h2 class="selected-name">{{ selectedNode.label }}</h2>
            <el-tag :type="selectedNode.type === 'category' ? 'info' : 'primary'" class="node-type-tag">
              {{ selectedNode.type === 'category' ? '分类' : '设备' }}
            </el-tag>
          </div>

          <div class="action-buttons">
            <el-button
              type="primary"
              @click="showAddPropertyDialog"
              class="add-property-btn"
              size="default"
            >
              <template #icon>
                <Plus />
              </template>
              添加属性
            </el-button>
            <el-button
              type="success"
              @click="saveAllProperties"
              :loading="saveLoading"
              size="default"
            >
              <template #icon>
                <Check />
              </template>
              保存配置
            </el-button>
          </div>
        </div>

        <!-- 未选择任何项时的空状态 -->
        <div v-else class="empty-state">
          <el-empty
            description="请从左侧选择一个设备或分类"
            class="main-empty-state"
          >
            <template #image>
              <div class="empty-image-container">
                <el-icon class="empty-icon"><Icon icon="ep:add" /></el-icon>
              </div>
            </template>
          </el-empty>
        </div>

        <!-- 属性卡片列表 -->
        <div v-if="selectedNode && properties.length > 0" class="properties-grid">
          <!-- 属性卡片组件，使用v-for渲染 -->
          <property-card
            v-for="(property, index) in properties"
            :key="property.id"
            :property="property"
            @update-property="handlePropertyUpdate(index, $event)"
            @delete-property="handlePropertyDelete(index)"
            class="property-card-item"
          >
            <!-- 卡片底部插槽示例 - 可以根据需要自定义内容 -->
            <template #footer-actions>
              <el-tooltip content="查看历史记录">
                <el-button icon="Clock" size="mini" class="history-btn" />
              </el-tooltip>
            </template>
          </property-card>
        </div>

        <!-- 有选中项但无属性时的空状态 -->
        <div v-if="selectedNode && properties.length === 0" class="no-properties-state">
          <el-empty
            description="暂无属性，请点击添加属性按钮创建"
          >
            <template #image>
              <div class="no-properties-image">
                <el-icon class="no-properties-icon"><Icon icon="ep:add" /></el-icon>
              </div>
            </template>
            <template #bottom>
              <el-button
                type="primary"
                @click="showAddPropertyDialog"
                size="default"
              >
                <template #icon>
                  <Plus />
                </template>
                添加第一个属性
              </el-button>
            </template>
          </el-empty>
        </div>
      </div>
    </div>

    <!-- 添加/编辑属性对话框 -->
    <el-dialog
      v-model="propertyDialogVisible"
      :title="isEditing ? '编辑属性' : '添加新属性'"
      :width="500"
      @close="resetPropertyForm"
      class="property-dialog"
    >
      <el-form
        ref="propertyForm"
        :model="currentProperty"
        :rules="propertyRules"
        label-width="120px"
        class="property-form"
      >
        <el-form-item label="属性名称" prop="name">
          <el-input
            v-model="currentProperty.name"
            placeholder="请输入属性名称"
            maxlength="50"
          />
        </el-form-item>

        <el-form-item label="属性标识" prop="code">
          <el-input
            v-model="currentProperty.code"
            placeholder="请输入属性唯一标识"
            maxlength="30"
            :disabled="isEditing"
          />
          <div class="form-hint">标识用于系统内部识别，添加后不可修改</div>
        </el-form-item>

        <el-form-item label="数据类型" prop="dataType">
          <el-select
            v-model="currentProperty.dataType"
            placeholder="请选择数据类型"
            @change="handleDataTypeChange"
          >
            <el-option label="整数" value="integer" />
            <el-option label="浮点数" value="float" />
            <el-option label="布尔值" value="boolean" />
          </el-select>
        </el-form-item>

        <el-form-item label="单位" prop="unit">
          <el-input
            v-model="currentProperty.unit"
            placeholder="例如：℃、%、m"
            maxlength="10"
          />
        </el-form-item>

        <el-row :gutter="16" class="limit-inputs-row">
          <el-col :span="12">
            <el-form-item label="最小值" prop="minValue">
              <el-input-number
                v-model.number="currentProperty.minValue"
                :precision="currentProperty.dataType === 'float' ? 2 : 0"
                :step="currentProperty.dataType === 'float' ? 0.1 : 1"
                placeholder="请输入最小值"
                :disabled="currentProperty.dataType === 'boolean'"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="最大值" prop="maxValue">
              <el-input-number
                v-model.number="currentProperty.maxValue"
                :precision="currentProperty.dataType === 'float' ? 2 : 0"
                :step="currentProperty.dataType === 'float' ? 0.1 : 1"
                placeholder="请输入最大值"
                :disabled="currentProperty.dataType === 'boolean'"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="描述信息" prop="description">
          <el-input
            v-model="currentProperty.description"
            placeholder="请输入属性描述（可选）"
            type="textarea"
            :rows="3"
            maxlength="200"
          />
        </el-form-item>

        <el-form-item>
          <el-checkbox v-model="currentProperty.required">设为必填属性</el-checkbox>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="propertyDialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="confirmPropertyAction"
          :loading="dialogLoading"
        >
          {{ isEditing ? '更新属性' : '创建属性' }}
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, watch, nextTick, computed } from 'vue';
import {
  Search, FolderOpened, Monitor, Plus, Check,
  Edit, Delete, InfoFilled, Clock
} from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus';

// 属性卡片组件（使用slot）
const PropertyCard = {
  props: {
    property: {
      type: Object,
      required: true,
      default: () => ({})
    }
  },
  emits: ['update-property', 'delete-property'],
  template: `
    <el-card class="property-card">
      <!-- 卡片头部 -->
      <template #header>
        <div class="property-card-header">
          <div class="property-name">
            <span>{{ property.name }}</span>
            <el-tag
              v-if="property.required"
              size="mini"
              type="danger"
              class="required-tag"
            >
              必填
            </el-tag>
          </div>
          <div class="property-actions">
            <el-tooltip content="编辑属性" placement="top">
              <el-button
                icon="Edit"
                size="mini"
                @click="$emit('update-property', { ...property })"
                class="action-btn edit-btn"
              />
            </el-tooltip>
            <el-tooltip content="删除属性" placement="top">
              <el-button
                icon="Delete"
                size="mini"
                @click="$emit('delete-property')"
                class="action-btn delete-btn"
              />
            </el-tooltip>
          </div>
        </div>
      </template>

      <!-- 卡片内容区 -->
      <div class="property-content">
        <div class="property-info-item">
          <span class="info-label">标识：</span>
          <span class="info-value">{{ property.code }}</span>
        </div>

        <div class="property-info-item">
          <span class="info-label">类型：</span>
          <span class="info-value">
            <el-tag size="small" :type="getTypeTagType(property.dataType)">
              {{ getTypeName(property.dataType) }}
            </el-tag>
          </span>
        </div>

        <!-- 上下限配置区域 -->
        <div v-if="property.dataType !== 'boolean'" class="property-limits">
          <div class="limits-label">数值范围：</div>
          <div class="limits-inputs">
            <el-input-number
              v-model.number="property.minValue"
              :precision="property.dataType === 'float' ? 2 : 0"
              :step="property.dataType === 'float' ? 0.1 : 1"
              :placeholder="'最小'"
              size="small"
              class="limit-input min-input"
              @change="handleLimitChange"
            />
            <span class="limit-separator">-</span>
            <el-input-number
              v-model.number="property.maxValue"
              :precision="property.dataType === 'float' ? 2 : 0"
              :step="property.dataType === 'float' ? 0.1 : 1"
              :placeholder="'最大'"
              size="small"
              class="limit-input max-input"
              :min="property.minValue"
              @change="handleLimitChange"
            />
            <span v-if="property.unit" class="property-unit">{{ property.unit }}</span>
          </div>
        </div>

        <!-- 布尔值特殊处理 -->
        <div v-else class="boolean-value">
          <span class="info-label">值：</span>
          <el-switch
            v-model="property.booleanValue"
            active-text="真"
            inactive-text="假"
            @change="handleBooleanChange"
          />
        </div>

        <!-- 描述信息 -->
        <div v-if="property.description" class="property-description">
          <el-icon class="description-icon"><InfoFilled /></el-icon>
          <span>{{ property.description }}</span>
        </div>
      </div>

      <!-- 卡片底部，包含默认内容和插槽 -->
      <template #footer>
        <div class="property-card-footer">
          <span class="last-updated">
            最后更新：{{ formatDate(property.updatedAt) }}
          </span>
          <div class="footer-actions">
            <!-- 插槽：允许父组件添加额外的操作按钮 -->
            <slot name="footer-actions"></slot>
          </div>
        </div>
      </template>
    </el-card>
  `,
  methods: {
    // 获取数据类型显示名称
    getTypeName(type) {
      const types = {
        'integer': '整数',
        'float': '浮点数',
        'boolean': '布尔值'
      };
      return types[type] || type;
    },
    // 获取数据类型标签样式
    getTypeTagType(type) {
      const types = {
        'integer': 'primary',
        'float': 'success',
        'boolean': 'warning'
      };
      return types[type] || 'info';
    },
    // 处理上下限变化
    handleLimitChange() {
      this.$emit('update-property', { ...this.property });
    },
    // 处理布尔值变化
    handleBooleanChange() {
      this.$emit('update-property', { ...this.property });
    },
    // 格式化日期
    formatDate(timestamp) {
      if (!timestamp) return '未更新';
      const date = new Date(timestamp);
      return date.toLocaleString();
    }
  }
};

// 生成唯一ID
const generateId = () => {
  return Date.now().toString(36) + Math.random().toString(36).substr(2, 8);
};

// 设备树形结构数据
const deviceTreeData = ref([
  {
    id: 'cat1',
    label: '温度设备',
    type: 'category',
    propertyCount: 3,
    children: [
      {
        id: 'dev11',
        label: '室内温度计',
        type: 'device',
        propertyCount: 5
      },
      {
        id: 'dev12',
        label: '室外温度计',
        type: 'device',
        propertyCount: 4
      }
    ]
  },
  {
    id: 'cat2',
    label: '湿度设备',
    type: 'category',
    propertyCount: 2,
    children: [
      {
        id: 'dev21',
        label: '车间湿度计',
        type: 'device',
        propertyCount: 3
      },
      {
        id: 'dev22',
        label: '仓库湿度计',
        type: 'device',
        propertyCount: 3
      }
    ]
  }
]);

// 树形结构配置
const treeProps = {
  children: 'children',
  label: 'label'
};

// 状态管理
const searchQuery = ref('');
const deviceTree = ref(null);
const selectedNode = ref(null);
const properties = ref([]);
const saveLoading = ref(false);
const dialogLoading = ref(false);
const propertyDialogVisible = ref(false);
const isEditing = ref(false);
const currentEditIndex = ref(-1);

// 属性表单数据
const currentProperty = reactive({
  id: '',
  name: '',
  code: '',
  dataType: 'float',
  unit: '',
  minValue: null,
  maxValue: null,
  booleanValue: false,
  description: '',
  required: false,
  updatedAt: null
});

// 属性表单验证规则
const propertyRules = {
  name: [
    { required: true, message: '请输入属性名称', trigger: 'blur' },
    { max: 50, message: '属性名称不能超过50个字符', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入属性标识', trigger: 'blur' },
    { pattern: /^[a-zA-Z0-9_]+$/, message: '标识只能包含字母、数字和下划线', trigger: 'blur' },
    { max: 30, message: '属性标识不能超过30个字符', trigger: 'blur' }
  ],
  dataType: [
    { required: true, message: '请选择数据类型', trigger: 'change' }
  ],
  minValue: [
    {
      required: () => currentProperty.dataType !== 'boolean',
      message: '请输入最小值',
      trigger: 'blur'
    },
    {
      type: 'number',
      message: '请输入有效的数字',
      trigger: 'blur',
      validator: (rule, value, callback) => {
        if (currentProperty.dataType === 'boolean') {
          return callback();
        }
        if (value === null || value === undefined) {
          return callback(new Error('请输入最小值'));
        }
        if (currentProperty.maxValue !== null && value > currentProperty.maxValue) {
          return callback(new Error('最小值不能大于最大值'));
        }
        callback();
      }
    }
  ],
  maxValue: [
    {
      required: () => currentProperty.dataType !== 'boolean',
      message: '请输入最大值',
      trigger: 'blur'
    },
    {
      type: 'number',
      message: '请输入有效的数字',
      trigger: 'blur',
      validator: (rule, value, callback) => {
        if (currentProperty.dataType === 'boolean') {
          return callback();
        }
        if (value === null || value === undefined) {
          return callback(new Error('请输入最大值'));
        }
        if (currentProperty.minValue !== null && value < currentProperty.minValue) {
          return callback(new Error('最大值不能小于最小值'));
        }
        callback();
      }
    }
  ]
};

// 过滤节点方法
const filterNode = (value, data) => {
  if (!value) return true;
  return data.label.toLowerCase().includes(value.toLowerCase());
};

// 监听搜索关键词变化
watch(searchQuery, (value) => {
  deviceTree.value?.filter(value);
});

// 处理节点选择
const handleNodeSelect = (data) => {
  // 检查是否有未保存的修改
  if (hasUnsavedChanges.value) {
    ElMessageBox.confirm(
      '当前有未保存的修改，切换设备/分类将丢失这些更改，是否继续？',
      '确认切换',
      {
        confirmButtonText: '继续',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => {
      loadNodeProperties(data);
    }).catch(() => {
      // 取消切换，恢复之前的选择
      nextTick(() => {
        deviceTree.value.setCurrentKey(selectedNode.value?.id);
      });
    });
  } else {
    loadNodeProperties(data);
  }
};

// 加载节点属性
const loadNodeProperties = (data) => {
  selectedNode.value = data;
  // 模拟API加载属性数据
  saveLoading.value = true;

  setTimeout(() => {
    // 根据不同节点加载不同的属性示例数据
    if (data.id === 'dev11') { // 室内温度计
      properties.value = [
        {
          id: generateId(),
          name: '测量温度',
          code: 'measure_temp',
          dataType: 'float',
          unit: '℃',
          minValue: -10,
          maxValue: 50,
          required: true,
          description: '设备测量的环境温度',
          updatedAt: Date.now() - 86400000
        },
        {
          id: generateId(),
          name: '测量精度',
          code: 'measure_precision',
          dataType: 'float',
          unit: '℃',
          minValue: 0,
          maxValue: 0.5,
          required: false,
          description: '温度测量的允许误差范围',
          updatedAt: Date.now() - 3600000
        },
        {
          id: generateId(),
          name: '采样频率',
          code: 'sample_rate',
          dataType: 'integer',
          unit: '次/分钟',
          minValue: 1,
          maxValue: 60,
          required: true,
          updatedAt: Date.now()
        }
      ];
    } else if (data.id === 'cat1') { // 温度设备分类
      properties.value = [
        {
          id: generateId(),
          name: '工作温度',
          code: 'working_temp',
          dataType: 'float',
          unit: '℃',
          minValue: -20,
          maxValue: 70,
          required: true,
          description: '设备正常工作的环境温度范围',
          updatedAt: Date.now() - 86400000 * 2
        },
        {
          id: generateId(),
          name: '存储温度',
          code: 'storage_temp',
          dataType: 'float',
          unit: '℃',
          minValue: -40,
          maxValue: 85,
          required: true,
          description: '设备存储的环境温度范围',
          updatedAt: Date.now() - 86400000
        }
      ];
    } else {
      // 其他节点的默认属性
      properties.value = [];
    }

    saveLoading.value = false;
    ElNotification({
      title: '已加载',
      message: `已加载 ${data.label} 的 ${properties.value.length} 个属性`,
      duration: 1500,
      position: 'bottom-right'
    });
  }, 600);
};

// 检查是否有未保存的更改
const hasUnsavedChanges = ref(false);

// 监听属性变化
watch(properties, (newVal) => {
  hasUnsavedChanges.value = true;
}, { deep: true });

// 显示添加属性对话框
const showAddPropertyDialog = () => {
  resetPropertyForm();
  isEditing.value = false;
  currentProperty.id = generateId();
  propertyDialogVisible.value = true;

  // 自动聚焦到第一个输入框
  nextTick(() => {
    const firstInput = document.querySelector('.property-dialog .el-input__inner');
    if (firstInput) firstInput.focus();
  });
};

// 显示编辑属性对话框
const showEditPropertyDialog = (index, property) => {
  resetPropertyForm();
  isEditing.value = true;
  currentEditIndex.value = index;

  // 复制属性数据到表单
  Object.assign(currentProperty, { ...property });

  propertyDialogVisible.value = true;
  nextTick(() => {
    const firstInput = document.querySelector('.property-dialog .el-input__inner');
    if (firstInput) firstInput.focus();
  });
};

// 重置属性表单
const resetPropertyForm = () => {
  currentProperty.name = '';
  currentProperty.code = '';
  currentProperty.dataType = 'float';
  currentProperty.unit = '';
  currentProperty.minValue = null;
  currentProperty.maxValue = null;
  currentProperty.booleanValue = false;
  currentProperty.description = '';
  currentProperty.required = false;

  // 重置表单验证
  nextTick(() => {
    propertyForm.value?.clearValidate();
  });
};

// 处理数据类型变化
const handleDataTypeChange = (type) => {
  // 根据数据类型重置相关值
  if (type === 'boolean') {
    currentProperty.minValue = null;
    currentProperty.maxValue = null;
  } else if (type === 'integer') {
    currentProperty.minValue = currentProperty.minValue !== null ? Math.round(currentProperty.minValue) : 0;
    currentProperty.maxValue = currentProperty.maxValue !== null ? Math.round(currentProperty.maxValue) : 100;
  }
};

// 确认属性操作（添加或编辑）
const propertyForm = ref(null);
const confirmPropertyAction = () => {
  propertyForm.value.validate((valid) => {
    if (valid) {
      dialogLoading.value = true;

      // 模拟API请求延迟
      setTimeout(() => {
        const newProperty = { ...currentProperty };
        newProperty.updatedAt = Date.now();

        if (isEditing.value) {
          // 编辑现有属性
          properties.value.splice(currentEditIndex.value, 1, newProperty);
          ElMessage.success('属性已更新');
        } else {
          // 添加新属性
          properties.value.push(newProperty);
          // 更新节点的属性计数
          if (selectedNode.value) {
            selectedNode.value.propertyCount = (selectedNode.value.propertyCount || 0) + 1;
          }
          ElMessage.success('新属性已添加');
        }

        dialogLoading.value = false;
        propertyDialogVisible.value = false;
      }, 500);
    }
  });
};

// 处理属性更新
const handlePropertyUpdate = (index, updatedProperty) => {
  updatedProperty.updatedAt = Date.now();
  properties.value.splice(index, 1, updatedProperty);
};

// 处理属性删除
const handlePropertyDelete = (index) => {
  const property = properties.value[index];
  ElMessageBox.confirm(
    `确定要删除属性"${property.name}"吗？此操作不可撤销。`,
    '确认删除',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'danger'
    }
  ).then(() => {
    properties.value.splice(index, 1);
    // 更新节点的属性计数
    if (selectedNode.value) {
      selectedNode.value.propertyCount = Math.max(0, (selectedNode.value.propertyCount || 0) - 1);
    }
    ElMessage.success('属性已删除');
  }).catch(() => {
    // 取消删除
  });
};

// 保存所有属性配置
const saveAllProperties = () => {
  if (properties.value.length === 0) {
    ElMessage.warning('没有可保存的属性');
    return;
  }

  saveLoading.value = true;

  // 模拟API保存
  setTimeout(() => {
    saveLoading.value = false;
    hasUnsavedChanges.value = false;

    ElNotification({
      title: '保存成功',
      message: `已成功保存 ${properties.value.length} 个属性配置`,
      type: 'success',
      duration: 2000,
      position: 'bottom-right'
    });
  }, 800);
};

// 返回操作
const handleBack = () => {
  if (hasUnsavedChanges.value) {
    ElMessageBox.confirm(
      '当前有未保存的修改，离开页面将丢失这些更改，是否继续？',
      '确认离开',
      {
        confirmButtonText: '离开',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => {
      // 实际应用中这里会执行路由跳转
      ElMessage.info('已返回上一页');
    });
  } else {
    // 实际应用中这里会执行路由跳转
    ElMessage.info('已返回上一页');
  }
};

// 页面加载时默认选中第一个设备
watch(() => deviceTreeData.value.length, (length) => {
  if (length > 0 && !selectedNode.value) {
    // 尝试选择第一个设备节点
    const firstDevice = deviceTreeData.value[0]?.children?.[0];
    if (firstDevice) {
      nextTick(() => {
        handleNodeSelect(firstDevice);
        deviceTree.value.setCurrentKey(firstDevice.id);
      });
    }
  }
}, { immediate: true });
</script>

<style scoped>
/* 全局样式 */
.property-manager-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}

/* 页面头部 */
.page-header {
  margin-bottom: 24px;
  --el-page-header-text-color: #1d2129;
  --el-page-header-font-size: 20px;
}

.breadcrumb {
  font-size: 13px;
  color: #86909c;
}

/* 主内容区 */
.main-content {
  display: flex;
  gap: 24px;
  height: calc(100vh - 120px);
}

/* 左侧边栏 */
.sidebar {
  width: 320px;
  flex-shrink: 0;
}

.sidebar-card {
  height: 100%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  border-radius: 8px;
  overflow: hidden;
  border: none;
  display: flex;
  flex-direction: column;
}

.sidebar-header {
  padding: 16px;
  background-color: #f7f8fa;
  border-bottom: 1px solid #f0f0f0;
}

.sidebar-title {
  margin: 0 0 12px 0;
  font-size: 16px;
  font-weight: 500;
  color: #1d2129;
}

.search-input {
  width: 100%;
  --el-input-bg-color: #fff;
}

.search-icon {
  color: #86909c;
}

.device-tree {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0;
  --el-tree-node-content-hover-bg-color: #f5f7fa;
}

.tree-node {
  display: flex;
  align-items: center;
  padding: 4px 8px;
}

.category-icon {
  color: #409eff;
  margin-right: 8px;
  font-size: 16px;
}

.device-icon {
  color: #00b42a;
  margin-right: 8px;
  font-size: 16px;
}

.node-label {
  font-size: 14px;
  flex: 1;
  transition: color 0.2s;
}

.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content .node-label {
  color: #409eff;
  font-weight: 500;
}

.property-count-badge {
  background-color: #f2f3f5;
  color: #86909c;
  --el-badge-font-size: 12px;
}

/* 右侧属性配置区 */
.property-config-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* 选中项信息栏 */
.selected-info-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  margin-bottom: 20px;
}

.selected-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.selected-name {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
  color: #1d2129;
}

.node-type-tag {
  margin-left: 8px;
}

.action-buttons {
  display: flex;
  gap: 12px;
}

.add-property-btn {
  transition: all 0.2s;
}

.add-property-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}

/* 属性卡片网格 */
.properties-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap: 20px;
  padding: 4px;
  overflow-y: auto;
  flex: 1;
}

.property-card-item {
  transition: all 0.3s ease;
}

.property-card-item:hover {
  transform: translateY(-4px);
}

/* 属性卡片样式 */
.property-card {
  height: 100%;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
  transition: all 0.2s;
  border: none;
  overflow: hidden;
}

.property-card:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.property-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background-color: #f7f8fa;
  border-bottom: 1px solid #f0f0f0;
}

.property-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
  color: #1d2129;
}

.required-tag {
  font-size: 12px;
  padding: 0 4px;
  height: 18px;
  line-height: 18px;
}

.property-actions {
  display: flex;
  gap: 4px;
}

.action-btn {
  padding: 0 4px;
  height: 24px;
  border-radius: 4px;
  transition: all 0.2s;
}

.edit-btn {
  color: #409eff;
  background-color: #ecf5ff;
}

.edit-btn:hover {
  background-color: #d9ecff;
}

.delete-btn {
  color: #f56c6c;
  background-color: #fef0f0;
}

.delete-btn:hover {
  background-color: #fee4e4;
}

.property-content {
  padding: 16px;
}

.property-info-item {
  margin-bottom: 12px;
  font-size: 14px;
}

.info-label {
  color: #86909c;
  display: inline-block;
  width: 60px;
}

.info-value {
  color: #1d2129;
}

.property-limits {
  margin: 16px 0;
  padding: 12px;
  background-color: #f7f8fa;
  border-radius: 6px;
}

.limits-label {
  color: #86909c;
  margin-bottom: 8px;
  font-size: 14px;
}

.limits-inputs {
  display: flex;
  align-items: center;
  gap: 10px;
}

.limit-input {
  flex: 1;
  --el-input-number-input-height: 32px;
}

.min-input {
  --el-input-number-bg-color: #f0f7ff;
}

.max-input {
  --el-input-number-bg-color: #f0fff4;
}

.limit-separator {
  color: #86909c;
  font-weight: 500;
}

.property-unit {
  color: #86909c;
  white-space: nowrap;
  padding-left: 4px;
}

.boolean-value {
  margin: 16px 0;
  padding: 12px;
  background-color: #f7f8fa;
  border-radius: 6px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.property-description {
  margin-top: 12px;
  padding: 8px 12px;
  background-color: #f0f7ff;
  border-radius: 4px;
  font-size: 13px;
  color: #4e5969;
  display: flex;
  align-items: center;
  gap: 6px;
}

.description-icon {
  color: #409eff;
  font-size: 14px;
}

.property-card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 16px;
  background-color: #f7f8fa;
  border-top: 1px solid #f0f0f0;
  font-size: 12px;
  color: #86909c;
}

.last-updated {
  flex: 1;
}

.footer-actions {
  display: flex;
  gap: 4px;
}

.history-btn {
  color: #86909c;
  background-color: #f2f3f5;
  padding: 0 4px;
  height: 24px;
}

/* 空状态样式 */
.empty-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.empty-image-container {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background-color: #f0f7ff;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
}

.empty-icon {
  font-size: 60px;
  color: #409eff;
}

.no-properties-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  padding: 40px;
}

.no-properties-image {
  width: 100px;
  height: 100px;
  margin-bottom: 16px;
}

.no-properties-icon {
  font-size: 100px;
  color: #c9cdD4;
}

/* 对话框样式 */
.property-dialog {
  --el-dialog-border-radius: 8px;
}

.property-form {
  margin-top: 12px;
}

.form-hint {
  margin-top: 4px;
  font-size: 12px;
  color: #86909c;
  line-height: 1.4;
}

.limit-inputs-row {
  margin-bottom: 8px;
}

/* 滚动条美化 */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 动画效果 */
.el-collapse-transition {
  transition: height 0.3s ease, opacity 0.3s ease;
}

/* 响应式调整 */
@media (max-width: 1200px) {
  .properties-grid {
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  }
}

@media (max-width: 992px) {
  .main-content {
    flex-direction: column;
    height: auto;
  }

  .sidebar {
    width: 100%;
    height: 300px;
  }

  .properties-grid {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  }
}
</style>
