<template>
  <div class="timing-strategy-page">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2 class="page-title">
        <el-icon><Clock /></el-icon>
        定时策略管理
      </h2>
      <p class="page-description">管理设备的定时控制策略，支持按周期和时间自动执行设备操作</p>
    </div>

    <!-- 查询条件卡片 -->
    <el-card class="search-card" shadow="hover">
      <el-form :model="searchForm" inline class="search-form">
        <el-form-item label="策略名称">
          <el-input
              v-model="searchForm.searchText"
              placeholder="请输入策略名称搜索"
              clearable
              prefix-icon="Search"
              @keyup.enter="handleSearch"
              class="search-input"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch" :icon="Search">
            搜索
          </el-button>
          <el-button @click="handleReset" :icon="Refresh">
            重置
          </el-button>
          <el-button type="success" @click="handleAdd" :icon="Plus">
            新增策略
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 数据表格卡片 -->
    <el-card class="table-card" shadow="hover">
      <template #header>
        <div class="card-header">
          <div class="header-left">
            <el-icon><List /></el-icon>
            <span>策略列表</span>
            <el-tag type="info" class="count-tag">共 {{ pagination.total }} 条</el-tag>
          </div>
        </div>
      </template>

      <el-table
          :data="tableData"
          stripe
          class="strategy-table"
      >
        <el-table-column prop="timing_name" label="策略名称" min-width="150">
          <template #default="{ row }">
            <div class="strategy-name">
              <el-icon class="name-icon"><Timer /></el-icon>
              {{ row.timing_name }}
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="weeks" label="重复日期" min-width="200">
          <template #default="{ row }">
            <div class="weeks-container">
              <el-tag
                  v-for="week in getWeekTags(row.weeks)"
                  :key="week.value"
                  :type="week.type"
                  size="small"
                  class="week-tag"
              >
                {{ week.label }}
              </el-tag>
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="timing_start_time" label="执行时间" width="120">
          <template #default="{ row }">
            <div class="time-display">
              <el-icon><Clock /></el-icon>
              {{ row.timing_start_time }}
            </div>
          </template>
        </el-table-column>

        <!-- 保持原来的设备指令列显示方式，但优化内容 -->
        <el-table-column prop="timing_agreement" label="设备指令" min-width="180">
          <template #default="{ row }">
            <div class="agreement-display">
              <el-tag
                  v-for="(item, index) in getAgreementTags(row.timing_agreement)"
                  :key="index"
                  :type="item.type"
                  size="small"
                  class="agreement-tag"
                  :class="item.configType"
              >
        <span class="tag-icon" v-if="item.icon">
          <el-icon>
            <component :is="item.icon" />
          </el-icon>
        </span>
                {{ item.label }}
              </el-tag>

              <!-- 如果没有任何配置显示提示 -->
              <el-tag v-if="getAgreementTags(row.timing_agreement).length === 0" type="info" size="small" class="no-config-tag">
                <el-icon><InfoFilled /></el-icon>
                未配置路数
              </el-tag>
            </div>
          </template>
        </el-table-column>

        <el-table-column prop="timing_state" label="状态" width="100">
          <template #default="{ row }">
            <el-switch
                v-model="row.timing_state"
                :active-value="1"
                :inactive-value="0"
                active-color="#13ce66"
                inactive-color="#ff4949"
                @change="handleStatusChange(row)"
            />
          </template>
        </el-table-column>

        <el-table-column label="操作" width="180" fixed="right">
          <template #default="{ row }">
            <div class="action-buttons">
              <el-button
                  type="primary"
                  size="small"
                  :icon="Edit"
                  @click="handleEdit(row)"
                  link
                  class="action-btn control-btn"
              >
                编辑
              </el-button>
              <el-button
                  type="info"
                  size="small"
                  :icon="View"
                  @click="handleDetail(row)"
                  link
              >
                详情
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
            v-model:current-page="pagination.currentPage"
            v-model:page-size="pagination.pageSize"
            :total="pagination.total"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            background
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 新增/编辑弹窗 -->
    <el-dialog
        v-model="dialogVisible"
        :title="dialogTitle"
        width="900px"
        :close-on-click-modal="false"
        class="strategy-dialog"
        @close="handleDialogClose"
    >
      <el-form
          :model="formData"
          :rules="formRules"
          ref="formRef"
          label-width="120px"
          class="strategy-form"
      >
        <!-- 基本信息 -->
        <div class="form-section">
          <h3 class="section-title">
            <el-icon><InfoFilled /></el-icon>
            基本信息
          </h3>

          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="策略名称" prop="timing_name">
                <el-input
                    v-model="formData.timing_name"
                    placeholder="请输入策略名称"
                    prefix-icon="Edit"
                    maxlength="50"
                    show-word-limit
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="执行时间" prop="timing_start_time">
                <el-time-picker
                    v-model="formData.timing_start_time"
                    format="HH:mm"
                    value-format="HH:mm"
                    placeholder="选择时间"
                    style="width: 100%"
                />
              </el-form-item>
            </el-col>
          </el-row>

          <!-- 重复日期选择 -->
          <el-form-item label="重复日期" prop="weeks">
            <div class="weeks-selection">
              <!-- 快捷选择按钮 -->
              <div class="quick-select-buttons">
                <el-button
                    size="small"
                    @click="selectAllWeekdays"
                    :type="isAllWeekdaysSelected ? 'primary' : ''"
                >
                  工作日
                </el-button>
                <el-button
                    size="small"
                    @click="selectWeekend"
                    :type="isWeekendSelected ? 'primary' : ''"
                >
                  周末
                </el-button>
                <el-button
                    size="small"
                    @click="selectAllWeek"
                    :type="isAllWeekSelected ? 'primary' : ''"
                >
                  全选
                </el-button>
                <el-button
                    size="small"
                    @click="clearAllWeeks"
                >
                  清空
                </el-button>
              </div>

              <!-- 星期选择 -->
              <div class="week-selection-container">
                <div class="week-days-grid">
                  <div
                      v-for="day in weekDays"
                      :key="day.value"
                      :class="[
                        'week-day-item',
                        { 'selected': formData.weeks.includes(day.value) },
                        { 'weekend': day.isWeekend }
                      ]"
                      @click="toggleWeekDay(day.value)"
                  >
                    <div class="day-content">
                      <div class="day-name">{{ day.name }}</div>
                      <div class="day-en">{{ day.en }}</div>
                      <div class="day-icon">
                        <el-icon v-if="formData.weeks.includes(day.value)">
                          <Check />
                        </el-icon>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- 特殊选项 -->
                <div class="special-options">
                  <div class="special-option-group">
                    <h4 class="option-group-title">特殊设置</h4>
                    <div class="special-checkboxes">
                      <div
                          :class="[
                            'special-checkbox',
                            { 'checked': formData.weeks.includes(256) }
                          ]"
                          @click="toggleSpecialOption(256)"
                      >
                        <el-icon class="checkbox-icon">
                          <Check v-if="formData.weeks.includes(256)" />
                        </el-icon>
                        <span class="checkbox-label">节假日执行</span>
                      </div>
                      <div
                          :class="[
                            'special-checkbox',
                            { 'checked': formData.weeks.includes(512) }
                          ]"
                          @click="toggleSpecialOption(512)"
                      >
                        <el-icon class="checkbox-icon">
                          <Check v-if="formData.weeks.includes(512)" />
                        </el-icon>
                        <span class="checkbox-label">节假日不执行</span>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- 选择结果预览 -->
              <div class="selection-preview" v-if="formData.weeks.length > 0">
                <div class="preview-title">已选择：</div>
                <div class="preview-tags">
                  <el-tag
                      v-for="week in getSelectedWeekTags"
                      :key="week.value"
                      :type="week.type"
                      size="small"
                      closable
                      @close="removeWeekDay(week.value)"
                      class="preview-tag"
                  >
                    {{ week.label }}
                  </el-tag>
                </div>
              </div>
            </div>
          </el-form-item>
        </div>

        <!-- 设备选择 -->
        <div class="form-section">
          <h3 class="section-title">
            <el-icon><Monitor /></el-icon>
            设备选择
          </h3>

          <el-form-item label="选择方式">
            <el-radio-group v-model="deviceSelectType" class="select-type-radio" @change="handleSelectTypeChange">
              <el-radio label="region">
                <el-icon><Location /></el-icon>
                按区域选择
              </el-radio>
              <el-radio label="group">
                <el-icon><Collection /></el-icon>
                按分组选择
              </el-radio>
            </el-radio-group>
          </el-form-item>

          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item label="所属位置" prop="region_ids">
                <!-- 区域选择 - 使用树形选择器 -->
                <el-tree-select
                    ref="regionTreeRef"
                    v-model="formData.region_ids"
                    :data="regionTreeData"
                    :props="regionTreeProps"
                    placeholder="请选择所属位置"
                    clearable
                    filterable
                    check-strictly
                    :load="loadRegionNode"
                    lazy
                    style="width: 100%"
                    @change="handleRegionSelectChange"
                    :default-expanded-keys="[]"
                    :show-checkbox="false"
                    node-key="id"
                    :render-after-expand="false"
                    :cache-data="false"
                    :key="`region-tree-${treeKey}`"
                />
              </el-form-item>
            </el-col>

            <el-col :span="8">
              <el-form-item label="设备分类" prop="category_id">
                <el-select
                    v-model="formData.category_id"
                    placeholder="请选择设备分类"
                    clearable
                    style="width: 100%"
                    @change="handleCategoryChange"
                >
                  <el-option
                      v-for="item in categoryOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>

            <el-col :span="8">
              <el-form-item label="设备型号" prop="device_type_id">
                <el-select
                    v-model="formData.device_type_id"
                    placeholder="请选择设备型号"
                    clearable
                    style="width: 100%"
                    @change="handleDeviceTypeChange"
                >
                  <el-option
                      v-for="item in deviceTypeOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-form-item label="设备名称" prop="device_ids">
            <div class="device-select-container">
              <el-select
                  v-model="formData.device_ids"
                  placeholder="请选择设备名称"
                  multiple
                  clearable
                  collapse-tags
                  collapse-tags-tooltip
                  :max-collapse-tags="30"
                  style="width: 100%"
                  @change="handleDeviceChange"
              >
                <template #header>
                  <div class="device-select-header">
                    <el-checkbox
                        v-model="isAllDevicesSelected"
                        :indeterminate="isDeviceIndeterminate"
                        @change="handleSelectAllDevices"
                    >
                      全选设备 ({{ deviceOptions.length }})
                    </el-checkbox>
                  </div>
                </template>
                <el-option
                    v-for="item in deviceOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                />
              </el-select>
              <div class="device-count-info" v-if="formData.device_ids.length > 0">
                已选择 {{ formData.device_ids.length }} 个设备
              </div>
            </div>
          </el-form-item>
        </div>

        <!-- 修改路数配置部分的模板 -->
        <div v-if="channelCount > 0" class="form-section">
          <h3 class="section-title">
            <el-icon><Connection /></el-icon>
            路数配置
            <el-tag type="info" size="small">{{ channelCount }}路设备</el-tag>
            <el-tag type="warning" size="small" style="margin-left: 8px;">可选配置</el-tag>
          </h3>

          <!-- 路数操作按钮 -->
          <!-- 修改路数操作按钮部分 -->
          <div class="channel-operations">
            <div class="operation-buttons">
              <el-button-group>
                <el-button size="small" @click="selectAllChannels" :icon="Check">
                  全部开启
                </el-button>
                <el-button size="small" @click="unselectAllChannels" :icon="Close">
                  全部关闭
                </el-button>
                <el-button size="small" @click="reverseAllChannels" :icon="Refresh">
                  反选
                </el-button>
              </el-button-group>
              <el-button size="small" @click="restoreChannelConfig" :icon="RefreshLeft" v-if="isEdit">
                恢复原配置
              </el-button>
              <el-button size="small" @click="clearAllChannels" :icon="Delete" type="danger">
                清空配置
              </el-button>
            </div>
            <div class="channel-status-info">
              <div class="status-line">
                开启: {{ getChannelStatusCount().on }} |
                关闭: {{ getChannelStatusCount().off }}
              </div>
            </div>
          </div>

          <div class="channel-grid">
            <div
                v-for="i in channelCount"
                :key="i"
                class="channel-item"
                :class="{
          'has-name': hasChannelName(i),
          'has-status': hasChannelStatus(i),
          'configured': hasChannelName(i) || hasChannelStatus(i)
        }"
            >
              <div class="channel-header">
                <div class="channel-info">
                  <span class="channel-number">{{ getChineseNumber(i) }}路</span>
                </div>
                <el-form-item
                    :prop="`channel_names.Tag${i}`"
                    :rules="channelNameRules"
                    class="channel-name-form-item"
                >
                  <el-input
                      v-model="formData.channel_names[`Tag${i}`]"
                      size="small"
                      placeholder="可选：输入路数名称"
                      class="channel-name-input"
                      maxlength="20"
                      clearable
                      @input="handleChannelNameChange(i)"
                      @clear="handleChannelNameClear(i)"
                  />
                </el-form-item>
              </div>

              <div class="channel-control">
                <div class="channel-buttons">
                  <el-button
                      size="small"
                      :type="formData.timing_agreement[`Tag${i}`] === 0 ? 'danger' : ''"
                      :plain="formData.timing_agreement[`Tag${i}`] !== 0"
                      @click="toggleChannelStatus(i, 0)"
                      class="status-button"
                  >
                    <el-icon><SwitchButton /></el-icon>
                    关闭
                  </el-button>
                  <el-button
                      size="small"
                      :type="formData.timing_agreement[`Tag${i}`] === 1 ? 'success' : ''"
                      :plain="formData.timing_agreement[`Tag${i}`] !== 1"
                      @click="toggleChannelStatus(i, 1)"
                      class="status-button"
                  >
                    <el-icon><SwitchButton /></el-icon>
                    开启
                  </el-button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false" :icon="Close">
            取消
          </el-button>
          <el-button type="primary" @click="handleSubmit" :icon="Check" :loading="submitLoading">
            {{ submitLoading ? '保存中...' : '确定' }}
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 详情弹窗 -->
    <el-dialog
        v-model="detailVisible"
        title="策略详情"
        width="900px"
        class="detail-dialog"
    >
      <div class="detail-content" v-if="detailData">
        <div class="detail-section">
          <h4>基本信息</h4>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="策略名称">
              {{ detailData.timing_name }}
            </el-descriptions-item>
            <el-descriptions-item label="执行时间">
              {{ detailData.timing_start_time }}
            </el-descriptions-item>
            <el-descriptions-item label="重复日期" :span="2">
              <el-tag
                  v-for="week in getWeekTags(detailData.weeks)"
                  :key="week.value"
                  :type="week.type"
                  size="small"
                  class="week-tag"
              >
                {{ week.label }}
              </el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="状态">
              <el-tag :type="detailData.timing_state === 1 ? 'success' : 'danger'">
                {{ detailData.timing_state === 1 ? '启用' : '禁用' }}
              </el-tag>
            </el-descriptions-item>
          </el-descriptions>
        </div>

        <div class="detail-section">
          <h4>设备指令</h4>
          <div class="agreement-detail">
            <div
                v-for="item in getAgreementTags(detailData.timing_agreement)"
                :key="item.label"
                class="agreement-item"
            >
              <span class="channel-name">{{ item.label }}</span>
              <el-tag :type="item.type" size="small">{{ item.status }}</el-tag>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup name="zmTime">
import {
  Clock, Search, Refresh, Plus, List, Timer, Edit, View, Delete,
  InfoFilled, Monitor, Location, Collection, Connection, SwitchButton,
  Close, Check, RefreshLeft
} from '@element-plus/icons-vue'
import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios'

// 响应式数据
const searchForm = reactive({
  searchText: ''
})

const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0
})

const tableData = ref([])
const dialogVisible = ref(false)
const detailVisible = ref(false)
const detailData = ref(null)
const dialogTitle = ref('新增策略')
const isEdit = ref(false)
const deviceSelectType = ref('region')
const channelCount = ref(0)
const submitLoading = ref(false)
const regionTreeRef = ref(null)

const requestCache = new Map() // 请求缓存
const requestQueue = new Map() // 请求队列，防止重复请求
const treeKey = ref(0) // 用于强制刷新树组件
let debounceTimer = null

// 请求缓存工具函数
const getCacheKey = (url, params) => {
  return `${url}?${new URLSearchParams(params).toString()}`
}

const getCachedRequest = (url, params) => {
  const key = getCacheKey(url, params)
  return requestCache.get(key)
}

const setCachedRequest = (url, params, data) => {
  const key = getCacheKey(url, params)
  requestCache.set(key, {
    data,
    timestamp: Date.now(),
    expiry: 5 * 60 * 1000 // 5分钟过期
  })
}

const isCacheValid = (cachedItem) => {
  return cachedItem && (Date.now() - cachedItem.timestamp < cachedItem.expiry)
}

// 区域树形数据
const regionTreeData = ref([])
const regionTreeProps = {
  value: 'id',
  label: 'name',
  children: 'children',
  isLeaf: (data) => data.children_count === 0
}

// 存储原始配置用于恢复
const originalChannelConfig = ref({
  timing_agreement: {},
  channel_names: {}
})

const formData = reactive({
  timing_id: null,
  timing_name: '',
  weeks: [],
  timing_start_time: '',
  region_ids: '',
  group_id: '',
  category_id: '',
  device_type_id: '',
  device_ids: [],
  timing_agreement: {},
  channel_names: {},
  region_type: null,
  selectedRegionNode: null  // 新增：保存完整的区域节点信息
})

const categoryOptions = ref([])
const deviceTypeOptions = ref([])
const deviceOptions = ref([])
const formRef = ref()

// 星期数据配置
const weekDays = [
  { value: 2, name: '周一', en: 'MON', isWeekend: false },
  { value: 4, name: '周二', en: 'TUE', isWeekend: false },
  { value: 8, name: '周三', en: 'WED', isWeekend: false },
  { value: 16, name: '周四', en: 'THU', isWeekend: false },
  { value: 32, name: '周五', en: 'FRI', isWeekend: false },
  { value: 64, name: '周六', en: 'SAT', isWeekend: true },
  { value: 128, name: '周日', en: 'SUN', isWeekend: true }
]

// 表单验证规则
const formRules = {
  timing_name: [
    { required: true, message: '请输入策略名称', trigger: 'blur' },
    { min: 2, max: 50, message: '策略名称长度在 2 到 50 个字符', trigger: 'blur' }
  ],
  weeks: [
    {
      required: true,
      validator: (rule, value, callback) => {
        if (!value || value.length === 0) {
          callback(new Error('请选择重复日期'))
        } else {
          callback()
        }
      },
      trigger: 'change'
    }
  ],
  timing_start_time: [
    { required: true, message: '请选择执行时间', trigger: 'change' }
  ],
  region_ids: [
    {
      validator: (rule, value, callback) => {
        if (deviceSelectType.value === 'region' && !value) {
          callback(new Error('请选择所属位置'))
        } else {
          callback()
        }
      },
      trigger: 'change'
    }
  ],
  group_id: [
    {
      validator: (rule, value, callback) => {
        if (deviceSelectType.value === 'group' && !value) {
          callback(new Error('请选择设备分组'))
        } else {
          callback()
        }
      },
      trigger: 'change'
    }
  ],
  category_id: [
    { required: true, message: '请选择设备分类', trigger: 'change' }
  ],
  device_type_id: [
    { required: true, message: '请选择设备型号', trigger: 'change' }
  ],
  device_ids: [
    {
      required: true,
      validator: (rule, value, callback) => {
        if (!value || value.length === 0) {
          callback(new Error('请选择至少一个设备'))
        } else {
          callback()
        }
      },
      trigger: 'change'
    }
  ]
}

// 路数名称验证规则
const channelNameRules = [
  { min: 1, max: 20, message: '路数名称长度在 1 到 20 个字符', trigger: 'blur' }
]

// 计算属性
const weekMap = {
  2: { label: '周一', type: 'primary' },
  4: { label: '周二', type: 'success' },
  8: { label: '周三', type: 'info' },
  16: { label: '周四', type: 'warning' },
  32: { label: '周五', type: 'danger' },
  64: { label: '周六', type: '' },
  128: { label: '周日', type: '' },
  256: { label: '节假日执行', type: 'success' },
  512: { label: '节假日不执行', type: 'danger' }
}

const hasChannelName = (channelNum) => {
  return formData.channel_names[`Tag${channelNum}`] &&
      formData.channel_names[`Tag${channelNum}`].trim() !== ''
}

const hasChannelStatus = (channelNum) => {
  return formData.timing_agreement[`Tag${channelNum}`] !== undefined &&
      formData.timing_agreement[`Tag${channelNum}`] !== null
}

const getNamedChannelCount = () => {
  let count = 0
  for (let i = 1; i <= channelCount.value; i++) {
    if (hasChannelName(i)) {
      count++
    }
  }
  return count
}

const getChannelStatusType = (channelNum) => {
  const status = formData.timing_agreement[`Tag${channelNum}`]
  if (status === 1) return 'success'
  if (status === 0) return 'danger'
  return 'info'
}

const getChannelStatusText = (channelNum) => {
  const status = formData.timing_agreement[`Tag${channelNum}`]
  if (status === 1) return '开启'
  if (status === 0) return '关闭'
  return '未设置'
}

const toggleChannelStatus = (channelNum, targetStatus) => {
  const currentStatus = formData.timing_agreement[`Tag${channelNum}`]

  if (currentStatus === targetStatus) {
    // 如果当前状态与目标状态相同，则取消选择
    formData.timing_agreement[`Tag${channelNum}`] = undefined
  } else {
    // 否则设置为目标状态
    formData.timing_agreement[`Tag${channelNum}`] = targetStatus

    // 只有在没有名称时才设置默认名称
    if (!formData.channel_names[`Tag${channelNum}`] || formData.channel_names[`Tag${channelNum}`].trim() === '') {
      formData.channel_names[`Tag${channelNum}`] = `${channelNum}路`
    }
  }
}

const handleChannelNameChange = (channelNum) => {
  // 当用户输入路数名称时，不自动设置状态
  // 用户可以选择只设置名称而不设置开关状态
}

const handleChannelNameClear = (channelNum) => {
  // 当用户清空路数名称时，只清空名称，不影响状态
  formData.channel_names[`Tag${channelNum}`] = ''
}

// 修改批量操作方法，避免强制设置名称
const selectAllChannels = () => {
  for (let i = 1; i <= channelCount.value; i++) {
    formData.timing_agreement[`Tag${i}`] = 1
    // 只有在没有名称时才设置默认名称
    if (!formData.channel_names[`Tag${i}`] || formData.channel_names[`Tag${i}`].trim() === '') {
      formData.channel_names[`Tag${i}`] = `${i}路`
    }
  }
}

const unselectAllChannels = () => {
  for (let i = 1; i <= channelCount.value; i++) {
    formData.timing_agreement[`Tag${i}`] = 0
    // 只有在没有名称时才设置默认名称
    if (!formData.channel_names[`Tag${i}`] || formData.channel_names[`Tag${i}`].trim() === '') {
      formData.channel_names[`Tag${i}`] = `${i}路`
    }
  }
}

const reverseAllChannels = () => {
  for (let i = 1; i <= channelCount.value; i++) {
    const currentStatus = formData.timing_agreement[`Tag${i}`]
    if (currentStatus === 1) {
      formData.timing_agreement[`Tag${i}`] = 0
    } else if (currentStatus === 0) {
      formData.timing_agreement[`Tag${i}`] = 1
    } else {
      // 如果是未配置状态，设置为开启
      formData.timing_agreement[`Tag${i}`] = 1
      // 只有在没有名称时才设置默认名称
      if (!formData.channel_names[`Tag${i}`] || formData.channel_names[`Tag${i}`].trim() === '') {
        formData.channel_names[`Tag${i}`] = `${i}路`
      }
    }
  }
}

// 修改判断是否有配置的方法
const hasChannelConfig = (channelNum) => {
  return hasChannelName(channelNum) || hasChannelStatus(channelNum)
}

const clearChannelStatus = (channelNum) => {
  formData.timing_agreement[`Tag${channelNum}`] = undefined
}


const isChannelConfigured = (channelNum) => {
  return formData.timing_agreement[`Tag${channelNum}`] !== undefined
}

const getChannelStatusCount = () => {
  let on = 0, off = 0
  for (let i = 1; i <= channelCount.value; i++) {
    if (formData.timing_agreement[`Tag${i}`] === 1) {
      on++
    } else if (formData.timing_agreement[`Tag${i}`] === 0) {
      off++
    }
  }
  return { on, off }
}

const clearAllChannels = () => {
  for (let i = 1; i <= channelCount.value; i++) {
    formData.timing_agreement[`Tag${i}`] = undefined
    formData.channel_names[`Tag${i}`] = ''
  }
}

// 快捷选择相关计算属性
const isAllWeekdaysSelected = computed(() => {
  const weekdays = [2, 4, 8, 16, 32]
  return weekdays.every(day => formData.weeks.includes(day))
})

const isWeekendSelected = computed(() => {
  const weekend = [64, 128]
  return weekend.every(day => formData.weeks.includes(day))
})

const isAllWeekSelected = computed(() => {
  const allWeek = [2, 4, 8, 16, 32, 64, 128]
  return allWeek.every(day => formData.weeks.includes(day))
})

const getSelectedWeekTags = computed(() => {
  return formData.weeks.map(week => ({
    value: week,
    label: weekMap[week]?.label || week,
    type: weekMap[week]?.type || ''
  }))
})

// 设备选择相关计算属性
const isAllDevicesSelected = computed({
  get() {
    return deviceOptions.value.length > 0 && formData.device_ids.length === deviceOptions.value.length
  },
  set(value) {
    if (value) {
      formData.device_ids = deviceOptions.value.map(item => item.value)
    } else {
      formData.device_ids = []
    }
  }
})

const isDeviceIndeterminate = computed(() => {
  return formData.device_ids.length > 0 && formData.device_ids.length < deviceOptions.value.length
})

// 监听设备选择变化
watch(() => formData.device_ids, (newVal) => {
  if (newVal.length > 0 && channelCount.value > 0) {
    // 确保路数配置存在，但不强制设置值
    for (let i = 1; i <= channelCount.value; i++) {
      if (formData.timing_agreement[`Tag${i}`] === undefined) {
        // 保持未配置状态
        formData.timing_agreement[`Tag${i}`] = undefined
      }
      if (formData.channel_names[`Tag${i}`] === undefined) {
        formData.channel_names[`Tag${i}`] = ''
      }
    }
  }
}, { deep: true })

// 工具方法
const getWeekTags = (weeks) => {
  if (!weeks || !Array.isArray(weeks)) return []
  return weeks.map(week => ({
    value: week,
    label: weekMap[week]?.label || week,
    type: weekMap[week]?.type || ''
  }))
}

const getAgreementTags = (agreement, channelNames = null) => {
  if (!agreement) return []
  try {
    const parsed = typeof agreement === 'string' ? JSON.parse(agreement) : agreement

    const result = []
    const processedTags = new Set()

    // 收集所有的Tag和name信息
    const tagStatus = {}
    const nameInfo = {}

    Object.keys(parsed).forEach(key => {
      if (key.startsWith('Tag') || key.startsWith('tag')) {
        const tagKey = key.startsWith('Tag') ? key : `Tag${key.replace('tag', '')}`
        const num = tagKey.replace('Tag', '')
        tagStatus[num] = parseInt(parsed[key])
      } else if (key.startsWith('name')) {
        const num = key.replace('name', '')
        nameInfo[num] = parsed[key]
      }
    })

    // 处理所有有配置的路数
    const allNums = new Set([...Object.keys(tagStatus), ...Object.keys(nameInfo)])

    allNums.forEach(num => {
      if (processedTags.has(num)) return
      processedTags.add(num)

      const hasStatus = tagStatus.hasOwnProperty(num)
      const hasName = nameInfo.hasOwnProperty(num)

      if (hasStatus || hasName) {
        let channelName = nameInfo[num] || `${num}路`
        let label = ''
        let type = 'info'
        let configType = ''
        let icon = null

        if (hasStatus && hasName) {
          // 完整配置：显示名称和状态
          const status = tagStatus[num] === 1 ? '开启' : '关闭'
          label = `${channelName}: ${status}`
          type = tagStatus[num] === 1 ? 'success' : 'danger'
          configType = 'full-config'
          icon = tagStatus[num] === 1 ? 'Check' : 'Close'
        } else if (hasStatus && !hasName) {
          // 仅状态配置：显示默认名称和状态
          const status = tagStatus[num] === 1 ? '开启' : '关闭'
          label = `${num}路: ${status}`
          type = tagStatus[num] === 1 ? 'success' : 'danger'
          configType = 'status-only'
          icon = tagStatus[num] === 1 ? 'Check' : 'Close'
        } else if (hasName && !hasStatus) {
          // 仅名称配置：只显示名称，标记为标识用
          label = `${channelName} `
          type = 'warning'
          configType = 'name-only'
          icon = 'PriceTag'
        }

        result.push({
          label: label,
          status: hasStatus ? (tagStatus[num] === 1 ? '开启' : '关闭') : '标识',
          type: type,
          configType: configType,
          channelName: channelName,
          tagNum: num,
          hasStatus: hasStatus,
          hasName: hasName,
          icon: icon
        })
      }
    })

    // 按路数排序
    result.sort((a, b) => parseInt(a.tagNum) - parseInt(b.tagNum))

    return result
  } catch (e) {
    console.error('解析设备指令失败:', e)
    return []
  }
}

const getChineseNumber = (num) => {
  const numbers = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二']
  return numbers[num] || num
}

const restoreChannelConfig = () => {
  if (isEdit.value && originalChannelConfig.value.timing_agreement) {
    formData.timing_agreement = { ...originalChannelConfig.value.timing_agreement }
    formData.channel_names = { ...originalChannelConfig.value.channel_names }
    ElMessage.success('已恢复原配置')
  }
}

// 星期选择相关方法
const toggleWeekDay = (value) => {
  const index = formData.weeks.indexOf(value)
  if (index > -1) {
    formData.weeks.splice(index, 1)
  } else {
    formData.weeks.push(value)
  }
}

const toggleSpecialOption = (value) => {
  const index = formData.weeks.indexOf(value)
  if (index > -1) {
    formData.weeks.splice(index, 1)
  } else {
    // 如果是节假日相关选项，需要互斥
    if (value === 256) {
      const notRunIndex = formData.weeks.indexOf(512)
      if (notRunIndex > -1) {
        formData.weeks.splice(notRunIndex, 1)
      }
    } else if (value === 512) {
      const runIndex = formData.weeks.indexOf(256)
      if (runIndex > -1) {
        formData.weeks.splice(runIndex, 1)
      }
    }
    formData.weeks.push(value)
  }
}

const removeWeekDay = (value) => {
  const index = formData.weeks.indexOf(value)
  if (index > -1) {
    formData.weeks.splice(index, 1)
  }
}

const selectAllWeekdays = () => {
  const weekdays = [2, 4, 8, 16, 32]
  if (isAllWeekdaysSelected.value) {
    weekdays.forEach(day => {
      const index = formData.weeks.indexOf(day)
      if (index > -1) {
        formData.weeks.splice(index, 1)
      }
    })
  } else {
    weekdays.forEach(day => {
      if (!formData.weeks.includes(day)) {
        formData.weeks.push(day)
      }
    })
  }
}

const selectWeekend = () => {
  const weekend = [64, 128]
  if (isWeekendSelected.value) {
    weekend.forEach(day => {
      const index = formData.weeks.indexOf(day)
      if (index > -1) {
        formData.weeks.splice(index, 1)
      }
    })
  } else {
    weekend.forEach(day => {
      if (!formData.weeks.includes(day)) {
        formData.weeks.push(day)
      }
    })
  }
}

const selectAllWeek = () => {
  const allWeek = [2, 4, 8, 16, 32, 64, 128]
  if (isAllWeekSelected.value) {
    allWeek.forEach(day => {
      const index = formData.weeks.indexOf(day)
      if (index > -1) {
        formData.weeks.splice(index, 1)
      }
    })
  } else {
    allWeek.forEach(day => {
      if (!formData.weeks.includes(day)) {
        formData.weeks.push(day)
      }
    })
  }
}

const clearAllWeeks = () => {
  formData.weeks = []
}

// 设备选择相关方法
const handleSelectAllDevices = (value) => {
  if (value) {
    formData.device_ids = deviceOptions.value.map(item => item.value)
  } else {
    formData.device_ids = []
  }
}

const handleSelectTypeChange = () => {
  // 切换选择方式时清空相关数据
  formData.region_ids = ''
  formData.group_id = ''
  formData.category_id = ''
  formData.device_type_id = ''
  formData.device_ids = []
  categoryOptions.value = []
  deviceTypeOptions.value = []
  deviceOptions.value = []
  channelCount.value = 0
  formData.timing_agreement = {}
  formData.channel_names = {}
}

const handleLocationOrGroupChange = async (value, node) => {
  // 清空相关数据
  formData.category_id = ''
  formData.device_type_id = ''
  formData.device_ids = []
  deviceTypeOptions.value = []
  deviceOptions.value = []
  channelCount.value = 0
  formData.timing_agreement = {}
  formData.channel_names = {}

  if (value && node) {
    // 从选中的节点获取完整的数据
    formData.region_ids = node.id || node.value  // 获取选中节点的id
    formData.region_type = node.type             // 获取选中节点的type

    console.log('选中的区域数据:', {
      id: formData.region_ids,
      type: formData.region_type,
      node: node
    })

    await fetchDeviceCategories()
  } else {
    // 如果没有选中值，清空相关字段
    formData.region_ids = ''
    formData.region_type = null
  }
}

// 处理区域选择变化
const handleRegionSelectChange = async (value) => {
  // 清除之前的防抖定时器
  if (debounceTimer) {
    clearTimeout(debounceTimer)
  }

  debounceTimer = setTimeout(async () => {
    console.log('区域选择变化:', value)

    if (value) {
      // 获取选中节点的完整数据
      const selectedNode = regionTreeRef.value?.getCurrentNode?.() ||
          regionTreeRef.value?.getNode?.(value)?.data

      if (selectedNode) {
        formData.region_ids = selectedNode.id
        formData.region_type = selectedNode.type
        formData.selectedRegionNode = selectedNode

        console.log('区域选择变化:', {
          value: value,
          selectedNode: selectedNode
        })

        // 清空相关数据
        resetDeviceSelections()

        // 获取设备分类
        await fetchDeviceCategories()
      }
    } else {
      // 清空选择
      formData.region_ids = ''
      formData.region_type = null
      formData.selectedRegionNode = null
      resetDeviceSelections()
    }
  }, 300) // 300ms 防抖
}

// 重置设备相关选择
const resetDeviceSelections = () => {
  formData.category_id = ''
  formData.device_type_id = ''
  formData.device_ids = []
  deviceTypeOptions.value = []
  deviceOptions.value = []
  channelCount.value = 0
  formData.timing_agreement = {}
  formData.channel_names = {}
}

// 丰富节点信息，获取父级信息
const enrichNodeWithParentInfo = async (node) => {
  try {
    const enrichedNode = { ...node }

    // 如果是房间类型且没有parentName，尝试获取
    if (node.type === 3 && !node.parentName && node.parentId) {
      const parentNode = await getNodeById(node.parentId)
      if (parentNode) {
        enrichedNode.parentName = parentNode.name
      }
    }

    // 确保有建筑信息
    if (!enrichedNode.buildingName && enrichedNode.BuildingId) {
      const buildingNode = await getNodeById(enrichedNode.BuildingId)
      if (buildingNode) {
        enrichedNode.buildingName = buildingNode.name
      }
    }

    return enrichedNode
  } catch (error) {
    console.error('丰富节点信息失败:', error)
    return node
  }
}

// 根据ID获取节点信息（可能需要调用API）
const getNodeById = async (nodeId) => {
  try {
    // 首先在已加载的树数据中查找
    const foundNode = findNodeInTree(regionTreeData.value, nodeId)
    if (foundNode) {
      return foundNode
    }

    // 如果在树中找不到，可能需要调用API获取
    // 这里可以根据实际情况调用相应的API
    return null
  } catch (error) {
    console.error('获取节点信息失败:', error)
    return null
  }
}

// 强制刷新树形选择器
const refreshTreeSelect = async () => {
  if (regionTreeRef.value) {
    try {
      // 清空树数据
      regionTreeData.value = []
      await nextTick()

      // 重新加载根节点
      await loadRootRegions()
      await nextTick()

      // 重新设置选中值
      if (formData.region_ids) {
        regionTreeRef.value.setCurrentKey(formData.region_ids)
      }
    } catch (error) {
      console.error('刷新树形选择器失败:', error)
    }
  }
}

// 区域树形加载方法
const loadRegionNode = async (node, resolve) => {
  try {
    let params = {}
    let url = `${__LOCAL_API__}/illuminating/getBuildingRegionRoomTree`

    if (node.level === 0) {
      params = {}
    } else if (node.level === 1) {
      params = { building_id: node.data.id }
    } else {
      params = {
        building_id: node.data.BuildingId || getBuildingIdFromPath(node),
        region_parent_id: node.data.id
      }
    }

    // 检查缓存
    const cacheKey = getCacheKey(url, params)
    const cachedData = getCachedRequest(url, params)

    if (isCacheValid(cachedData)) {
      console.log('使用缓存数据:', cacheKey)
      resolve(cachedData.data)
      return
    }

    // 检查是否正在请求中
    if (requestQueue.has(cacheKey)) {
      console.log('等待现有请求:', cacheKey)
      const existingRequest = requestQueue.get(cacheKey)
      const result = await existingRequest
      resolve(result)
      return
    }

    // 创建新请求
    const requestPromise = axios.get(url, { params }).then(response => {
      if (response.data.code === 200) {
        const data = response.data.data || []
        const treeData = data.map(item => ({
          ...item,
          id: item.id,
          type: item.type,
          BuildingId: item.BuildingId || params.building_id || item.id,
          children: item.children_count > 0 ? [] : undefined,
          RegionId: item.RegionId,
          IsLastRegion: item.IsLastRegion,
          RegionType: item.RegionType,
          parentName: item.parentName,
          parentId: item.parentId,
          label: item.name,
          value: item.id
        }))

        // 缓存结果
        setCachedRequest(url, params, treeData)
        return treeData
      } else {
        throw new Error(response.data.message || '获取区域数据失败')
      }
    }).finally(() => {
      // 请求完成后从队列中移除
      requestQueue.delete(cacheKey)
    })

    // 将请求加入队列
    requestQueue.set(cacheKey, requestPromise)

    const result = await requestPromise
    resolve(result)

  } catch (error) {
    console.error('获取区域数据失败:', error)
    ElMessage.error('获取区域数据失败，请检查网络连接')
    resolve([])
  }
}

// 辅助函数：从节点路径中获取建筑ID
const getBuildingIdFromPath = (node) => {
  let currentNode = node
  while (currentNode && currentNode.level > 1) {
    currentNode = currentNode.parent
  }
  return currentNode?.data?.BuildingId || currentNode?.data?.id
}

// 为编辑模式加载完整的区域路径
const loadRegionPathForEdit = async (regionId, regionType, buildingId, parentId, regionName, fullPath) => {
  try {
    console.log('加载编辑区域路径:', { regionId, regionType, buildingId, parentId, regionName, fullPath })

    // 增加树组件的key，强制重新渲染
    treeKey.value++

    // 等待组件重新渲染
    await nextTick()

    // 1. 首先加载根节点（建筑列表）- 只在没有数据时加载
    if (regionTreeData.value.length === 0) {
      await loadRootRegions()
      await nextTick()
    }

    // 2. 根据类型逐级展开节点
    if (regionType >= 2 && buildingId) {
      await expandBuildingNode(buildingId)
      await nextTick()
    }

    if (regionType === 3 && parentId) {
      await expandRegionNode(parentId, buildingId)
      await nextTick()
    }

    // 3. 设置选中值
    formData.region_ids = regionId

    // 4. 手动设置树的当前节点
    if (regionTreeRef.value) {
      try {
        regionTreeRef.value.setCurrentKey(regionId)
      } catch (e) {
        console.warn('setCurrentKey失败:', e)
      }
    }

    console.log('区域路径加载完成')

  } catch (error) {
    console.error('加载编辑区域路径失败:', error)
  }
}

// 加载根节点区域
const loadRootRegions = async () => {
  try {
    // 如果已经有数据，直接返回，避免重复加载
    if (regionTreeData.value.length > 0) {
      return
    }

    const response = await axios.get(`${__LOCAL_API__}/illuminating/getBuildingRegionRoomTree`)

    if (response.data.code === 200) {
      const data = response.data.data || []

      // 去重处理
      const uniqueData = data.filter((item, index, self) =>
          index === self.findIndex(t => t.id === item.id)
      )

      regionTreeData.value = uniqueData.map(item => ({
        ...item,
        id: item.id,
        type: item.type,
        BuildingId: item.id, // 建筑的BuildingId就是自己的id
        children: item.children_count > 0 ? [] : undefined,
        RegionId: item.RegionId,
        IsLastRegion: item.IsLastRegion,
        RegionType: item.RegionType,
        parentName: item.parentName,
        parentId: item.parentId || 0,
        label: item.name,
        value: item.id
      }))
    }
  } catch (error) {
    console.error('加载根节点失败:', error)
  }
}

// 展开建筑节点
const expandBuildingNode = async (buildingId) => {
  try {
    const response = await axios.get(`${__LOCAL_API__}/illuminating/getBuildingRegionRoomTree`, {
      params: { building_id: buildingId }
    })

    if (response.data.code === 200) {
      const data = response.data.data || []

      // 找到对应的建筑节点并更新其children
      const updateBuildingChildren = (nodes) => {
        for (let node of nodes) {
          if (node.id === buildingId && node.type === 1) {
            node.children = data.map(item => ({
              ...item,
              id: item.id,
              type: item.type,
              BuildingId: buildingId,
              children: item.children_count > 0 ? [] : undefined,
              RegionId: item.RegionId,
              IsLastRegion: item.IsLastRegion,
              RegionType: item.RegionType,
              parentName: item.parentName,
              parentId: item.parentId,
              label: item.name,
              value: item.id
            }))
            return true
          }
          if (node.children && node.children.length > 0) {
            if (updateBuildingChildren(node.children)) {
              return true
            }
          }
        }
        return false
      }

      updateBuildingChildren(regionTreeData.value)
    }
  } catch (error) {
    console.error('展开建筑节点失败:', error)
  }
}

// 展开区域节点
const expandRegionNode = async (regionId, buildingId) => {
  try {
    const response = await axios.get(`${__LOCAL_API__}/illuminating/getBuildingRegionRoomTree`, {
      params: {
        building_id: buildingId,
        region_parent_id: regionId
      }
    })

    if (response.data.code === 200) {
      const data = response.data.data || []

      // 找到对应的区域节点并更新其children
      const updateRegionChildren = (nodes) => {
        for (let node of nodes) {
          if (node.id === regionId && node.type === 2) {
            node.children = data.map(item => ({
              ...item,
              id: item.id,
              type: item.type,
              BuildingId: buildingId,
              children: item.children_count > 0 ? [] : undefined,
              RegionId: item.RegionId,
              IsLastRegion: item.IsLastRegion,
              RegionType: item.RegionType,
              parentName: item.parentName,
              parentId: item.parentId,
              label: item.name,
              value: item.id
            }))
            return true
          }
          if (node.children && node.children.length > 0) {
            if (updateRegionChildren(node.children)) {
              return true
            }
          }
        }
        return false
      }

      updateRegionChildren(regionTreeData.value)
    }
  } catch (error) {
    console.error('展开区域节点失败:', error)
  }
}

// 事件处理方法
const handleSearch = () => {
  pagination.currentPage = 1
  fetchData()
}

const handleReset = () => {
  searchForm.searchText = ''
  handleSearch()
}

const handleAdd = () => {
  dialogTitle.value = '新增策略'
  isEdit.value = false
  resetForm()
  dialogVisible.value = true
}

const handleEdit = async (row) => {
  try {
    dialogTitle.value = '编辑策略'
    isEdit.value = true

    // 先重置表单和清空树数据
    resetForm()

    // 先调用详情接口获取完整数据
    const response = await axios.get(`${__LOCAL_API__}/illuminating/getTimingId`, {
      params: { timing_id: row.timing_id }
    })

    if (response.data.code === 200) {
      const data = response.data.data

      // 解析region_ids，格式为 "2-5-1=09A/09A"
      let regionId = ''
      let regionType = 1
      let buildingId = null
      let parentId = 0
      let selectedRegionNode = null
      let regionName = ''
      let fullPath = ''

      if (data.region_ids) {
        const parts = data.region_ids.split('=')
        fullPath = parts[1] || ''
        const idParts = parts[0].split('-')

        if (idParts.length >= 2) {
          regionType = parseInt(idParts[0])
          regionId = parseInt(idParts[1])

          if (idParts.length > 2) {
            buildingId = parseInt(idParts[2])
          }

          // 从完整路径中解析当前节点名称
          const pathParts = fullPath.split('/')
          if (regionType === 1) {
            regionName = pathParts[0] || ''
            buildingId = regionId
          } else if (regionType === 2) {
            regionName = pathParts[pathParts.length - 1] || ''
          } else if (regionType === 3) {
            regionName = pathParts[pathParts.length - 1] || ''
          }

          selectedRegionNode = {
            id: regionId,
            name: regionName,
            type: regionType,
            parentId: parentId,
            RegionId: parentId || regionId,
            BuildingId: buildingId,
            buildingName: pathParts[0] || '',
            parentName: pathParts.length > 2 ? pathParts[pathParts.length - 2] : '',
            fullPath: fullPath
          }
        }
      }

      // 设置选择方式
      deviceSelectType.value = data.group_id ? 'group' : 'region'

      // 填充表单数据
      Object.assign(formData, {
        timing_id: data.timing_id,
        timing_name: data.timing_name,
        weeks: data.weeks || [],
        timing_start_time: data.timing_start_time,
        region_ids: regionId,
        region_type: regionType,
        selectedRegionNode: selectedRegionNode,
        group_id: data.group_id || '',
        category_id: data.category_id || '',
        device_type_id: data.device_type_id || '',
        device_ids: data.device_ids || []
      })

      // 处理路数配置
      await handleTimingAgreementData(data)

      // 先打开对话框
      dialogVisible.value = true

      // 等待DOM更新后再加载数据
      await nextTick()

      // 然后异步加载区域树和其他数据
      await Promise.all([
        loadRegionPathForEdit(regionId, regionType, buildingId, parentId, regionName, fullPath),
        loadEditData()
      ])

    } else {
      ElMessage.error(response.data.message || '获取策略详情失败')
    }
  } catch (error) {
    console.error('加载编辑数据失败:', error)
    ElMessage.error('加载数据失败')
  }
}

// 处理设备指令数据
const handleTimingAgreementData = async (data) => {
  if (data.timing_agreement) {
    try {
      const agreement = typeof data.timing_agreement === 'string'
          ? JSON.parse(data.timing_agreement)
          : data.timing_agreement

      console.log('原始设备配置:', agreement)

      // 分离Tag配置和name配置
      const tagAgreement = {}
      const channelNames = {}
      let maxTagNum = 0

      // 先初始化所有路数为未配置状态
      for (let i = 1; i <= channelCount.value; i++) {
        tagAgreement[`Tag${i}`] = undefined
        channelNames[`Tag${i}`] = ''
      }

      Object.keys(agreement).forEach(key => {
        if (key.startsWith('Tag')) {
          // 直接使用Tag1格式存储
          tagAgreement[key] = parseInt(agreement[key])
          const tagNum = parseInt(key.replace('Tag', ''))
          maxTagNum = Math.max(maxTagNum, tagNum)
        } else if (key.startsWith('name')) {
          const tagNum = key.replace('name', '')
          channelNames[`Tag${tagNum}`] = agreement[key]
        }
      })

      // 如果没有从agreement中获取到name配置，尝试从设备数据中获取
      if (Object.keys(channelNames).filter(key => channelNames[key]).length === 0 && data.devices && data.devices.length > 0) {
        const firstDevice = data.devices[0]
        if (firstDevice.devices_json_object) {
          try {
            const deviceData = JSON.parse(firstDevice.devices_json_object)
            for (let i = 1; i <= maxTagNum; i++) {
              if (deviceData[`name${i}`] && !channelNames[`Tag${i}`]) {
                channelNames[`Tag${i}`] = deviceData[`name${i}`]
              }
            }
          } catch (e) {
            console.error('解析设备数据失败:', e)
          }
        }
      }

      formData.timing_agreement = tagAgreement
      formData.channel_names = channelNames
      channelCount.value = Math.max(maxTagNum, channelCount.value)

      // 保存原始配置用于恢复
      originalChannelConfig.value = {
        timing_agreement: { ...tagAgreement },
        channel_names: { ...channelNames }
      }

      console.log('解析后的配置:', {
        tagAgreement,
        channelNames,
        maxTagNum
      })

    } catch (e) {
      console.error('解析设备指令失败:', e)
    }
  }
}

// 加载编辑数据的辅助方法
const loadEditData = async () => {
  try {
    // 1. 先加载设备分类
    await fetchDeviceCategories()

    // 2. 如果有分类ID，加载设备型号
    if (formData.category_id) {
      await fetchDeviceTypes()
    }

    // 3. 如果有设备型号ID，加载设备列表和路数信息
    if (formData.device_type_id) {
      await Promise.all([
        fetchDevices(),
        fetchChannelCount(formData.device_type_id)
      ])
    }
  } catch (error) {
    console.error('加载编辑数据失败:', error)
    throw error
  }
}

const handleDetail = (row) => {
  detailData.value = row
  detailVisible.value = true
}

const handleStatusChange = async (row) => {
  try {
    await updateStrategyStatus(row.timing_id, row.timing_state)
    ElMessage.success(`策略已${row.timing_state === 1 ? '启用' : '禁用'}`)
  } catch (error) {
    // 恢复原状态
    row.timing_state = row.timing_state === 1 ? 0 : 1
    ElMessage.error('状态更新失败')
  }
}

const handleSizeChange = (size) => {
  pagination.pageSize = size
  fetchData()
}

const handleCurrentChange = (page) => {
  pagination.currentPage = page
  fetchData()
}

const handleDialogClose = () => {
  resetForm()
}

const handleCategoryChange = (categoryId) => {
  formData.device_type_id = ''
  formData.device_ids = []
  deviceTypeOptions.value = []
  deviceOptions.value = []
  channelCount.value = 0
  formData.timing_agreement = {}
  formData.channel_names = {}

  if (categoryId) {
    fetchDeviceTypes()
  }
}

const handleDeviceTypeChange = (deviceTypeId) => {
  formData.device_ids = []
  deviceOptions.value = []
  channelCount.value = 0
  formData.timing_agreement = {}
  formData.channel_names = {}

  if (deviceTypeId) {
    fetchDevices()
    fetchChannelCount(deviceTypeId)
  }
}

const handleDeviceChange = (deviceIds) => {
  // 设备选择变化时的处理
  if (deviceIds.length === 0) {
    // 如果没有选择设备，清空路数配置
    formData.timing_agreement = {}
    formData.channel_names = {}
  }
}

const handleSubmit = async () => {
  try {
    await formRef.value.validate()

    submitLoading.value = true

    // 构建region_ids格式
    let regionIdsStr = ''
    if (deviceSelectType.value === 'region' && formData.selectedRegionNode) {
      regionIdsStr = buildRegionIdsString(formData.selectedRegionNode)
    }

    // 构建完整的设备控制配置
    const fullAgreement = {}
    const fullCommitAgreement = {}

    // 处理所有有配置的路数（包括只有名称的和只有状态的）
    for (let i = 1; i <= channelCount.value; i++) {
      const tagKey = `Tag${i}`
      const hasName = hasChannelName(i)
      const hasStatus = hasChannelStatus(i)

      if (hasName || hasStatus) {
        // 如果有状态配置，添加状态
        if (hasStatus) {
          const lowerKey = tagKey.toLowerCase() // Tag1 -> tag1
          const value = formData.timing_agreement[tagKey]
          fullAgreement[lowerKey] = value.toString()
          fullCommitAgreement[lowerKey] = value.toString()
        }

        // 如果有名称配置，添加名称
        if (hasName) {
          const nameKey = tagKey.replace('Tag', 'name') // Tag1 -> name1
          const nameValue = formData.channel_names[tagKey]
          fullAgreement[nameKey] = nameValue
          fullCommitAgreement[nameKey] = nameValue
        } else if (hasStatus) {
          // 如果只有状态没有名称，使用默认名称
          /*const nameKey = tagKey.replace('Tag', 'name')
          const defaultName = `${i}路`
          fullAgreement[nameKey] = defaultName
          fullCommitAgreement[nameKey] = defaultName*/
        }
      }
    }

    console.log('完整的设备配置:', fullAgreement)

    // 构建提交数据
    const submitData = {
      timing_name: formData.timing_name,
      weeks: formData.weeks,
      timing_start_time: formData.timing_start_time,
      device_ids: formData.device_ids,
      timing_agreement: JSON.stringify(fullAgreement),
      commit_agreement: JSON.stringify(fullCommitAgreement),
      timing_state: 1,
      radio: 0
    }

    // 根据选择方式添加不同的参数
    if (deviceSelectType.value === 'region') {
      submitData.region_ids = regionIdsStr
    } else {
      submitData.group_id = formData.group_id
    }

    // 如果是编辑模式，添加timing_id
    if (isEdit.value) {
      submitData.timing_id = formData.timing_id
    }

    console.log('提交的数据:', submitData)

    if (isEdit.value) {
      await updateStrategy(submitData)
      ElMessage.success('编辑成功')
    } else {
      await createStrategy(submitData)
      ElMessage.success('新增成功')
    }

    dialogVisible.value = false
    fetchData()
  } catch (error) {
    if (error.message) {
      ElMessage.error(error.message)
    } else {
      console.error('表单验证失败:', error)
    }
  } finally {
    submitLoading.value = false
  }
}

// 查找选中的区域节点
const findSelectedRegionNode = (regionId) => {
  // 从区域树中查找选中的节点
  return findNodeInTree(regionTreeData.value, regionId)
}

// 构建region_ids字符串
const buildRegionIdsString = (regionNode) => {
  try {
    console.log('构建region_ids，节点数据:', regionNode)

    // 根据节点数据构建ID字符串
    let idParts = []

    // 添加type
    if (regionNode.type !== undefined) {
      idParts.push(regionNode.type)
    }

    // 添加id
    if (regionNode.id !== undefined) {
      idParts.push(regionNode.id)
    }

    // 根据类型添加第三个参数
    if (regionNode.type === 2 && regionNode.BuildingId !== undefined) {
      // 区域类型：type-id-buildingId
      idParts.push(regionNode.BuildingId)
    } else if (regionNode.type === 3 && regionNode.RegionId !== undefined) {
      // 房间类型：type-id-regionId
      idParts.push(regionNode.RegionId)
    }

    // 构建完整的层级路径名称
    const fullPath = buildFullPathName(regionNode)

    // 组装最终的region_ids字符串
    const idString = idParts.join('-')
    const result = `${idString}=${fullPath}`

    console.log('构建的region_ids:', result)

    return result
  } catch (error) {
    console.error('构建region_ids失败:', error)
    return `${regionNode.id}=${regionNode.name || ''}`
  }
}

// 构建完整的层级路径名称（优化版）
const buildFullPathName = (regionNode) => {
  try {
    const pathParts = []

    // 根据节点类型构建路径
    if (regionNode.type === 1) {
      // 建筑类型：只显示建筑名称
      pathParts.push(regionNode.name)
    } else if (regionNode.type === 2) {
      // 区域类型：建筑名称/区域名称
      if (regionNode.buildingName) {
        pathParts.push(regionNode.buildingName)
      } else {
        // 如果没有buildingName，尝试从树中获取
        const buildingName = getBuildingNameById(regionNode.BuildingId)
        if (buildingName) {
          pathParts.push(buildingName)
        }
      }
      pathParts.push(regionNode.name)
    } else if (regionNode.type === 3) {
      // 房间类型：建筑名称/父区域名称/房间名称
      if (regionNode.buildingName) {
        pathParts.push(regionNode.buildingName)
      } else {
        const buildingName = getBuildingNameById(regionNode.BuildingId)
        if (buildingName) {
          pathParts.push(buildingName)
        }
      }

      // 添加父区域名称
      if (regionNode.parentName) {
        pathParts.push(regionNode.parentName)
      }

      // 添加当前房间名称
      pathParts.push(regionNode.name)
    }

    return pathParts.join('/')
  } catch (error) {
    console.error('构建路径名称失败:', error)
    return regionNode.name || ''
  }
}

// 根据建筑ID获取建筑名称
const getBuildingNameById = (buildingId) => {
  try {
    // 从区域树数据中查找建筑名称
    const building = findBuildingInTree(regionTreeData.value, buildingId)
    return building ? building.name : null
  } catch (error) {
    console.error('获取建筑名称失败:', error)
    return null
  }
}

// 在树中查找建筑
const findBuildingInTree = (treeData, buildingId) => {
  for (const node of treeData) {
    if (node.type === 1 && node.id === buildingId) {
      return node
    }
    if (node.children && node.children.length > 0) {
      const found = findBuildingInTree(node.children, buildingId)
      if (found) return found
    }
  }
  return null
}

// 递归查找树节点
const findNodeInTree = (treeData, targetId) => {
  for (const node of treeData) {
    if (node.id === targetId) {
      return node
    }
    if (node.children && node.children.length > 0) {
      const found = findNodeInTree(node.children, targetId)
      if (found) return found
    }
  }
  return null
}

const resetForm = () => {
  // 清除防抖定时器
  if (debounceTimer) {
    clearTimeout(debounceTimer)
    debounceTimer = null
  }

  Object.assign(formData, {
    timing_id: null,
    timing_name: '',
    weeks: [],
    timing_start_time: '',
    region_ids: '',
    group_id: '',
    category_id: '',
    device_type_id: '',
    device_ids: [],
    timing_agreement: {},
    channel_names: {},
    region_type: null,
    selectedRegionNode: null
  })

  channelCount.value = 0
  deviceSelectType.value = 'region'
  categoryOptions.value = []
  deviceTypeOptions.value = []
  deviceOptions.value = []

  // 清空树形数据缓存
  regionTreeData.value = []

  // 增加树组件的key，强制重新渲染
  treeKey.value++

  originalChannelConfig.value = {
    timing_agreement: {},
    channel_names: {}
  }

  // 清除表单验证
  if (formRef.value) {
    formRef.value.clearValidate()
  }
}

// API 调用方法 (获取定时策略列表)
const fetchData = async () => {
  try {
    const params = {
      currentPage: pagination.currentPage,
      pageSize: pagination.pageSize,
      searchText: searchForm.searchText
    }

    const response = await axios.get(`${__LOCAL_API__}/illuminating/getDeviceOrgid`, {
      params
    })

    if (response.data.code === 200) {
      tableData.value = response.data.data.Timing || []
      pagination.total = response.data.data.count || 0
    } else {
      ElMessage.error(response.data.message || '获取数据失败')
    }
  } catch (error) {
    console.error('获取列表数据失败:', error)
    ElMessage.error('获取数据失败，请检查网络连接')
  }
}

// 获取设备分类
const fetchDeviceCategories = async () => {
  try {
    // 必须有id和type才能查询
    if (!formData.region_ids || !formData.region_type) {
      console.log('缺少必要参数:', {
        region_ids: formData.region_ids,
        region_type: formData.region_type
      })
      return
    }

    // 构建请求参数
    const params = {
      id: formData.region_ids,
      type: formData.region_type
    }

    console.log('fetchDeviceCategories 请求参数:', params)

    const response = await axios.get(`${__LOCAL_API__}/illuminating/categoryPart`, {
      params
    })

    if (response.data.code === 200) {
      const categories = response.data.data.BaseDevicesCategorys || []
      categoryOptions.value = categories.map(item => ({
        label: item.category_name,
        value: item.category_id
      }))
      console.log('获取到的设备分类:', categoryOptions.value)
    } else {
      ElMessage.error(response.data.message || '获取设备分类失败')
    }
  } catch (error) {
    console.error('获取设备分类失败:', error)
    ElMessage.error('获取设备分类失败，请检查网络连接')
  }
}

// 获取设备型号
const fetchDeviceTypes = async () => {
  try {
    const params = {
      category_id: formData.category_id,
      devices_enabled: -1
    }

    // 根据选择方式添加不同的参数
    if (deviceSelectType.value === 'region' && formData.region_ids) {
      params.id = formData.region_ids
      params.type = formData.region_type  // 使用从区域选择中获取的真实type值
    } else if (deviceSelectType.value === 'group' && formData.group_id) {
      params.id = formData.group_id
      params.type = 'group'  // 或者根据实际情况设置group的type值
    }

    console.log('fetchDeviceTypes 请求参数:', params)

    const response = await axios.get(`${__LOCAL_API__}/illuminating/getTypeFind`, {
      params
    })

    if (response.data.code === 200) {
      const deviceTypes = response.data.data.baseDeviceType || []
      deviceTypeOptions.value = deviceTypes.map(item => ({
        label: item.devices_type_name,
        value: item.devices_type_id,
        code: item.devices_type_code,
        // 从dialect_agreements中获取路数信息
        channelCount: getChannelCountFromDialects(item.dialect_agreements || [])
      }))
    } else {
      ElMessage.error(response.data.message || '获取设备型号失败')
      deviceTypeOptions.value = []
    }
  } catch (error) {
    console.error('获取设备型号失败:', error)
    ElMessage.error('获取设备型号失败，请检查网络连接')
    deviceTypeOptions.value = []
  }
}

// 从dialect_agreements中获取路数信息
const getChannelCountFromDialects = (dialects) => {
  const tagDialects = dialects.filter(dialect =>
      dialect.dialect_key && dialect.dialect_key.startsWith('Tag')
  )

  if (tagDialects.length > 0) {
    // 获取最大的Tag数字
    const maxTag = Math.max(...tagDialects.map(dialect => {
      const match = dialect.dialect_key.match(/Tag(\d+)/)
      return match ? parseInt(match[1]) : 0
    }))
    return maxTag
  }

  // 默认返回8路
  return 8
}

// 获取设备列表
const fetchDevices = async () => {
  try {
    const params = {
      device_type_id: formData.device_type_id,
      devices_enabled: -1
    }

    // 根据选择方式添加不同的参数
    if (deviceSelectType.value === 'region' && formData.region_ids) {
      params.position_id = formData.region_ids
      params.position_type = formData.region_type  // 使用真实的type值，而不是固定的'region'
    } else if (deviceSelectType.value === 'group' && formData.group_id) {
      params.position_id = formData.group_id
      params.position_type = 'group'  // 或者根据实际情况设置
    }

    console.log('fetchDevices 请求参数:', params)

    const response = await axios.get(`${__LOCAL_API__}/illuminating/deviceAllMini`, {
      params
    })

    if (response.data.code === 200) {
      const devices = response.data.data.devices || []
      deviceOptions.value = devices.map(item => ({
        label: `${item.devices_name} (${item.full_region_name}/${item.room_name})`,
        value: item.devices_id,
        deviceInfo: item
      }))
    } else {
      ElMessage.error(response.data.message || '获取设备列表失败')
      deviceOptions.value = []
    }
  } catch (error) {
    console.error('获取设备列表失败:', error)
    ElMessage.error('获取设备列表失败，请检查网络连接')
    deviceOptions.value = []
  }
}

// 获取设备路数信息
const fetchChannelCount = async (deviceTypeId) => {
  try {
    const deviceType = deviceTypeOptions.value.find(item => item.value === deviceTypeId)
    if (deviceType && deviceType.channelCount) {
      channelCount.value = deviceType.channelCount

      // 初始化路数配置（设置为未配置状态）
      if (!isEdit.value || Object.keys(formData.timing_agreement).length === 0) {
        const agreement = {}
        const names = {}
        for (let i = 1; i <= deviceType.channelCount; i++) {
          agreement[`Tag${i}`] = undefined // 设置为未配置状态
          names[`Tag${i}`] = '' // 名称为空
        }
        formData.timing_agreement = agreement
        formData.channel_names = names
      }
    } else {
      // 如果没有找到路数信息，使用默认值
      channelCount.value = 8
      if (!isEdit.value || Object.keys(formData.timing_agreement).length === 0) {
        const agreement = {}
        const names = {}
        for (let i = 1; i <= 8; i++) {
          agreement[`Tag${i}`] = undefined // 设置为未配置状态
          names[`Tag${i}`] = '' // 名称为空
        }
        formData.timing_agreement = agreement
        formData.channel_names = names
      }
    }
  } catch (error) {
    console.error('获取路数信息失败:', error)
    // 使用默认路数
    channelCount.value = 8
    if (!isEdit.value || Object.keys(formData.timing_agreement).length === 0) {
      const agreement = {}
      const names = {}
      for (let i = 1; i <= 8; i++) {
        agreement[`Tag${i}`] = undefined // 设置为未配置状态
        names[`Tag${i}`] = '' // 名称为空
      }
      formData.timing_agreement = agreement
      formData.channel_names = names
    }
  }
}

// 创建定时策略
const createStrategy = async (data) => {
  try {
    const response = await axios.post(`${__LOCAL_API__}/illuminating/timingSave`, data, {
      headers: {
        'Content-Type': 'application/json'
      }
    })

    if (response.data.code === 200) {
      return response.data
    } else {
      throw new Error(response.data.message || '创建策略失败')
    }
  } catch (error) {
    console.error('创建策略失败:', error)
    throw new Error(error.response?.data?.message || error.message || '创建策略失败')
  }
}

// 更新定时策略
const updateStrategy = async (data) => {
  try {
    const response = await axios.post(`${__LOCAL_API__}/illuminating/timingSave`, data, {
      headers: {
        'Content-Type': 'application/json'
      }
    })

    if (response.data.code === 200) {
      return response.data
    } else {
      throw new Error(response.data.message || '更新策略失败')
    }
  } catch (error) {
    console.error('更新策略失败:', error)
    throw new Error(error.response?.data?.message || error.message || '更新策略失败')
  }
}

// 更新策略状态
const updateStrategyStatus = async (timingId, status) => {
  try {
    const params = {
      timing_id: timingId,
      timing_state: status
    }

    const response = await axios.get(`${__LOCAL_API__}/illuminating/changeState`, {
      params
    })

    if (response.data.code === 200) {
      return response.data
    } else {
      throw new Error(response.data.message || '状态更新失败')
    }
  } catch (error) {
    console.error('更新状态失败:', error)
    throw new Error(error.response?.data?.message || error.message || '状态更新失败')
  }
}

// 删除定时策略
const deleteStrategy = async (timingId) => {
  try {
    const response = await axios.delete(`${__LOCAL_API__}/illuminating/deleteTimingStrategy/${timingId}`)

    if (response.data.code === 200) {
      return response.data
    } else {
      throw new Error(response.data.message || '删除策略失败')
    }
  } catch (error) {
    console.error('删除策略失败:', error)
    throw new Error(error.response?.data?.message || error.message || '删除策略失败')
  }
}

// 批量操作方法
const handleBatchDelete = async () => {
  const selectedRows = tableData.value.filter(row => row.selected)

  if (selectedRows.length === 0) {
    ElMessage.warning('请选择要删除的策略')
    return
  }

  try {
    await ElMessageBox.confirm(
        `确定要删除选中的 ${selectedRows.length} 个策略吗？`,
        '批量删除',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
    )

    const deletePromises = selectedRows.map(row => deleteStrategy(row.timing_id))
    await Promise.all(deletePromises)

    ElMessage.success('批量删除成功')
    fetchData()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('批量删除失败')
    }
  }
}

const handleBatchEnable = async (enable = true) => {
  const selectedRows = tableData.value.filter(row => row.selected)

  if (selectedRows.length === 0) {
    ElMessage.warning('请选择要操作的策略')
    return
  }

  try {
    const action = enable ? '启用' : '禁用'
    await ElMessageBox.confirm(
        `确定要${action}选中的 ${selectedRows.length} 个策略吗？`,
        `批量${action}`,
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
    )

    const updatePromises = selectedRows.map(row =>
        updateStrategyStatus(row.timing_id, enable ? 1 : 0)
    )
    await Promise.all(updatePromises)

    ElMessage.success(`批量${action}成功`)
    fetchData()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error(`批量${enable ? '启用' : '禁用'}失败`)
    }
  }
}

// 导出功能
const handleExport = async () => {
  try {
    const response = await axios.get(`${__LOCAL_API__}/illuminating/exportTimingStrategies`, {
      params: {
        searchText: searchForm.searchText
      },
      responseType: 'blob'
    })

    // 创建下载链接
    const blob = new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `定时策略_${new Date().toISOString().slice(0, 10)}.xlsx`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)

    ElMessage.success('导出成功')
  } catch (error) {
    console.error('导出失败:', error)
    ElMessage.error('导出失败')
  }
}

// 复制策略
const handleCopyStrategy = async (row) => {
  try {
    dialogTitle.value = '复制策略'
    isEdit.value = false

    // 先调用详情接口获取完整数据
    const response = await axios.get(`${__LOCAL_API__}/illuminating/getTimingId`, {
      params: { timing_id: row.timing_id }
    })

    if (response.data.code === 200) {
      const data = response.data.data

      // 解析region_ids
      let regionId = ''
      if (data.region_ids) {
        const parts = data.region_ids.split('=')[0]
        const idParts = parts.split('-')
        regionId = idParts.length === 2 ? idParts[1] : idParts[0]
      }

      // 设置选择方式
      deviceSelectType.value = data.group_id ? 'group' : 'region'

      // 复制数据但不包含ID
      Object.assign(formData, {
        timing_id: null,
        timing_name: `${data.timing_name}_副本`,
        weeks: [...(data.weeks || [])],
        timing_start_time: data.timing_start_time,
        region_ids: regionId,
        group_id: data.group_id || '',
        category_id: data.category_id || '',
        device_type_id: data.device_type_id || '',
        device_ids: [...(data.device_ids || [])]
      })

      // 复制路数配置
      if (data.timing_agreement) {
        try {
          const agreement = typeof data.timing_agreement === 'string'
              ? JSON.parse(data.timing_agreement)
              : data.timing_agreement

          // 从设备数据中提取路数名称
          const channelNames = {}
          if (data.devices && data.devices.length > 0) {
            const firstDevice = data.devices[0]
            if (firstDevice.devices_json_object) {
              try {
                const deviceData = JSON.parse(firstDevice.devices_json_object)
                for (let i = 1; i <= 12; i++) {
                  if (deviceData[`name${i}`]) {
                    channelNames[`Tag${i}`] = deviceData[`name${i}`]
                  }
                }
              } catch (e) {
                console.error('解析设备数据失败:', e)
              }
            }
          }

          formData.timing_agreement = { ...agreement }
          formData.channel_names = { ...channelNames }

          const tagCount = Object.keys(agreement).length
          channelCount.value = tagCount
        } catch (e) {
          console.error('解析设备指令失败:', e)
        }
      }

      // 按顺序加载相关选项数据
      await loadEditData()

      dialogVisible.value = true
    } else {
      ElMessage.error(response.data.message || '获取策略详情失败')
    }
  } catch (error) {
    console.error('加载复制数据失败:', error)
    ElMessage.error('复制策略失败')
  }
}

// 预览策略执行时间
const previewExecutionTimes = (weeks, startTime) => {
  if (!weeks || weeks.length === 0 || !startTime) {
    return []
  }

  const now = new Date()
  const times = []

  // 获取未来7天的执行时间
  for (let i = 0; i < 7; i++) {
    const date = new Date(now)
    date.setDate(date.getDate() + i)

    const dayOfWeek = Math.pow(2, date.getDay() === 0 ? 7 : date.getDay()) // 转换为位值

    if (weeks.includes(dayOfWeek)) {
      const [hours, minutes] = startTime.split(':')
      date.setHours(parseInt(hours), parseInt(minutes), 0, 0)

      times.push({
        date: date.toLocaleDateString(),
        time: startTime,
        dayName: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][date.getDay()]
      })
    }
  }

  return times
}

// 验证策略冲突
const validateStrategyConflict = async (formData) => {
  try {
    const response = await axios.post(`${__LOCAL_API__}/illuminating/validateTimingConflict`, {
      weeks: formData.weeks,
      timing_start_time: formData.timing_start_time,
      device_ids: formData.device_ids,
      timing_id: formData.timing_id // 编辑时传入，用于排除自身
    })

    if (response.data.code === 200) {
      const conflicts = response.data.data.conflicts || []
      if (conflicts.length > 0) {
        const conflictMessages = conflicts.map(conflict =>
            `策略"${conflict.timing_name}"在${conflict.conflict_time}存在冲突`
        ).join('\n')

        await ElMessageBox.confirm(
            `检测到以下时间冲突：\n${conflictMessages}\n\n是否继续保存？`,
            '策略冲突警告',
            {
              confirmButtonText: '继续保存',
              cancelButtonText: '取消',
              type: 'warning',
            }
        )
      }
      return true
    }
  } catch (error) {
    if (error === 'cancel') {
      return false
    }
    console.error('验证策略冲突失败:', error)
    // 验证失败时允许继续，但给出提示
    ElMessage.warning('无法验证策略冲突，请手动检查')
    return true
  }
}

// 处理周数据转换
const convertWeeksToArray = (weekValue) => {
  if (Array.isArray(weekValue)) {
    return weekValue
  }

  if (typeof weekValue === 'number') {
    const weeks = []
    const weekValues = [2, 4, 8, 16, 32, 64, 128, 256, 512]

    weekValues.forEach(value => {
      if (weekValue & value) {
        weeks.push(value)
      }
    })

    return weeks
  }

  return []
}

// 处理周数据转换为数字
const convertWeeksToNumber = (weeksArray) => {
  if (!Array.isArray(weeksArray)) {
    return 0
  }

  return weeksArray.reduce((sum, week) => sum + week, 0)
}

// 格式化区域显示
const formatRegionDisplay = (regionIds) => {
  if (!regionIds) return ''

  // 如果是 "1-1=南京芯片之城一期" 格式
  if (regionIds.includes('=')) {
    return regionIds.split('=')[1]
  }

  return regionIds
}

// 解析设备JSON对象获取路数名称
const parseDeviceChannelNames = (devices) => {
  const channelNames = {}

  if (!devices || devices.length === 0) {
    return channelNames
  }

  // 从第一个设备获取路数名称配置
  const firstDevice = devices[0]
  if (firstDevice && firstDevice.devices_json_object) {
    try {
      const deviceData = JSON.parse(firstDevice.devices_json_object)

      // 提取name1-name12的配置
      for (let i = 1; i <= 12; i++) {
        const nameKey = `name${i}`
        if (deviceData[nameKey] && deviceData[nameKey].trim() !== '' && deviceData[nameKey] !== '备用') {
          channelNames[`Tag${i}`] = deviceData[nameKey]
        }
      }
    } catch (error) {
      console.error('解析设备JSON失败:', error)
    }
  }

  return channelNames
}

// 生成默认路数名称
const generateDefaultChannelNames = (count) => {
  const names = {}
  for (let i = 1; i <= count; i++) {
    names[`Tag${i}`] = `${getChineseNumber(i)}路`
  }
  return names
}

// 验证表单数据完整性
const validateFormData = () => {
  // 验证基本信息
  if (!formData.timing_name.trim()) {
    throw new Error('请输入策略名称')
  }

  if (!formData.timing_start_time) {
    throw new Error('请选择执行时间')
  }

  if (!formData.weeks || formData.weeks.length === 0) {
    throw new Error('请选择重复日期')
  }

  // 验证设备选择
  if (deviceSelectType.value === 'region' && !formData.region_ids) {
    throw new Error('请选择所属位置')
  }

  if (deviceSelectType.value === 'group' && !formData.group_id) {
    throw new Error('请选择设备分组')
  }

  if (!formData.category_id) {
    throw new Error('请选择设备分类')
  }

  if (!formData.device_type_id) {
    throw new Error('请选择设备型号')
  }

  if (!formData.device_ids || formData.device_ids.length === 0) {
    throw new Error('请选择至少一个设备')
  }

  // 路数配置验证（可选）
  if (channelCount.value > 0) {
    // 验证已配置的路数名称长度
    for (let i = 1; i <= channelCount.value; i++) {
      const tagKey = `Tag${i}`
      if (formData.timing_agreement[tagKey] !== undefined) {
        const channelName = formData.channel_names[tagKey]
        if (channelName && channelName.length > 20) {
          throw new Error(`第${i}路的名称长度不能超过20个字符`)
        }
      }
    }
  }

  return true
}

// 处理表格数据显示
const processTableData = (data) => {
  return data.map(item => ({
    ...item,
    // 处理周数据
    weeks: convertWeeksToArray(item.timing_week || item.weeks),
    // 格式化区域显示
    region_display: formatRegionDisplay(item.region_ids),
    // 处理设备指令显示
    agreement_display: item.timing_agreement ?
        (typeof item.timing_agreement === 'string' ? item.timing_agreement : JSON.stringify(item.timing_agreement)) : '',
  }))
}

// 初始化页面数据
const initPageData = async () => {
  try {
    await fetchData()
  } catch (error) {
    console.error('初始化页面数据失败:', error)
    ElMessage.error('初始化页面失败')
  }
}

// 重置所有选择器
const resetAllSelectors = () => {
  formData.category_id = ''
  formData.device_type_id = ''
  formData.device_ids = []
  categoryOptions.value = []
  deviceTypeOptions.value = []
  deviceOptions.value = []
  channelCount.value = 0
  formData.timing_agreement = {}
  formData.channel_names = {}
}

// 处理区域选择变化
const handleRegionChange = (value) => {
  formData.region_ids = value
  resetAllSelectors()

  if (value) {
    fetchDeviceCategories()
  }
}

// 处理分组选择变化
const handleGroupChange = (value) => {
  formData.group_id = value
  resetAllSelectors()

  if (value) {
    fetchDeviceCategories()
  }
}

// 获取设备型号的路数配置
const getDeviceTypeChannelConfig = async (deviceTypeId) => {
  try {
    const deviceType = deviceTypeOptions.value.find(item => item.value === deviceTypeId)
    if (!deviceType) {
      return { count: 8, names: generateDefaultChannelNames(8) }
    }

    const count = deviceType.channelCount || 8
    const names = generateDefaultChannelNames(count)

    return { count, names }
  } catch (error) {
    console.error('获取设备型号路数配置失败:', error)
    return { count: 8, names: generateDefaultChannelNames(8) }
  }
}

// 更新路数配置
const updateChannelConfig = async (deviceTypeId) => {
  try {
    const { count, names } = await getDeviceTypeChannelConfig(deviceTypeId)

    channelCount.value = count

    // 如果是新增或者没有现有配置，初始化配置
    if (!isEdit.value || Object.keys(formData.timing_agreement).length === 0) {
      const agreement = {}
      for (let i = 1; i <= count; i++) {
        agreement[`Tag${i}`] = 0
      }
      formData.timing_agreement = agreement
      formData.channel_names = { ...names }
    } else {
      // 编辑模式下，确保路数名称存在
      for (let i = 1; i <= count; i++) {
        if (!formData.channel_names[`Tag${i}`]) {
          formData.channel_names[`Tag${i}`] = names[`Tag${i}`] || `${i}路`
        }
      }
    }
  } catch (error) {
    console.error('更新路数配置失败:', error)
  }
}

// 处理编辑数据的特殊逻辑
const handleEditDataSpecial = (data) => {
  // 处理周数据
  if (data.timing_week !== undefined) {
    formData.weeks = convertWeeksToArray(data.timing_week)
  } else if (data.weeks) {
    formData.weeks = Array.isArray(data.weeks) ? data.weeks : convertWeeksToArray(data.weeks)
  }

  // 处理区域ID
  if (data.region_ids) {
    const parts = data.region_ids.split('=')[0]
    const idParts = parts.split('-')
    formData.region_ids = idParts.length === 2 ? idParts[1] : idParts[0]
  }

  // 处理设备指令和路数名称
  if (data.timing_agreement) {
    try {
      const agreement = typeof data.timing_agreement === 'string'
          ? JSON.parse(data.timing_agreement)
          : data.timing_agreement

      formData.timing_agreement = { ...agreement }

      // 从设备数据中提取路数名称
      const deviceChannelNames = parseDeviceChannelNames(data.devices)

      // 合并路数名称（优先使用设备中的名称）
      const channelNames = { ...generateDefaultChannelNames(Object.keys(agreement).length) }
      Object.assign(channelNames, deviceChannelNames)

      formData.channel_names = channelNames

      // 设置路数
      channelCount.value = Object.keys(agreement).length

      // 保存原始配置
      originalChannelConfig.value = {
        timing_agreement: { ...agreement },
        channel_names: { ...channelNames }
      }
    } catch (error) {
      console.error('处理设备指令失败:', error)
    }
  }
}

// 生命周期
onMounted(() => {
  initPageData()
})


// 导出组件需要的方法和数据（如果需要的话）
defineExpose({
  fetchData,
  resetForm,
  handleAdd,
  handleEdit
})

// 添加清理过期缓存的方法
const clearExpiredCache = () => {
  const now = Date.now()
  for (const [key, value] of requestCache.entries()) {
    if (now - value.timestamp > value.expiry) {
      requestCache.delete(key)
    }
  }
}

// 在组件卸载时清理
onUnmounted(() => {
  if (debounceTimer) {
    clearTimeout(debounceTimer)
  }
  requestCache.clear()
  requestQueue.clear()
})

// 定期清理过期缓存
setInterval(clearExpiredCache, 1800000) // 每分钟清理一次
</script>

<style scoped>
.timing-strategy-page {
  padding: 24px;
  background: #f5f7fa;
  min-height: 90vh;
}

/* 页面标题 */
.page-header {
  margin-bottom: 24px;
}

.page-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 24px;
  font-weight: 600;
  color: #303133;
  margin: 0 0 8px 0;
}

.page-description {
  color: #909399;
  font-size: 14px;
  margin: 0;
}

/* 卡片样式 */
.search-card,
.table-card {
  margin-bottom: 24px;
  border-radius: 12px;
  border: none;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  color: #303133;
}

.card-header .header-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.count-tag {
  margin-left: 12px;
}

/* 搜索表单 */
.search-form {
  margin: 0;
}

.el-form--inline .el-form-item {
  display: inline-flex;
  margin-right: 32px;
  vertical-align: baseline;
}

.search-input {
  width: 280px;
}

/* 表格样式 */
.strategy-table {
  margin-bottom: 24px;
  padding: 12px 12px;
}

.strategy-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}

.name-icon {
  color: #409eff;
}

.weeks-container {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.week-tag {
  margin: 2px 0;
}

.time-display {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  color: #606266;
}

.agreement-display {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.agreement-tag {
  margin: 2px 0;
}

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

/* 分页 */
.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 24px;
}

/* 弹窗样式 */
.strategy-dialog :deep(.el-dialog__header) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 12px 12px 0 0;
  padding: 20px 24px;
}

.strategy-dialog :deep(.el-dialog__title) {
  color: white;
  font-weight: 600;
}

.strategy-dialog :deep(.el-dialog__headerbtn .el-dialog__close) {
  color: white;
}

.strategy-dialog :deep(.el-dialog__body) {
  padding: 24px;
}

/* 表单样式 */
.strategy-form {
  max-height: 60vh;
  overflow-y: auto;
  padding-right: 8px;
}

.form-section {
  margin-bottom: 32px;
  padding: 20px;
  background: #fafbfc;
  border-radius: 8px;
  border-left: 4px solid #409eff;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 20px 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

/* 设备选择样式 */
.device-select-container {
  width: 100%;
}

.device-select-header {
  padding: 8px 12px;
  border-bottom: 1px solid #e4e7ed;
  background: #f8f9fa;
}

.device-count-info {
  margin-top: 8px;
  font-size: 12px;
  color: #909399;
  text-align: right;
}

/* 路数配置操作按钮 */
.channel-operations {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 16px;
  background: #f0f9ff;
  border-radius: 8px;
  border: 1px solid #b3d8ff;
}

.operation-buttons {
  display: flex;
  gap: 12px;
  align-items: center;
}

.channel-status-info {
  font-size: 14px;
  color: #606266;
  font-weight: 500;
}

/* 重复日期选择样式 */
.weeks-selection {
  width: 100%;
  background: white;
  border-radius: 12px;
  padding: 20px;
  border: 1px solid #e4e7ed;
}

.quick-select-buttons {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid #f0f0f0;
}

.quick-select-buttons .el-button {
  border-radius: 20px;
  padding: 8px 16px;
  font-size: 13px;
  transition: all 0.3s ease;
}

.quick-select-buttons .el-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}

.week-selection-container {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.week-days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 12px;
}

.week-day-item {
  position: relative;
  background: #f8f9fa;
  border: 2px solid #e9ecef;
  border-radius: 12px;
  padding: 16px 8px;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  user-select: none;
  overflow: hidden;
}

.week-day-item::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  opacity: 0;
  transition: opacity 0.3s ease;
  z-index: 1;
}

.week-day-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
  border-color: #409eff;
}

.week-day-item:hover::before {
  opacity: 0.1;
}

.week-day-item.selected {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-color: #667eea;
  color: white;
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}

.week-day-item.weekend {
  background: #fff5f5;
  border-color: #fed7d7;
}

.week-day-item.weekend.selected {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  border-color: #f093fb;
}

.day-content {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.day-name {
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
}

.day-en {
  font-size: 11px;
  opacity: 0.7;
  line-height: 1;
}

.day-icon {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 20px;
  height: 20px;
  background: #67c23a;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 12px;
  opacity: 0;
  transform: scale(0);
  transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.week-day-item.selected .day-icon {
  opacity: 1;
  transform: scale(1);
}

/* 特殊选项 */
.special-options {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
  border: 1px solid #e9ecef;
}

.special-option-group {
  width: 100%;
}

.option-group-title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  margin: 0 0 12px 0;
  padding-bottom: 8px;
  border-bottom: 1px solid #e9ecef;
}

.special-checkboxes {
  display: flex;
  gap: 16px;
}

.special-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  background: white;
  border: 2px solid #e9ecef;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  user-select: none;
  flex: 1;
}

.special-checkbox:hover {
  border-color: #409eff;
  background: #f0f9ff;
}

.special-checkbox.checked {
  border-color: #409eff;
  background: #ecf5ff;
  color: #409eff;
}

.checkbox-icon {
  width: 16px;
  height: 16px;
  border: 1px solid #dcdfe6;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  transition: all 0.3s ease;
}

.special-checkbox.checked .checkbox-icon {
  background: #409eff;
  border-color: #409eff;
  color: white;
}

.checkbox-label {
  font-size: 14px;
  font-weight: 500;
}

/* 选择结果预览 */
.selection-preview {
  margin-top: 20px;
  padding: 16px;
  background: #f0f9ff;
  border-radius: 8px;
  border: 1px solid #b3d8ff;
}

.preview-title {
  font-size: 14px;
  font-weight: 600;
  color: #409eff;
  margin-bottom: 12px;
}

.preview-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.preview-tag {
  transition: all 0.3s ease;
}

.preview-tag:hover {
  transform: scale(1.05);
}

/* 设备选择样式 */
.select-type-radio {
  display: flex;
  gap: 24px;
}

.select-type-radio .el-radio {
  margin-right: 0;
  padding: 12px 20px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  background: white;
  transition: all 0.3s ease;
}

.select-type-radio .el-radio:hover {
  border-color: #409eff;
  background: #f0f9ff;
}

.select-type-radio .el-radio.is-checked {
  border-color: #409eff;
  background: #ecf5ff;
  color: #409eff;
}

.select-type-radio .el-radio :deep(.el-radio__input) {
  display: none;
}

.select-type-radio .el-radio :deep(.el-radio__label) {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0;
}

/* 路数配置样式 */
.channel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}

.channel-item {
  background: white;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  padding: 16px;
  transition: all 0.3s ease;
}

.channel-item:hover {
  border-color: #409eff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}

.channel-header {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 16px;
}

.channel-number {
  font-weight: 600;
  color: #303133;
  min-width: 40px;
  line-height: 32px;
}

/* 路数名称表单项样式 */
.channel-name-form-item {
  flex: 1;
  margin-bottom: 0;
}

.channel-name-form-item :deep(.el-form-item__content) {
  margin-left: 0 !important;
}

.channel-name-form-item :deep(.el-form-item__error) {
  position: static;
  margin-top: 4px;
  font-size: 12px;
}

.channel-name-input {
  flex: 1;
}

.channel-control {
  display: flex;
  justify-content: center;
}

.channel-radio {
  display: flex;
  gap: 16px;
}

.channel-radio .el-radio {
  margin: 0;
  padding: 8px 16px;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  background: white;
  transition: all 0.3s ease;
}

.radio-off.is-checked {
  border-color: #f56c6c;
  background: #fef0f0;
  color: #f56c6c;
}

.radio-on.is-checked {
  border-color: #67c23a;
  background: #f0f9ff;
  color: #67c23a;
}

.channel-radio .el-radio :deep(.el-radio__input) {
  display: none;
}

.channel-radio .el-radio :deep(.el-radio__label) {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  font-size: 14px;
}

/* 弹窗底部 */
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 20px 24px;
  background: #fafbfc;
  border-radius: 0 0 12px 12px;
  margin: 0 -24px -24px -24px;
}

/* 详情弹窗 */
.detail-dialog :deep(.el-dialog__header) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 12px 12px 0 0;
}

.detail-content {
  padding: 8px 0;
}

.detail-section {
  margin-bottom: 24px;
}

.detail-section h4 {
  margin: 0 0 16px 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  padding-bottom: 8px;
  border-bottom: 2px solid #e4e7ed;
}

.agreement-detail {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}

.agreement-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: #f8f9fa;
  border-radius: 6px;
  border-left: 3px solid #409eff;
}

.channel-name {
  font-weight: 500;
  color: #303133;
}

/* 树形选择器样式优化 */
.el-tree-select :deep(.el-tree-node__content) {
  padding: 8px 12px;
  border-radius: 4px;
  transition: all 0.3s ease;
}

.el-tree-select :deep(.el-tree-node__content):hover {
  background-color: #f0f9ff;
}

.el-tree-select :deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: #ecf5ff;
  color: #409eff;
  font-weight: 500;
}

.el-tree-select :deep(.el-tree-node__expand-icon) {
  color: #409eff;
}

.el-tree-select :deep(.el-tree-node__loading-icon) {
  color: #409eff;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .channel-grid {
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  }

  .week-days-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
  }
}

@media (max-width: 768px) {
  .timing-strategy-page {
    padding: 16px;
  }

  .page-title {
    font-size: 20px;
  }

  .search-input {
    width: 100%;
  }

  .search-form .el-form-item {
    margin-bottom: 16px;
  }

  .week-days-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
  }

  .week-day-item {
    padding: 12px 6px;
  }

  .day-name {
    font-size: 13px;
  }

  .day-en {
    font-size: 10px;
  }

  .quick-select-buttons {
    flex-wrap: wrap;
    gap: 8px;
  }

  .special-checkboxes {
    flex-direction: column;
    gap: 12px;
  }

  .channel-grid {
    grid-template-columns: 1fr;
  }

  .agreement-detail {
    grid-template-columns: 1fr;
  }

  .action-buttons {
    flex-direction: column;
    gap: 4px;
  }

  .strategy-dialog {
    width: 95% !important;
    margin: 0 auto;
  }

  .detail-dialog {
    width: 95% !important;
    margin: 0 auto;
  }

  .weeks-selection {
    padding: 16px;
  }

  .preview-tags {
    gap: 6px;
  }

  .channel-operations {
    flex-direction: column;
    gap: 12px;
    align-items: stretch;
  }

  .operation-buttons {
    justify-content: center;
  }

  .select-type-radio {
    flex-direction: column;
    gap: 12px;
  }
}

@media (max-width: 480px) {
  .week-days-grid {
    grid-template-columns: 1fr;
    gap: 6px;
  }

  .week-day-item {
    padding: 10px;
  }

  .quick-select-buttons {
    grid-template-columns: repeat(2, 1fr);
    display: grid;
  }

  .channel-radio {
    flex-direction: column;
    gap: 8px;
  }

  .special-checkboxes {
    gap: 8px;
  }

  .special-checkbox {
    padding: 8px 12px;
  }
}

/* 滚动条样式 */
.strategy-form::-webkit-scrollbar {
  width: 6px;
}

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

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

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

/* 动画效果 */
.el-card {
  transition: all 0.3s ease;
}

.el-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
}

.el-button {
  transition: all 0.3s ease;
}

.el-table__row {
  transition: all 0.3s ease;
}

.el-table__row:hover {
  background-color: #f5f7fa !important;
}

/* 设备选择下拉框头部样式 */
.device-select-header :deep(.el-checkbox) {
  width: 100%;
}

.device-select-header :deep(.el-checkbox__label) {
  font-weight: 500;
  color: #606266;
}

/* 表单验证错误样式优化 */
.el-form-item.is-error :deep(.el-input__wrapper) {
  box-shadow: 0 0 0 1px #f56c6c inset;
}

.el-form-item.is-error :deep(.el-select .el-input__wrapper) {
  box-shadow: 0 0 0 1px #f56c6c inset;
}

.el-form-item.is-error :deep(.el-tree-select .el-input__wrapper) {
  box-shadow: 0 0 0 1px #f56c6c inset;
}

/* 提交按钮加载状态 */
.el-button.is-loading {
  pointer-events: none;
}

/* 路数配置状态指示 */
.channel-status-info {
  display: flex;
  gap: 16px;
  align-items: center;
}

.channel-status-info::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #67c23a;
  display: inline-block;
}

/* 优化选择器样式 */
.el-select-dropdown__item.selected {
  background-color: #f0f9ff;
  color: #409eff;
  font-weight: 500;
}

/* 优化时间选择器样式 */
.el-time-picker {
  width: 100%;
}

.el-time-picker :deep(.el-input__wrapper) {
  transition: all 0.3s ease;
}

.el-time-picker :deep(.el-input__wrapper):hover {
  box-shadow: 0 0 0 1px #409eff inset;
}

/* 优化多选标签样式 */
.el-select :deep(.el-tag) {
  margin: 2px 4px 2px 0;
  background-color: #f0f9ff;
  border-color: #b3d8ff;
  color: #409eff;
}

.el-select :deep(.el-tag .el-tag__close) {
  color: #409eff;
}

.el-select :deep(.el-tag .el-tag__close):hover {
  background-color: #409eff;
  color: white;
}

/* 优化开关样式 */
.el-switch.is-checked :deep(.el-switch__core) {
  background-color: #13ce66;
}

.el-switch :deep(.el-switch__core) {
  background-color: #ff4949;
}

/* 优化描述列表样式 */
.el-descriptions :deep(.el-descriptions__header) {
  margin-bottom: 16px;
}

.el-descriptions :deep(.el-descriptions__title) {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.el-descriptions :deep(.el-descriptions__body) {
  background-color: #fafbfc;
}

.el-descriptions :deep(.el-descriptions-item__label) {
  font-weight: 500;
  color: #606266;
  background-color: #f8f9fa;
}

.el-descriptions :deep(.el-descriptions-item__content) {
  color: #303133;
}

/* 工具提示样式 */
.el-tooltip__popper {
  max-width: 300px;
  word-break: break-all;
}

/* 过渡动画 */
.week-day-item,
.special-checkbox,
.preview-tag {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 焦点状态 */
.week-day-item:focus,
.special-checkbox:focus {
  outline: 2px solid #409eff;
  outline-offset: 2px;
}

/* 禁用状态 */
.week-day-item.disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* 减少动画模式支持 */
@media (prefers-reduced-motion: reduce) {
  .week-day-item,
  .special-checkbox,
  .preview-tag,
  .day-icon {
    transition: none;
  }
}

/* 树形选择器下拉面板样式 */
.el-tree-select-dropdown {
  max-height: 300px;
}

.el-tree-select-dropdown :deep(.el-tree) {
  padding: 8px;
}

.el-tree-select-dropdown :deep(.el-tree-node) {
  margin-bottom: 4px;
}

.el-tree-select-dropdown :deep(.el-tree-node__content) {
  border-radius: 6px;
  padding: 8px 12px;
  transition: all 0.2s ease;
}

.el-tree-select-dropdown :deep(.el-tree-node__content):hover {
  background-color: #f0f9ff;
}

.el-tree-select-dropdown :deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: #ecf5ff;
  color: #409eff;
  font-weight: 500;
}

.el-tree-select-dropdown :deep(.el-tree-node__label) {
  font-size: 14px;
  color: #606266;
}

.el-tree-select-dropdown :deep(.el-tree-node.is-current .el-tree-node__label) {
  color: #409eff;
}

/* 加载状态样式 */
.el-tree-select-dropdown :deep(.el-tree-node__loading-icon) {
  color: #409eff;
  animation: rotating 2s linear infinite;
}

@keyframes rotating {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* 空状态样式 */
.el-tree-select-dropdown :deep(.el-tree__empty-block) {
  padding: 20px;
  text-align: center;
  color: #909399;
  font-size: 14px;
}

/* 优化表格行高 */
.strategy-table :deep(.el-table__row) {
  height: 60px;
}

.strategy-table :deep(.el-table__cell) {
  padding: 12px 0;
}

/* 优化表格头部样式 */
.strategy-table :deep(.el-table__header-wrapper) {
  background: #f8f9fa;
}

.strategy-table :deep(.el-table__header th) {
  background: #f8f9fa;
  color: #495057;
  font-weight: 600;
  border-bottom: 2px solid #e9ecef;
}

/* 优化分页样式 */
.el-pagination {
  padding: 20px 0;
}

.el-pagination :deep(.el-pagination__total) {
  color: #606266;
  font-weight: 500;
}

.el-pagination :deep(.btn-prev),
.el-pagination :deep(.btn-next) {
  border-radius: 6px;
  transition: all 0.3s ease;
}

.el-pagination :deep(.btn-prev):hover,
.el-pagination :deep(.btn-next):hover {
  color: #409eff;
  transform: translateY(-1px);
}

.el-pagination :deep(.el-pager li) {
  border-radius: 6px;
  margin: 0 2px;
  transition: all 0.3s ease;
}

.el-pagination :deep(.el-pager li:hover) {
  color: #409eff;
  transform: translateY(-1px);
}

.el-pagination :deep(.el-pager li.is-active) {
  background-color: #409eff;
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

/* 优化消息提示样式 */
.el-message {
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}

.el-message.el-message--success {
  background-color: #f0f9ff;
  border-color: #b3d8ff;
  color: #409eff;
}

.el-message.el-message--error {
  background-color: #fef0f0;
  border-color: #fbc4c4;
  color: #f56c6c;
}

/* 优化确认框样式 */
.el-message-box {
  border-radius: 12px;
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.2);
}

.el-message-box__header {
  padding: 20px 24px 16px;
  border-bottom: 1px solid #e9ecef;
}

.el-message-box__title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.el-message-box__content {
  padding: 20px 24px;
}

.el-message-box__btns {
  padding: 16px 24px 20px;
  border-top: 1px solid #e9ecef;
}

/* 优化加载动画 */
.el-loading-mask {
  background-color: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(4px);
}

.el-loading-spinner {
  color: #409eff;
}

/* 优化表单项间距 */
.el-form-item {
  margin-bottom: 20px;
}

.el-form-item:last-child {
  margin-bottom: 0;
}

/* 优化输入框样式 */
.el-input__wrapper {
  border-radius: 6px;
  transition: all 0.3s ease;
}

.el-input__wrapper:hover {
  box-shadow: 0 0 0 1px #c0c4cc inset;
}

.el-input__wrapper.is-focus {
  box-shadow: 0 0 0 1px #409eff inset;
}

/* 优化选择器样式 */
.el-select .el-input__wrapper {
  cursor: pointer;
}

.el-select .el-input__wrapper:hover {
  box-shadow: 0 0 0 1px #c0c4cc inset;
}

.el-select .el-input__wrapper.is-focus {
  box-shadow: 0 0 0 1px #409eff inset;
}

/* 优化按钮样式 */
.el-button {
  border-radius: 6px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.el-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.el-button--primary {
  background: linear-gradient(135deg, #409eff 0%, #3a8ee6 100%);
  border-color: #409eff;
}

.el-button--primary:hover {
  background: linear-gradient(135deg, #66b1ff 0%, #409eff 100%);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
}

.el-button--success {
  background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%);
  border-color: #67c23a;
}

.el-button--success:hover {
  background: linear-gradient(135deg, #85ce61 0%, #67c23a 100%);
  box-shadow: 0 4px 12px rgba(103, 194, 58, 0.4);
}

/* 优化标签样式 */
.el-tag {
  border-radius: 4px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.el-tag:hover {
  transform: scale(1.05);
}

.el-tag--primary {
  background-color: #ecf5ff;
  border-color: #b3d8ff;
  color: #409eff;
}

.el-tag--success {
  background-color: #f0f9ff;
  border-color: #b3e19d;
  color: #67c23a;
}

.el-tag--info {
  background-color: #f4f4f5;
  border-color: #d3d4d6;
  color: #909399;
}

.el-tag--warning {
  background-color: #fdf6ec;
  border-color: #f5dab1;
  color: #e6a23c;
}

.el-tag--danger {
  background-color: #fef0f0;
  border-color: #fbc4c4;
  color: #f56c6c;
}

/* 打印样式 */
@media print {
  .timing-strategy-page {
    background: white;
    padding: 0;
  }

  .search-card,
  .pagination-container,
  .action-buttons {
    display: none;
  }

  .table-card {
    box-shadow: none;
    border: 1px solid #ddd;
  }

  .strategy-table {
    font-size: 12px;
  }
}

/* 高对比度模式支持 */
@media (prefers-contrast: high) {
  .week-day-item {
    border-width: 3px;
  }

  .week-day-item.selected {
    border-width: 4px;
  }

  .special-checkbox {
    border-width: 2px;
  }

  .el-button {
    border-width: 2px;
  }
}

/* 深色模式支持 */
@media (prefers-color-scheme: dark) {
  .timing-strategy-page {
    background: #1a1a1a;
    color: #e5e5e5;
  }

  .search-card,
  .table-card {
    background: #2d2d2d;
    border-color: #404040;
  }

  .form-section {
    background: #2a2a2a;
    border-left-color: #409eff;
  }

  .week-day-item {
    background: #3a3a3a;
    border-color: #505050;
    color: #e5e5e5;
  }

  .week-day-item:hover {
    background: #404040;
  }

  .channel-item {
    background: #3a3a3a;
    border-color: #505050;
  }
}
.action-btn {
  min-width: 60px;
  height: 32px;
  border-radius: 6px;
  font-weight: 500;
  font-size: 12px;
  transition: all 0.3s ease;
  border: 1px solid transparent;
}

.action-btn {
  width: 40%;
  min-width: auto;
}

.control-btn {
  background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
  color: white;
  border: none;
}

.control-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
}

.control-btn:disabled {
  background: #c0c4cc;
  color: #ffffff;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}
</style>
