<template>
  <div class="batch-task-panel">
    <!-- 面板标题 -->
    <div class="panel-header">
      <h2>
        <n-icon><Flash /></n-icon>
        批量自动化任务
      </h2>
      <n-space>
        <n-tag
          v-if="batchStore.isExecuting"
          type="info"
          :bordered="false"
        >
          <template #icon>
            <n-icon><Refresh /></n-icon>
          </template>
          执行中...
        </n-tag>
        <n-tag
          type="success"
          :bordered="false"
        >
          并发数: {{ batchStore.maxConcurrency }}
        </n-tag>
        <!-- 定时任务状态指示器 -->
        <n-tooltip trigger="hover">
          <template #trigger>
            <n-tag
              :type="schedulerStatusType"
              :bordered="false"
              class="scheduler-status-tag"
            >
              <template #icon>
                <n-icon><Time /></n-icon>
              </template>
              {{ schedulerStatusText }}
            </n-tag>
          </template>
          <div class="scheduler-tooltip">
            <div v-if="batchStore.schedulerConfig.enabled">
              <p><strong>定时任务已启用</strong></p>
              <p v-if="batchStore.schedulerConfig.type === 'interval'">
                间隔执行：每 {{ formatInterval(batchStore.schedulerConfig.interval) }}
              </p>
              <p v-else>
                每日定时：{{ batchStore.schedulerConfig.dailyTimes.join(', ') }}
              </p>
              <p v-if="batchStore.schedulerConfig.lastExecutionTime">
                上次执行：{{ formatLastExecutionTime }}
              </p>
              <p v-else>
                尚未执行过
              </p>
            </div>
            <p v-else>定时任务未启用</p>
          </div>
        </n-tooltip>
      </n-space>
    </div>
    
    <!-- 定时任务快速控制栏 -->
    <div v-if="batchStore.schedulerConfig.enabled" class="scheduler-quick-control">
      <div class="control-info">
        <n-icon size="18"><Time /></n-icon>
        <span class="info-text">
          <strong>定时任务运行中</strong>
          <span v-if="batchStore.schedulerConfig.type === 'interval'">
            - 每 {{ formatInterval(batchStore.schedulerConfig.interval) }} 自动执行
          </span>
          <span v-else>
            - 每日 {{ batchStore.schedulerConfig.dailyTimes.join(', ') }} 执行
          </span>
        </span>
      </div>
      <n-space>
        <n-button
          size="small"
          @click="showScheduler = true"
        >
          <template #icon>
            <n-icon><Settings /></n-icon>
          </template>
          配置
        </n-button>
        <n-button
          size="small"
          type="warning"
          @click="handleQuickToggleScheduler(false)"
        >
          <template #icon>
            <n-icon><Pause /></n-icon>
          </template>
          停用
        </n-button>
      </n-space>
    </div>

    <!-- 任务模板选择 -->
    <div class="template-section">
      <n-space vertical :size="16">
        <!-- 模板选择器和并发数设置 -->
        <n-grid cols="1 s:2 m:3" :x-gap="16">
          <n-grid-item>
            <div class="template-selector">
              <label>选择任务模板：</label>
              <n-select
                v-model:value="batchStore.selectedTemplate"
                :options="templateOptions"
                :disabled="batchStore.isExecuting"
                size="large"
              />
            </div>
          </n-grid-item>
          
          <!-- 🆕 v3.13.0 连接池模式开关 -->
          <n-grid-item>
            <div class="connection-pool-toggle">
              <n-space justify="space-between" align="center">
                <div class="toggle-label">
                  <n-space align="center">
                    <n-icon size="20" :color="batchStore.USE_CONNECTION_POOL ? '#18a058' : '#999'">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
                      </svg>
                    </n-icon>
                    <span :style="{ fontWeight: 'bold', color: batchStore.USE_CONNECTION_POOL ? '#18a058' : '#666' }">
                      🏊 连接池模式
                    </span>
                    <n-tooltip trigger="hover" placement="right">
                      <template #trigger>
                        <n-icon size="16" color="#999">
                          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                            <path fill="currentColor" d="M11 17h2v-6h-2v6zm1-8q.425 0 .713-.288Q13 8.425 13 8t-.287-.713Q12.425 7 12 7t-.712.287Q11 7.575 11 8t.288.712Q11.575 9 12 9zm0 13q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Z"/>
                          </svg>
                        </n-icon>
                      </template>
                      <div style="max-width: 300px;">
                        <p><strong>连接池模式（推荐用于100并发）</strong></p>
                        <p>✅ 突破浏览器WebSocket连接数限制（10-20个）</p>
                        <p>✅ 100个Token复用20个连接，稳定高效</p>
                        <p>✅ 连接复用，节省建立时间</p>
                        <p>✅ 内存占用更低（20连接 vs 100连接）</p>
                        <p style="margin-top: 8px; color: #999;">
                          ⚠️ 传统模式：并发数超过20容易连接失败<br/>
                          ✨ 连接池模式：支持100+并发稳定运行
                        </p>
                      </div>
                    </n-tooltip>
                  </n-space>
                </div>
                <n-switch
                  v-model:value="batchStore.USE_CONNECTION_POOL"
                  :disabled="batchStore.isExecuting"
                  @update:value="handlePoolModeChange"
                  size="medium"
                >
                  <template #checked>
                    启用
                  </template>
                  <template #unchecked>
                    禁用
                  </template>
                </n-switch>
              </n-space>
            </div>
          </n-grid-item>
          
          <!-- 🆕 v3.14.1 性能模式开关 -->
          <n-grid-item>
            <div class="performance-mode-toggle">
              <n-space justify="space-between" align="center">
                <div class="toggle-label">
                  <n-space align="center">
                    <n-icon size="20" :color="batchStore.PERFORMANCE_MODE ? '#f59e0b' : '#999'">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path fill="currentColor" d="m8.6 22.5l-1.9-3.2l-3.6-.8l.35-3.7L1 12l2.45-2.8l-.35-3.7l3.6-.8l1.9-3.2L12 2.95l3.4-1.45l1.9 3.2l3.6.8l-.35 3.7L23 12l-2.45 2.8l.35 3.7l-3.6.8l-1.9 3.2l-3.4-1.45l-3.4 1.45Zm2.35-6.95L16.6 9.9l-1.4-1.45l-4.25 4.25l-2.15-2.1L7.4 12l3.55 3.55Z"/>
                      </svg>
                    </n-icon>
                    <span :style="{ fontWeight: 'bold', color: batchStore.PERFORMANCE_MODE ? '#f59e0b' : '#666' }">
                      🚀 性能模式
                    </span>
                    <n-tag size="tiny" :type="tokenCountType" :bordered="false">
                      {{ tokenCountText }}
                    </n-tag>
                    <n-tooltip trigger="hover" placement="right">
                      <template #trigger>
                        <n-icon size="16" color="#999">
                          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                            <path fill="currentColor" d="M11 17h2v-6h-2v6zm1-8q.425 0 .713-.288Q13 8.425 13 8t-.287-.713Q12.425 7 12 7t-.712.287Q11 7.575 11 8t.288.712Q11.575 9 12 9zm0 13q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Z"/>
                          </svg>
                        </n-icon>
                      </template>
                      <div style="max-width: 360px;">
                        <p><strong>🚀 性能模式（超大规模必备）</strong></p>
                        <p style="margin-top: 8px; color: #18a058;">✅ <strong>保留的显示：</strong></p>
                        <p style="padding-left: 12px;">• 总体进度统计（成功/失败/跳过数量）</p>
                        <p style="padding-left: 12px;">• 失败原因统计</p>
                        <p style="padding-left: 12px;">• Token状态（等待/执行中/完成/失败）</p>
                        <p style="margin-top: 8px; color: #999;">❌ <strong>隐藏的显示：</strong></p>
                        <p style="padding-left: 12px;">• 单个token的进度百分比</p>
                        <p style="padding-left: 12px;">• 单个token的当前任务名</p>
                        <p style="margin-top: 8px; color: #f59e0b;">
                          <strong>效果：</strong>降低CPU占用50-70%，适合500+并发
                        </p>
                      </div>
                    </n-tooltip>
                  </n-space>
                </div>
                <n-switch
                  v-model:value="batchStore.PERFORMANCE_MODE"
                  :disabled="batchStore.isExecuting"
                  @update:value="handlePerformanceModeChange"
                  size="medium"
                >
                  <template #checked>
                    开启
                  </template>
                  <template #unchecked>
                    关闭
                  </template>
                </n-switch>
              </n-space>
            </div>
          </n-grid-item>
          
          <!-- 🆕 连接池配置（可折叠） -->
          <n-grid-item v-if="batchStore.USE_CONNECTION_POOL">
            <n-collapse :default-expanded-names="[]" accordion>
              <n-collapse-item title="🔧 连接池配置" name="pool-config">
                <template #header-extra>
                  <n-tag size="small" type="info" :bordered="false">
                    {{ batchStore.POOL_SIZE }}池 | {{ batchStore.MAX_CONCURRENT_REQUESTS }}并发 | {{ batchStore.CONNECTION_INTERVAL }}ms
                  </n-tag>
                </template>
                
                <n-space vertical :size="16">
                  <!-- 连接池大小 -->
                  <div class="pool-size-selector">
              <div class="selector-header">
                <label>连接池大小：</label>
                <n-input-number
                  v-model:value="batchStore.POOL_SIZE"
                  :min="1"
                  :max="40"
                  :step="1"
                  :disabled="batchStore.isExecuting"
                  size="medium"
                  :show-button="true"
                  class="number-input"
                  @update:value="handlePoolSizeChange"
                >
                  <template #suffix>
                    <span style="margin-left: 4px;">个</span>
                  </template>
                </n-input-number>
              </div>
              <n-slider
                v-model:value="batchStore.POOL_SIZE"
                :min="1"
                :max="40"
                :step="1"
                :marks="{1: '1', 10: '10 (推荐)', 20: '20', 30: '30', 40: '40'}"
                :disabled="batchStore.isExecuting"
                :tooltip="true"
                @update:value="handlePoolSizeChange"
              />
              <div class="pool-size-hint">
                <n-alert type="info" :bordered="false" size="small">
                  <template #icon>
                    <n-icon><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M11 17h2v-6h-2v6zm1-8q.425 0 .713-.288Q13 8.425 13 8t-.287-.713Q12.425 7 12 7t-.712.287Q11 7.575 11 8t.288.712Q11.575 9 12 9zm0 13q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Z"/></svg></n-icon>
                  </template>
                  <span style="font-size: 12px;" v-if="batchStore.POOL_SIZE <= 10">适用：网络一般，追求稳定</span>
                  <span style="font-size: 12px;" v-else-if="batchStore.POOL_SIZE <= 20">适用：网络良好，平衡性能与稳定性（推荐）</span>
                  <span style="font-size: 12px;" v-else>适用：网络极好（企业/专线），追求极致性能</span>
                </n-alert>
              </div>
            </div>
                  
                  <!-- 同时执行数 -->
                  <div class="concurrent-requests-selector">
              <div class="selector-header">
                <label>同时执行数：</label>
                <n-input-number
                  v-model:value="batchStore.MAX_CONCURRENT_REQUESTS"
                  :min="1"
                  :max="20"
                  :step="1"
                  :disabled="batchStore.isExecuting"
                  size="medium"
                  :show-button="true"
                  class="number-input"
                  @update:value="handleConcurrentRequestsChange"
                >
                  <template #suffix>
                    <span style="margin-left: 4px;">个</span>
                  </template>
                </n-input-number>
              </div>
              <n-slider
                v-model:value="batchStore.MAX_CONCURRENT_REQUESTS"
                :min="1"
                :max="20"
                :step="1"
                :marks="{1: '1', 5: '5 (推荐)', 10: '10', 15: '15', 20: '20'}"
                :disabled="batchStore.isExecuting"
                :tooltip="true"
                @update:value="handleConcurrentRequestsChange"
              />
              <div class="concurrent-requests-hint">
                <n-alert type="info" :bordered="false" size="small">
                  <template #icon>
                    <n-icon><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M11 17h2v-6h-2v6zm1-8q.425 0 .713-.288Q13 8.425 13 8t-.287-.713Q12.425 7 12 7t-.712.287Q11 7.575 11 8t.288.712Q11.575 9 12 9zm0 13q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Z"/></svg></n-icon>
                  </template>
                  <strong>关键参数！</strong>控制同时执行的Token数量，避免拥堵。<span v-if="batchStore.MAX_CONCURRENT_REQUESTS <= 3">极度保守（网络差）</span><span v-else-if="batchStore.MAX_CONCURRENT_REQUESTS <= 6">推荐配置（平衡）</span><span v-else-if="batchStore.MAX_CONCURRENT_REQUESTS <= 10">激进配置（网络好）</span><span v-else>不推荐</span> | 超时频繁请降低，推荐从5开始测试
                </n-alert>
              </div>
            </div>
                  
                  <!-- 连接间隔 -->
                  <div class="connection-interval-selector">
              <div class="selector-header">
                <label>连接间隔：</label>
                <n-input-number
                  v-model:value="batchStore.CONNECTION_INTERVAL"
                  :min="20"
                  :max="300"
                  :step="20"
                  :disabled="batchStore.isExecuting"
                  size="medium"
                  :show-button="true"
                  class="number-input"
                  @update:value="handleConnectionIntervalChange"
                >
                  <template #suffix>
                    <span style="margin-left: 4px;">ms</span>
                  </template>
                </n-input-number>
              </div>
              <n-slider
                v-model:value="batchStore.CONNECTION_INTERVAL"
                :min="20"
                :max="300"
                :step="20"
                :marks="{20: '20', 100: '100 (推荐)', 200: '200', 300: '300'}"
                :disabled="batchStore.isExecuting"
                :tooltip="true"
                @update:value="handleConnectionIntervalChange"
              />
              <div class="connection-interval-hint">
                <n-alert type="info" :bordered="false" size="small">
                  <template #icon>
                    <n-icon><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M11 17h2v-6h-2v6zm1-8q.425 0 .713-.288Q13 8.425 13 8t-.287-.713Q12.425 7 12 7t-.712.287Q11 7.575 11 8t.288.712Q11.575 9 12 9zm0 13q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Z"/></svg></n-icon>
                  </template>
                  控制每个Token建立连接的间隔时间，避免瞬间大量连接。
                  <span v-if="batchStore.CONNECTION_INTERVAL < 80">极速模式</span>
                  <span v-else-if="batchStore.CONNECTION_INTERVAL <= 120">推荐配置</span>
                  <span v-else>保守模式</span>
                </n-alert>
              </div>
            </div>
                </n-space>
              </n-collapse-item>
            </n-collapse>
          </n-grid-item>
          
          <!-- 并发数量（仅在传统模式显示） -->
          <n-grid-item v-if="!batchStore.USE_CONNECTION_POOL">
            <div class="concurrency-selector">
              <div class="selector-header">
                <label>并发数量：</label>
                <n-input-number
                  v-model:value="batchStore.maxConcurrency"
                  :min="1"
                  :max="100"
                  :step="1"
                  :disabled="batchStore.isExecuting"
                  size="medium"
                  :show-button="true"
                  class="number-input"
                  @update:value="handleConcurrencyChange"
                >
                  <template #suffix>
                    <span style="margin-left: 4px;">个</span>
                  </template>
                </n-input-number>
              </div>
              <n-slider
                v-model:value="batchStore.maxConcurrency"
                :min="1"
                :max="100"
                :step="1"
                :marks="{1: '1', 10: '10', 20: '20', 30: '30', 40: '40', 50: '50', 60: '60', 70: '70', 80: '80', 90: '90', 100: '100'}"
                :disabled="batchStore.isExecuting"
                :tooltip="true"
                @update:value="handleConcurrencyChange"
              />
              <div class="concurrency-hint" v-if="batchStore.maxConcurrency > 20">
                <n-alert type="warning" :bordered="false" size="small">
                  <template #icon>
                    <n-icon><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></svg></n-icon>
                  </template>
                  并发数超过20容易导致WSS连接失败，建议启用连接池模式
                </n-alert>
              </div>
            </div>
          </n-grid-item>
          <n-grid-item>
            <div class="tower-count-selector">
              <div class="selector-header">
                <label>爬塔次数：</label>
                <n-input-number
                  v-model:value="batchStore.climbTowerCount"
                  :min="0"
                  :max="100"
                  :step="1"
                  :disabled="batchStore.isExecuting"
                  size="medium"
                  :show-button="true"
                  class="number-input"
                  @update:value="handleTowerCountChange"
                >
                  <template #suffix>
                    <span style="margin-left: 4px;">次</span>
                  </template>
                </n-input-number>
                <n-text depth="3" style="font-size: 12px; margin-left: 8px;">
                  (0=跳过)
                </n-text>
              </div>
            </div>
          </n-grid-item>
          <n-grid-item>
            <div class="tower-count-selector">
              <div class="selector-header">
                <label>发车刷新次数：</label>
                <n-input-number
                  v-model:value="batchStore.carRefreshCount"
                  :min="0"
                  :max="10"
                  :step="1"
                  :disabled="batchStore.isExecuting"
                  size="medium"
                  :show-button="true"
                  class="number-input"
                  @update:value="handleCarRefreshCountChange"
                >
                  <template #suffix>
                    <span style="margin-left: 4px;">次</span>
                  </template>
                </n-input-number>
                <n-text depth="3" style="font-size: 12px; margin-left: 8px;">
                  (0=跳过)
                </n-text>
              </div>
            </div>
          </n-grid-item>
        </n-grid>

        <!-- 自动重试配置 -->
        <div class="auto-retry-config">
          <div class="config-header">
            <n-space align="center">
              <n-switch
                v-model:value="batchStore.autoRetryConfig.enabled"
                @update:value="handleAutoRetryToggle"
              />
              <span class="config-title">自动重试失败任务</span>
              <n-tag
                v-if="batchStore.autoRetryConfig.enabled"
                type="success"
                size="small"
                :bordered="false"
              >
                已启用
              </n-tag>
            </n-space>
          </div>
          <div v-if="batchStore.autoRetryConfig.enabled" class="config-details">
            <n-space vertical :size="12">
              <div class="config-item">
                <span class="label">最大重试轮数：</span>
                <n-input-number
                  v-model:value="batchStore.autoRetryConfig.maxRetries"
                  :min="1"
                  :max="10"
                  :step="1"
                  size="small"
                  style="width: 100px;"
                  @update:value="handleAutoRetryConfigChange"
                >
                  <template #suffix>轮</template>
                </n-input-number>
                <n-text depth="3" style="margin-left: 8px; font-size: 12px;">
                  ({{ batchStore.currentRetryRound }}/{{ batchStore.autoRetryConfig.maxRetries }})
                </n-text>
              </div>
              <div class="config-item">
                <span class="label">重试间隔时间：</span>
                <n-input-number
                  v-model:value="retryDelaySeconds"
                  :min="1"
                  :max="60"
                  :step="1"
                  size="small"
                  style="width: 100px;"
                  @update:value="handleRetryDelayChange"
                >
                  <template #suffix>秒</template>
                </n-input-number>
              </div>
              <n-alert type="info" size="small" :bordered="false">
                开启后，批量任务完成时如有失败的token，会自动重试最多{{ batchStore.autoRetryConfig.maxRetries }}轮
              </n-alert>
            </n-space>
          </div>
        </div>

        <!-- 🆕 日志控制面板 -->
        <div class="log-control-panel">
          <div class="log-control-header" @click="showLogControl = !showLogControl" style="cursor: pointer;">
            <n-icon size="18"><DocumentText /></n-icon>
            <span>日志打印控制</span>
            <n-space style="margin-left: auto;">
              <n-button
                text
                size="small"
                @click.stop="enableAllLogs"
              >
                全部启用
              </n-button>
              <n-button
                text
                size="small"
                @click.stop="disableAllLogs"
              >
                全部禁用
              </n-button>
              <n-icon size="20" style="transition: transform 0.3s ease;" :style="{ transform: showLogControl ? 'rotate(180deg)' : 'rotate(0deg)' }">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                  <path fill="currentColor" d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6l-6-6l1.41-1.41z"/>
                </svg>
              </n-icon>
            </n-space>
          </div>
          
          <div v-show="showLogControl" class="log-control-body">
            <div class="log-section">
              <div class="section-title">任务日志</div>
              <div class="log-switches">
                <n-space>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.dailyFix" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>一键补差</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.climbTower" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>爬塔</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.restartBottle" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>重启盐罐</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.legionSignIn" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>俱乐部签到</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.autoStudy" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>一键答题</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.claimHangupReward" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>挂机奖励</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.addClock" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>加钟</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.sendCar" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>发车</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.monthlyTask" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>月度任务</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.blackMarket" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>小号黑市购买</span>
                  </div>
                </n-space>
              </div>
            </div>
            
            <div class="log-section">
              <div class="section-title">系统日志</div>
              <div class="log-switches">
                <n-space>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.batch" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>批量执行</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.heartbeat" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>心跳机制</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.websocket" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>WebSocket</span>
                  </div>
                  <div class="log-switch-item">
                    <n-switch v-model:value="batchStore.logConfig.gameMessage" size="small" @update:value="batchStore.saveLogConfig" />
                    <span>游戏消息跳过</span>
                  </div>
                </n-space>
              </div>
            </div>
          </div>
        </div>

        <!-- 任务列表预览 -->
        <div class="tasks-preview">
          <div class="preview-header">
            <span>包含任务 ({{ currentTasks.length }}个)：</span>
            <n-button
              text
              size="small"
              @click="showTemplateEditor = true"
            >
              <template #icon>
                <n-icon><Settings /></n-icon>
              </template>
              自定义模板
            </n-button>
          </div>
          <div class="task-tags">
            <n-tag
              v-for="task in currentTasks"
              :key="task.id"
              :color="task.color ? { color: task.color, textColor: '#fff', borderColor: task.color } : undefined"
              :type="task.color ? undefined : task.type"
              size="small"
              :class="{ 'clickable-tag': task.id === 'dailyFix' || task.id === 'blackMarket' }"
              :style="{ cursor: (task.id === 'dailyFix' || task.id === 'blackMarket') ? 'pointer' : 'default' }"
              @click="handleTaskClick(task.id)"
            >
              {{ task.label }}
              <span v-if="task.id === 'dailyFix'" style="margin-left: 4px;">
                ({{ dailyTaskStateStore.dailyFixTaskDefinitions.length }}个子任务)
              </span>
            </n-tag>
          </div>
        </div>

        <!-- 执行控制按钮 -->
        <div class="control-buttons">
          <n-space>
            <n-button
              v-if="!batchStore.isExecuting"
              type="primary"
              size="large"
              :disabled="!batchStore.canExecute"
              @click="handleStart"
            >
              <template #icon>
                <n-icon><PlayCircle /></n-icon>
              </template>
              开始执行 ({{ tokenStore.gameTokens.length }}个角色)
            </n-button>

            <n-button
              v-if="!batchStore.isExecuting && failedTaskCount > 0"
              type="warning"
              size="large"
              @click="handleRetryFailed"
            >
              <template #icon>
                <n-icon><Refresh /></n-icon>
              </template>
              重试失败 ({{ failedTaskCount }}个)
            </n-button>

            <n-button
              v-if="batchStore.isExecuting && !batchStore.isPaused"
              type="warning"
              size="large"
              @click="batchStore.pauseExecution()"
            >
              <template #icon>
                <n-icon><Pause /></n-icon>
              </template>
              暂停
            </n-button>

            <n-button
              v-if="batchStore.isExecuting && batchStore.isPaused"
              type="success"
              size="large"
              @click="batchStore.resumeExecution()"
            >
              <template #icon>
                <n-icon><Play /></n-icon>
              </template>
              继续
            </n-button>

            <n-button
              v-if="batchStore.isExecuting || batchStore.isAutoRetryWaiting"
              type="error"
              size="large"
              @click="handleStop"
            >
              <template #icon>
                <n-icon><Stop /></n-icon>
              </template>
              {{ batchStore.isAutoRetryWaiting ? '取消重试' : '停止' }}
            </n-button>

            <n-button
              size="large"
              @click="showScheduler = true"
            >
              <template #icon>
                <n-icon><Time /></n-icon>
              </template>
              定时设置
            </n-button>

            <n-button
              size="large"
              @click="showHistory = true"
            >
              <template #icon>
                <n-icon><List /></n-icon>
              </template>
              执行历史
            </n-button>

            <n-button
              size="large"
              type="info"
              @click="handleManualMemoryCleanup"
            >
              <template #icon>
                <n-icon>
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path fill="currentColor" d="M19.36 2.72l1.42 1.42-5.72 5.71c1.07 1.54 1.22 3.39.32 4.59L9.06 8.12c1.2-.9 3.05-.75 4.59.32l5.71-5.72M5.93 17.57c-2.01-2.01-3.24-4.41-3.58-6.65l4.88-2.09 7.44 7.44-2.09 4.88c-2.24-.34-4.64-1.57-6.65-3.58z"/>
                  </svg>
                </n-icon>
              </template>
              清理内存
            </n-button>
            
            <n-button
              size="large"
              type="info"
              @click="handleStorageStats"
            >
              <template #icon>
                <n-icon>
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path fill="currentColor" d="M4 4h16v2H4V4m0 4h16v2H4V8m0 4h16v2H4v-2m0 4h10v2H4v-2z"/>
                  </svg>
                </n-icon>
              </template>
              存储统计
            </n-button>
          </n-space>
        </div>

        <!-- 执行进度 -->
        <div
          v-if="batchStore.isExecuting"
          class="execution-progress"
        >
          <div class="progress-header">
            <n-space align="center" :size="8">
              <span>总体进度 ({{ batchStore.executionStats.success + batchStore.executionStats.failed + batchStore.executionStats.skipped }}/{{ batchStore.executionStats.total }})</span>
              <n-tag
                v-if="batchStore.isAutoRetryWaiting"
                type="info"
                size="small"
                :bordered="false"
              >
                ⏳ 等待自动重试...
              </n-tag>
              <n-tag
                v-else-if="batchStore.currentRetryRound > 0"
                type="warning"
                size="small"
                :bordered="false"
              >
                🔄 第{{ batchStore.currentRetryRound }}轮重试
              </n-tag>
            </n-space>
            <span>{{ batchStore.overallProgress }}%</span>
          </div>
          <n-progress
            type="line"
            :percentage="batchStore.overallProgress"
            :status="batchStore.isPaused ? 'warning' : 'info'"
            :show-indicator="false"
          />
        </div>

        <!-- 统计信息 -->
        <div
          v-if="batchStore.isExecuting || batchStore.executionStats.endTime"
          class="stats-panel"
        >
          <n-space justify="space-around">
            <n-statistic label="总计" :value="batchStore.executionStats.total" />
            <n-statistic
              label="成功"
              :value="batchStore.executionStats.success"
              class="success"
            />
            <n-statistic
              label="失败"
              :value="batchStore.executionStats.failed"
              class="failed"
            />
            <n-statistic
              label="跳过"
              :value="batchStore.executionStats.skipped"
              class="skipped"
            />
            <n-statistic
              v-if="batchStore.autoRetryConfig.enabled"
              label="重试轮数"
              :value="`${batchStore.currentRetryRound}/${batchStore.autoRetryConfig.maxRetries}`"
              class="retry-round"
            />
            <n-statistic
              label="耗时"
              :value="executionDuration"
            />
          </n-space>
        </div>
        
        <!-- 🆕 失败原因统计 -->
        <div
          v-if="hasFailureReasons"
          class="failure-reasons-panel"
        >
          <n-card title="📋 失败原因统计" size="small" :bordered="false">
            <div class="failure-reasons-list">
              <div
                v-for="([reason, count], index) in failureReasonsList"
                :key="index"
                class="failure-reason-item"
              >
                <span class="reason-text">{{ reason }}</span>
                <n-tag type="error" size="small">{{ count }}个Token</n-tag>
              </div>
            </div>
          </n-card>
        </div>
      </n-space>
    </div>

    <!-- 任务模板编辑器弹窗 -->
    <n-modal
      v-model:show="showTemplateEditor"
      preset="card"
      title="自定义任务模板"
      :style="{ width: '600px' }"
      :bordered="false"
      :segmented="true"
    >
      <TemplateEditor
        :templates="batchStore.taskTemplates"
        @save="handleSaveTemplate"
        @delete="handleDeleteTemplate"
        @close="showTemplateEditor = false"
      />
    </n-modal>

    <!-- 定时设置弹窗 -->
    <n-modal
      v-model:show="showScheduler"
      preset="card"
      title="定时任务设置"
      :style="{ width: '600px' }"
      :bordered="false"
      :segmented="true"
    >
      <SchedulerConfig
        :config="batchStore.schedulerConfig"
        @save="handleSaveScheduler"
        @close="showScheduler = false"
      />
    </n-modal>

    <!-- 执行历史弹窗 -->
    <n-modal
      v-model:show="showHistory"
      preset="card"
      title="执行历史"
      :style="{ width: '700px' }"
      :bordered="false"
      :segmented="true"
    >
      <ExecutionHistory
        :history="batchStore.executionHistory"
        @clear="handleClearHistory"
        @close="showHistory = false"
      />
    </n-modal>

    <!-- 一键补差子任务详情弹窗 -->
    <n-modal
      v-model:show="showDailyFixDetail"
      preset="card"
      title="一键补差 - 子任务详情"
      :style="{ width: '700px', maxHeight: '80vh' }"
      :bordered="false"
      :segmented="true"
    >
      <div class="daily-fix-detail">
        <n-alert type="info" :bordered="false" style="margin-bottom: 16px;">
          <template #header>
            <strong>任务说明</strong>
          </template>
          "一键补差"会自动执行以下 {{ dailyTaskStateStore.dailyFixTaskDefinitions.length }} 个子任务，
          标记为 <n-tag type="error" size="tiny" :bordered="false">消耗资源</n-tag> 的任务在已完成后会自动跳过。
        </n-alert>

        <n-scrollbar style="max-height: 500px;">
          <n-list bordered>
            <n-list-item
              v-for="(task, index) in dailyTaskStateStore.dailyFixTaskDefinitions"
              :key="task.id"
            >
              <template #prefix>
                <n-tag :bordered="false" size="small" type="default">
                  {{ index + 1 }}
                </n-tag>
              </template>
              <div class="task-item">
                <span class="task-name">{{ task.name }}</span>
                <n-tag
                  v-if="task.consumesResources"
                  type="error"
                  size="tiny"
                  :bordered="false"
                  style="margin-left: 8px;"
                >
                  消耗资源
                </n-tag>
              </div>
            </n-list-item>
          </n-list>
        </n-scrollbar>

        <n-divider style="margin: 16px 0;" />

        <div class="task-summary">
          <n-space vertical>
            <n-statistic label="任务总数" :value="dailyTaskStateStore.dailyFixTaskDefinitions.length" />
            <n-statistic 
              label="消耗资源任务" 
              :value="dailyTaskStateStore.resourceConsumingTasks.filter(t => dailyTaskStateStore.dailyFixTaskDefinitions.find(dt => dt.id === t.id)).length"
            >
              <template #suffix>
                <span style="font-size: 14px; color: #999;">个（已完成会跳过）</span>
              </template>
            </n-statistic>
            <n-statistic 
              label="预计执行时间" 
              :value="Math.ceil(dailyTaskStateStore.dailyFixTaskDefinitions.length * 1.2)"
            >
              <template #suffix>
                <span style="font-size: 14px; color: #999;">秒（单个角色）</span>
              </template>
            </n-statistic>
          </n-space>
        </div>

        <div style="margin-top: 16px; text-align: right;">
          <n-button type="primary" @click="showDailyFixDetail = false">
            知道了
          </n-button>
        </div>
      </div>
    </n-modal>

    <!-- 小号黑市购买详情弹窗 -->
    <n-modal
      v-model:show="showBlackMarketDetail"
      preset="card"
      title="小号黑市购买 - 任务说明"
      :style="{ width: '600px' }"
      :bordered="false"
      :segmented="true"
    >
      <div class="blackmarket-detail">
        <n-alert type="warning" :bordered="false" style="margin-bottom: 16px;">
          <template #header>
            <strong>固定购买配置</strong>
          </template>
          此任务使用固定购买策略，不可自定义配置
        </n-alert>

        <n-card title="购买策略" :bordered="false" size="small" style="margin-bottom: 16px;">
          <n-list bordered>
            <n-list-item>
              <template #prefix>
                <n-tag type="success" :bordered="false">✓</n-tag>
              </template>
              <div class="purchase-item">
                <span class="item-name">青铜宝箱</span>
                <n-tag type="error" size="small" :bordered="false">必买</n-tag>
                <span class="item-price">原价: 400金砖</span>
              </div>
            </n-list-item>
            <n-list-item>
              <template #prefix>
                <n-tag type="warning" :bordered="false">~</n-tag>
              </template>
              <div class="purchase-item">
                <span class="item-name">黄金宝箱</span>
                <n-tag type="warning" size="small" :bordered="false">≤5折购买</n-tag>
                <span class="item-price">原价: 375金砖</span>
              </div>
            </n-list-item>
            <n-list-item>
              <template #prefix>
                <n-tag type="success" :bordered="false">✓</n-tag>
              </template>
              <div class="purchase-item">
                <span class="item-name">铂金宝箱</span>
                <n-tag type="error" size="small" :bordered="false">必买</n-tag>
                <span class="item-price">原价: 625金砖</span>
              </div>
            </n-list-item>
          </n-list>
        </n-card>

        <n-card title="执行流程" :bordered="false" size="small" style="margin-bottom: 16px;">
          <n-steps vertical :current="4" :status="'finish'">
            <n-step title="获取黑市信息" description="发送store_goodslist命令" />
            <n-step title="第一轮购买" description="按策略购买青铜、黄金(≤5折)、铂金宝箱" />
            <n-step title="刷新黑市" description="发送store_refresh命令(消耗100金砖)" />
            <n-step title="第二轮购买" description="再次按策略购买宝箱" />
          </n-steps>
        </n-card>

        <n-alert type="info" :bordered="false" style="margin-bottom: 16px;">
          <template #header>
            <strong>智能跳过</strong>
          </template>
          ✓ 如果"黑市购买1次物品"每日任务已完成，自动跳过<br/>
          ✓ 第一次刷新免费，后续刷新需要100金砖
        </n-alert>

        <div class="task-summary">
          <n-space vertical>
            <n-statistic label="预计消耗" value="~1400-2900">
              <template #suffix>
                <span style="font-size: 14px; color: #999;">金砖（含刷新费用）</span>
              </template>
            </n-statistic>
            <n-statistic label="预计执行时间" value="~5-8">
              <template #suffix>
                <span style="font-size: 14px; color: #999;">秒（单个角色）</span>
              </template>
            </n-statistic>
          </n-space>
        </div>

        <div style="margin-top: 16px; text-align: right;">
          <n-button type="primary" @click="showBlackMarketDetail = false">
            知道了
          </n-button>
        </div>
      </div>
    </n-modal>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, h } from 'vue'
import { useMessage, useDialog } from 'naive-ui'
import { 
  Flash, 
  Refresh, 
  Settings, 
  PlayCircle, 
  Pause, 
  Play, 
  Stop, 
  Time, 
  List,
  DocumentText
} from '@vicons/ionicons5'
import { useBatchTaskStore } from '@/stores/batchTaskStore'
import { useTokenStore } from '@/stores/tokenStore'
import { useDailyTaskStateStore } from '@/stores/dailyTaskState'
import { taskScheduler } from '@/utils/taskScheduler'
import TemplateEditor from './TemplateEditor.vue'
import SchedulerConfig from './SchedulerConfig.vue'
import ExecutionHistory from './ExecutionHistory.vue'

const batchStore = useBatchTaskStore()
const tokenStore = useTokenStore()
const dailyTaskStateStore = useDailyTaskStateStore()
const message = useMessage()
const dialog = useDialog()

// 弹窗状态
const showTemplateEditor = ref(false)
const showScheduler = ref(false)
const showHistory = ref(false)
const showDailyFixDetail = ref(false)
const showBlackMarketDetail = ref(false) // 黑市购买说明
const showLogControl = ref(false) // 日志控制面板折叠状态，默认折叠

// 任务定义（可扩展）
const taskDefinitions = {
  dailyFix: { label: '一键补差', type: 'warning', color: '#f0a020' },          // 金橙色
  restartBottle: { label: '重启盐罐机器人', type: 'success', color: '#18a058' }, // 绿色
  legionSignIn: { label: '俱乐部签到', type: 'primary', color: '#2080f0' },     // 蓝色
  autoStudy: { label: '一键答题', type: 'error', color: '#d03050' },           // 红色
  claimHangupReward: { label: '领取挂机奖励', type: 'info', color: '#70c0e8' }, // 浅蓝色
  addClock: { label: '加钟', type: 'default', color: '#909399' },              // 灰色
  sendCar: { label: '发车', type: 'warning', color: '#9333ea' },               // 紫色
  climbTower: { label: '爬塔', type: 'error', color: '#ec4899' },              // 粉红色
  blackMarket: { label: '小号黑市购买', type: 'info', color: '#f59e0b' }        // 橙色
}

// 模板选项
const templateOptions = computed(() => {
  return Object.keys(batchStore.taskTemplates).map(key => ({
    label: batchStore.taskTemplates[key].name,
    value: key
  }))
})

// 当前选中模板的任务列表
const currentTasks = computed(() => {
  return batchStore.currentTemplateTasks.map(taskId => ({
    id: taskId,
    ...taskDefinitions[taskId]
  }))
})

// 执行耗时
const executionDuration = computed(() => {
  const stats = batchStore.executionStats
  if (!stats.startTime) return '0秒'
  
  const endTime = stats.endTime || Date.now()
  const duration = Math.round((endTime - stats.startTime) / 1000)
  
  if (duration < 60) return `${duration}秒`
  
  const minutes = Math.floor(duration / 60)
  const seconds = duration % 60
  return `${minutes}分${seconds}秒`
})

// 🆕 失败原因统计
const hasFailureReasons = computed(() => {
  return Object.keys(batchStore.failureReasonsStats).length > 0
})

const failureReasonsList = computed(() => {
  return Object.entries(batchStore.failureReasonsStats)
    .sort((a, b) => b[1] - a[1]) // 按数量降序排列
})

// 格式化时间间隔
const formatInterval = (minutes) => {
  if (minutes < 60) {
    return `${minutes}分钟`
  } else if (minutes % 60 === 0) {
    return `${minutes / 60}小时`
  } else {
    const hours = Math.floor(minutes / 60)
    const mins = minutes % 60
    return `${hours}小时${mins}分钟`
  }
}

// 定时任务状态文本
const schedulerStatusText = computed(() => {
  if (!batchStore.schedulerConfig.enabled) return '定时任务：未启用'
  
  if (batchStore.schedulerConfig.type === 'interval') {
    return `定时任务：每${formatInterval(batchStore.schedulerConfig.interval)}`
  } else {
    return `定时任务：每日${batchStore.schedulerConfig.dailyTimes.length}次`
  }
})

// 定时任务状态标签类型
const schedulerStatusType = computed(() => {
  return batchStore.schedulerConfig.enabled ? 'warning' : 'default'
})

// 🆕 v3.14.1 性能模式 - Token数量提示
const tokenCountType = computed(() => {
  const count = tokenStore.gameTokens.length
  if (count > 500) return 'error' // 强烈推荐
  if (count > 200) return 'warning' // 可选
  return 'success' // 不需要
})

const tokenCountText = computed(() => {
  const count = tokenStore.gameTokens.length
  if (count > 500) return `${count}个Token (强烈推荐)`
  if (count > 200) return `${count}个Token (可选)`
  return `${count}个Token`
})

// 格式化最后执行时间
const formatLastExecutionTime = computed(() => {
  if (!batchStore.schedulerConfig.lastExecutionTime) return '从未执行'
  
  const date = new Date(batchStore.schedulerConfig.lastExecutionTime)
  return date.toLocaleString('zh-CN', {
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
})

// 失败任务数量
const failedTaskCount = computed(() => {
  return Object.values(batchStore.taskProgress).filter(
    progress => progress.status === 'failed'
  ).length
})

// 重试延迟（秒转换）
const retryDelaySeconds = computed({
  get: () => batchStore.autoRetryConfig.retryDelay / 1000,
  set: (value) => {
    batchStore.autoRetryConfig.retryDelay = value * 1000
    handleAutoRetryConfigChange()
  }
})

// 处理任务标签点击
const handleTaskClick = (taskId) => {
  if (taskId === 'dailyFix') {
    showDailyFixDetail.value = true
  } else if (taskId === 'blackMarket') {
    showBlackMarketDetail.value = true
  }
}

// 开始执行
const handleStart = () => {
  // 🆕 检查是否有保存的进度
  if (batchStore.hasSavedProgress && batchStore.savedProgress) {
    const completed = batchStore.savedProgress.completedTokenIds.length
    const total = batchStore.savedProgress.allTokenIds.length
    const remaining = total - completed
    
    dialog.warning({
      title: '发现未完成的任务',
      content: () => {
        return h('div', [
          h('p', `检测到上次有未完成的批量任务：`),
          h('ul', { style: 'margin: 12px 0; padding-left: 24px;' }, [
            h('li', `总计：${total} 个Token`),
            h('li', `已完成：${completed} 个`),
            h('li', { style: 'color: #ff6b6b; font-weight: bold;' }, `剩余：${remaining} 个`)
          ]),
          h('p', { style: 'margin-top: 16px; font-weight: bold;' }, '您想要：')
        ])
      },
      positiveText: '继续上次进度',
      negativeText: '重新开始',
      onPositiveClick: () => {
        batchStore.startBatchExecution(null, null, false, true)
        message.success(`继续执行剩余 ${remaining} 个Token`)
      },
      onNegativeClick: () => {
        dialog.warning({
          title: '确认重新开始',
          content: `确定要重新开始执行所有 ${tokenStore.gameTokens.length} 个角色的任务吗？\n\n已完成的 ${completed} 个Token将会重新执行。`,
          positiveText: '确定重新开始',
          negativeText: '取消',
          onPositiveClick: () => {
            batchStore.clearSavedProgress()
            batchStore.startBatchExecution()
            message.success('批量任务已启动（重新开始）')
          }
        })
      }
    })
  } else {
    // 没有保存的进度，正常开始
    dialog.warning({
      title: '确认执行',
      content: `即将对 ${tokenStore.gameTokens.length} 个角色执行批量任务，是否继续？`,
      positiveText: '确定',
      negativeText: '取消',
      onPositiveClick: () => {
        batchStore.startBatchExecution()
        message.success('批量任务已启动')
      }
    })
  }
}

// 停止执行
const handleStop = () => {
  let dialogInstance = null
  
  const updateDialogContent = (content, loading = false) => {
    if (dialogInstance) {
      dialogInstance.content = () => h('div', { style: 'padding: 10px 0;' }, [
        loading ? h('div', { style: 'display: flex; align-items: center; gap: 12px;' }, [
          h('div', {
            style: 'width: 20px; height: 20px; border: 2px solid #18a058; border-top-color: transparent; border-radius: 50%; animation: spin 1s linear infinite;'
          }),
          h('span', content)
        ]) : h('span', content)
      ])
    }
  }
  
  dialogInstance = dialog.warning({
    title: '确认停止',
    content: '是否停止当前批量任务？',
    positiveText: '确定',
    negativeText: '取消',
    closable: false,  // 停止过程中不允许关闭
    closeOnEsc: false,
    maskClosable: false,
    onPositiveClick: async () => {
      // 🔥 更新对话框内容，显示正在停止
      updateDialogContent('正在停止任务并清理连接...', true)
      
      // 禁用按钮，防止重复点击
      dialogInstance.positiveText = '停止中...'
      dialogInstance.positiveButtonProps = { disabled: true, loading: true }
      dialogInstance.negativeButtonProps = { disabled: true }
      
      try {
        await batchStore.stopExecution()
        
        // 更新为成功状态
        updateDialogContent('✅ 批量任务已停止，所有连接已清理', false)
        
        // 显示500ms后自动关闭对话框
        await new Promise(resolve => setTimeout(resolve, 500))
        
        // 关闭对话框
        dialogInstance.destroy()
        
        // 显示成功消息
        message.success('批量任务已停止')
        
      } catch (error) {
        updateDialogContent('❌ 停止任务时出错', false)
        console.error('停止任务错误:', error)
        
        // 显示错误后允许关闭
        dialogInstance.positiveText = '关闭'
        dialogInstance.positiveButtonProps = { disabled: false }
        dialogInstance.closable = true
      }
      
      return false  // 阻止对话框自动关闭
    }
  })
}

// 重试失败任务
const handleRetryFailed = () => {
  const count = failedTaskCount.value
  dialog.warning({
    title: '重试失败任务',
    content: `即将重新执行 ${count} 个失败的任务，是否继续？`,
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: async () => {
      await batchStore.retryFailedTasks()
      message.success(`已重新执行 ${count} 个失败的任务`)
    }
  })
}

// 自动重试开关切换
const handleAutoRetryToggle = (value) => {
  batchStore.saveAutoRetryConfig({ enabled: value })
  if (value) {
    message.success('已启用自动重试失败任务')
  } else {
    message.info('已关闭自动重试')
  }
}

// 自动重试配置变更
const handleAutoRetryConfigChange = () => {
  batchStore.saveAutoRetryConfig(batchStore.autoRetryConfig)
  message.success('自动重试配置已更新')
}

// 重试延迟变更
const handleRetryDelayChange = (value) => {
  batchStore.autoRetryConfig.retryDelay = value * 1000
  batchStore.saveAutoRetryConfig(batchStore.autoRetryConfig)
}

// 保存任务模板
const handleSaveTemplate = (name, tasks) => {
  batchStore.saveTaskTemplate(name, tasks)
  message.success('任务模板已保存')
}

// 删除任务模板
const handleDeleteTemplate = (name) => {
  batchStore.deleteTaskTemplate(name)
  message.success('任务模板已删除')
}

// 保存调度器配置
const handleSaveScheduler = (config) => {
  // 如果是首次启用，显示确认对话框
  if (config.enabled && !batchStore.schedulerConfig.enabled) {
    const scheduleDesc = config.type === 'interval' 
      ? `每 ${formatInterval(config.interval)} 自动执行一次`
      : `每天在 ${config.dailyTimes.join(', ')} 自动执行`
    
    dialog.warning({
      title: '⚠️ 首次启用定时任务',
      content: `您正在启用定时任务功能：\n\n${scheduleDesc}\n\n任务将在后台自动执行，请确认您已了解此功能。\n\n提示：您可以随时在此页面停用定时任务。`,
      positiveText: '确认启用',
      negativeText: '取消',
      onPositiveClick: () => {
        batchStore.saveSchedulerConfig(config)
        startScheduler()
        message.success('✅ 定时任务已启动')
        showScheduler.value = false
      }
    })
  } else {
    batchStore.saveSchedulerConfig(config)
    
    // 重启调度器
    if (config.enabled) {
      startScheduler()
      message.success('定时任务已更新')
    } else {
      stopScheduler()
      message.info('定时任务已停止')
    }
    
    showScheduler.value = false
  }
}

// 快速切换调度器（用于快速控制栏）
const handleQuickToggleScheduler = (enabled) => {
  if (!enabled) {
    // 停用确认
    dialog.warning({
      title: '停用定时任务',
      content: '确定要停用定时任务吗？您可以随时重新启用。',
      positiveText: '确定停用',
      negativeText: '取消',
      onPositiveClick: () => {
        batchStore.saveSchedulerConfig({ enabled: false })
        stopScheduler()
        message.info('✅ 定时任务已停用')
      }
    })
  } else {
    // 快速启用（使用现有配置）
    batchStore.saveSchedulerConfig({ enabled: true })
    startScheduler()
    message.success('✅ 定时任务已启用')
  }
}

// 清空历史
const handleClearHistory = () => {
  batchStore.clearHistory()
  message.success('执行历史已清空')
}

// 手动清理内存
const handleManualMemoryCleanup = () => {
  // 获取当前内存使用情况
  const memory = batchStore.getMemoryUsage()
  const memoryInfo = memory 
    ? `当前内存使用：${memory.used}MB / ${memory.limit}MB (${((memory.used / memory.limit) * 100).toFixed(1)}%)`
    : '浏览器不支持内存监控API'
  
  dialog.info({
    title: '🧹 内存清理',
    content: () => {
      return h('div', [
        h('p', { style: 'margin-bottom: 12px; font-weight: bold; color: #666;' }, memoryInfo),
        h('p', '即将执行以下清理操作：'),
        h('ul', { style: 'margin: 12px 0; padding-left: 24px;' }, [
          h('li', '清理已完成任务的进度数据'),
          h('li', '清理待发送的UI更新队列'),
          h('li', '清空控制台日志历史（释放约10-50MB）'),
          h('li', '释放WebSocket发送队列'),
          h('li', '建议浏览器执行垃圾回收')
        ]),
        h('p', { style: 'margin-top: 16px; color: #999; font-size: 13px;' }, 
          '💡 提示：此操作不会影响任务执行，只是释放不再需要的内存'
        )
      ])
    },
    positiveText: '立即清理',
    negativeText: '取消',
    onPositiveClick: () => {
      // 执行清理
      const cleanedCount = batchStore.forceCleanupTaskProgress()
      batchStore.clearPendingUIUpdates()
      batchStore.clearConsoleLogs()
      
      // 建议垃圾回收
      if (typeof window !== 'undefined' && window.gc) {
        window.gc()
        message.success(`✅ 已清理 ${cleanedCount} 个任务数据并触发垃圾回收`, { duration: 5000 })
      } else {
        message.success(`✅ 已清理 ${cleanedCount} 个任务数据，内存释放中...`, { duration: 5000 })
        
        // 给出开启GC的提示
        setTimeout(() => {
          message.info('💡 如需强制垃圾回收，请用 --js-flags="--expose-gc" 启动浏览器', { duration: 6000 })
        }, 1000)
      }
    }
  })
}

// 🆕 v3.14.1: 存储统计和清理
const handleStorageStats = () => {
  // 获取dailyTaskState的统计信息
  const dailyTaskStats = dailyTaskStateStore.getStorageStats()
  
  // 获取内存使用情况
  const memory = batchStore.getMemoryUsage()
  const memoryInfo = memory 
    ? `${memory.used}MB / ${memory.limit}MB (${((memory.used / memory.limit) * 100).toFixed(1)}%)`
    : '不支持'
  
  dialog.info({
    title: '📊 存储统计',
    content: () => {
      return h('div', [
        h('p', { style: 'margin-bottom: 16px; font-weight: bold; color: #666;' }, '当前存储使用情况'),
        
        // 内存使用
        h('div', { style: 'margin-bottom: 16px; padding: 12px; background: #f5f5f5; border-radius: 8px;' }, [
          h('p', { style: 'font-weight: 600; margin-bottom: 8px;' }, '💾 内存使用'),
          h('p', { style: 'margin-left: 16px; color: #666;' }, `当前：${memoryInfo}`)
        ]),
        
        // DailyTaskState统计
        h('div', { style: 'margin-bottom: 16px; padding: 12px; background: #f5f5f5; border-radius: 8px;' }, [
          h('p', { style: 'font-weight: 600; margin-bottom: 8px;' }, '📋 每日任务状态数据'),
          h('p', { style: 'margin-left: 16px; color: #666;' }, `Token数量：${dailyTaskStats.tokenCount}`),
          h('p', { style: 'margin-left: 16px; color: #666;' }, `任务总数：${dailyTaskStats.totalTasks}`),
          h('p', { style: 'margin-left: 16px; color: #666;' }, `已完成：${dailyTaskStats.completedTasks}`),
          h('p', { style: 'margin-left: 16px; color: #666;' }, `存储大小：${dailyTaskStats.estimatedSize}`)
        ]),
        
        // 清理选项
        h('p', { style: 'margin-top: 16px; color: #999; font-size: 13px;' }, 
          '💡 可以清理长期未使用（7天以上）的Token数据来释放存储空间'
        )
      ])
    },
    positiveText: '清理旧数据',
    negativeText: '关闭',
    onPositiveClick: () => {
      const cleaned = dailyTaskStateStore.cleanUnusedTokenData()
      if (cleaned > 0) {
        message.success(`✅ 已清理 ${cleaned} 个长期未使用Token的数据`, { duration: 5000 })
        
        // 重新显示统计信息
        setTimeout(() => {
          handleStorageStats()
        }, 500)
      } else {
        message.info('✨ 没有需要清理的旧数据', { duration: 3000 })
      }
    }
  })
}

// 并发数改变
const handleConcurrencyChange = (value) => {
  batchStore.setMaxConcurrency(value)
  message.success(`并发数已设置为 ${value}`)
}

// 🆕 v3.13.0 连接池模式切换
const handlePoolModeChange = (enabled) => {
  batchStore.setUseConnectionPool(enabled)
  if (enabled) {
    message.success('🏊 连接池模式已启用 - 支持100+并发稳定运行', {
      duration: 3000
    })
  } else {
    message.info('⚙️ 连接池模式已禁用 - 使用传统模式', {
      duration: 3000
    })
  }
}

// 🆕 v3.14.1 性能模式切换
const handlePerformanceModeChange = (enabled) => {
  batchStore.setPerformanceMode(enabled)
  
  const tokenCount = tokenStore.gameTokens.length
  
  if (enabled) {
    message.success({
      content: `🚀 性能模式已启用 - CPU占用降低50-70%`,
      duration: 4000
    })
    
    // 给出建议
    if (tokenCount > 500) {
      message.info({
        content: `✅ 检测到${tokenCount}个Token，强烈推荐使用性能模式`,
        duration: 4000
      })
    }
  } else {
    message.info({
      content: `⚙️ 性能模式已禁用 - 显示完整进度信息`,
      duration: 3000
    })
    
    // 给出提示
    if (tokenCount > 500) {
      message.warning({
        content: `⚠️ ${tokenCount}个Token可能导致高CPU占用，建议启用性能模式`,
        duration: 4000
      })
    }
  }
}

// 🆕 v3.13.0 连接池大小改变
const handlePoolSizeChange = (value) => {
  batchStore.setPoolSize(value)
  message.success(`连接池大小已设置为 ${value}`)
}

// 🆕 v3.13.2 最大并发请求数改变
const handleConcurrentRequestsChange = (value) => {
  batchStore.setMaxConcurrentRequests(value)
  message.success(`同时执行数已设置为 ${value}`, {
    duration: 3000
  })
}

// 🆕 连接间隔改变
const handleConnectionIntervalChange = (value) => {
  batchStore.setConnectionInterval(value)
  message.success(`连接间隔已设置为 ${value}ms`, {
    duration: 3000
  })
}

// 爬塔次数改变
const handleTowerCountChange = (value) => {
  batchStore.setClimbTowerCount(value)
  if (value === 0) {
    message.info('爬塔次数设置为0，将跳过爬塔任务')
  } else {
    message.success(`爬塔次数已设置为 ${value}`)
  }
}

// 发车刷新次数改变
const handleCarRefreshCountChange = (value) => {
  batchStore.setCarRefreshCount(value)
  if (value === 0) {
    message.info('发车刷新次数设置为0，将跳过刷新步骤')
  } else {
    message.success(`发车刷新次数已设置为 ${value}`)
  }
}

// 🆕 日志控制
const enableAllLogs = () => {
  const keys = Object.keys(batchStore.logConfig)
  keys.forEach(key => {
    batchStore.logConfig[key] = true
  })
  batchStore.saveLogConfig()
  message.success('已启用所有日志')
}

const disableAllLogs = () => {
  const keys = Object.keys(batchStore.logConfig)
  keys.forEach(key => {
    batchStore.logConfig[key] = false
  })
  batchStore.saveLogConfig()
  message.success('已禁用所有日志')
}

// 启动调度器
const startScheduler = () => {
  const config = batchStore.schedulerConfig
  
  if (!config.enabled) return
  
  taskScheduler.start(config, async (tasks) => {
    // tasks参数：每日定时模式下会传递指定的任务列表，间隔模式下为null
    const tasksInfo = tasks ? ` [${tasks.length}个任务]` : ''
    console.log(`🤖 调度器触发批量任务${tasksInfo}`)
    
    // 如果指定了任务列表，直接使用这些任务
    if (tasks) {
      await batchStore.startBatchExecution(null, tasks)
    } else {
      // 否则使用当前选中的模板
      await batchStore.startBatchExecution()
    }
    
    // 更新最后执行时间
    batchStore.saveSchedulerConfig({
      lastExecutionTime: Date.now()
    })
  })
}

// 停止调度器
const stopScheduler = () => {
  taskScheduler.stop()
}

// 组件挂载时
onMounted(() => {
  // 如果启用了定时任务，显示提醒并启动调度器
  if (batchStore.schedulerConfig.enabled) {
    const config = batchStore.schedulerConfig
    const scheduleDesc = config.type === 'interval' 
      ? `每 ${formatInterval(config.interval)}`
      : `每天 ${config.dailyTimes.join(', ')}`
    
    // 显示通知提醒用户定时任务正在运行
    message.warning(
      `⏰ 定时任务已自动启动（${scheduleDesc}）`,
      {
        duration: 5000,
        closable: true
      }
    )
    
    startScheduler()
  }
})

// 组件卸载时
onUnmounted(() => {
  stopScheduler()
})
</script>

<style scoped lang="scss">
.batch-task-panel {
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(10px);
  margin-bottom: 16px;

  .panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;

    h2 {
      display: flex;
      align-items: center;
      gap: 6px;
      font-size: 18px;
      font-weight: 600;
      margin: 0;
      color: #333;

      .n-icon {
        font-size: 20px;
        color: #667eea;
      }
    }
  }

  // 定时任务状态标签
  .scheduler-status-tag {
    cursor: pointer;
    transition: all 0.3s ease;
    
    &:hover {
      transform: translateY(-1px);
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }
  }

  // 定时任务提示框
  .scheduler-tooltip {
    p {
      margin: 4px 0;
      line-height: 1.6;
      
      &:first-child {
        margin-top: 0;
      }
      
      &:last-child {
        margin-bottom: 0;
      }
      
      strong {
        color: #667eea;
      }
    }
  }

  // 定时任务快速控制栏
  .scheduler-quick-control {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 12px;
    margin-bottom: 12px;
    background: linear-gradient(135deg, rgba(255, 193, 7, 0.1) 0%, rgba(255, 152, 0, 0.1) 100%);
    border: 1px solid rgba(255, 193, 7, 0.3);
    border-radius: 8px;
    animation: pulse-border 2s ease-in-out infinite;
    
    .control-info {
      display: flex;
      align-items: center;
      gap: 12px;
      flex: 1;
      
      .n-icon {
        color: #ff9800;
        flex-shrink: 0;
      }
      
      .info-text {
        color: #333;
        font-size: 14px;
        
        strong {
          color: #ff6f00;
          margin-right: 8px;
        }
        
        span {
          color: #666;
        }
      }
    }
  }

  @keyframes pulse-border {
    0%, 100% {
      border-color: rgba(255, 193, 7, 0.3);
      box-shadow: 0 0 0 0 rgba(255, 193, 7, 0);
    }
    50% {
      border-color: rgba(255, 193, 7, 0.6);
      box-shadow: 0 0 0 4px rgba(255, 193, 7, 0.1);
    }
  }

  .template-section {
    .template-selector,
    // 🆕 v3.13.0 连接池模式切换
    .connection-pool-toggle {
      padding: 12px;
      background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
      border: 1px solid #bae6fd;
      border-radius: 8px;
      margin-bottom: 4px;
      
      .toggle-label {
        span {
          font-size: 15px;
        }
      }
    }
    
    // 🆕 v3.14.1 性能模式开关
    .performance-mode-toggle {
      padding: 12px;
      background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
      border: 1px solid #fde68a;
      border-radius: 8px;
      margin-bottom: 4px;
      
      .toggle-label {
        span {
          font-size: 15px;
        }
      }
    }
    
    // 🆕 v3.13.0 连接池大小选择器
    .pool-size-selector {
      padding: 12px;
      background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
      border: 1px solid #bbf7d0;
      border-radius: 8px;
      
      .pool-size-hint {
        margin-top: 12px;
      }
      
      .selector-header {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 12px;
        
        label {
          margin: 0;
          font-weight: 500;
          color: #15803d;
          white-space: nowrap;
        }
        
        .number-input {
          flex-shrink: 0;
          width: 140px !important;
          
          :deep(.n-input-number-input) {
            text-align: center;
          }
        }
      }
    }
    
    // 🆕 v3.13.2 最大并发请求数选择器
    .concurrent-requests-selector {
      padding: 12px;
      background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
      border: 1px solid #fcd34d;
      border-radius: 8px;
      
      .concurrent-requests-hint {
        margin-top: 12px;
      }
      
      .selector-header {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 12px;
        
        label {
          margin: 0;
          font-weight: 500;
          color: #92400e;
          white-space: nowrap;
        }
        
        .number-input {
          flex-shrink: 0;
          width: 140px !important;
          
          :deep(.n-input-number-input) {
            text-align: center;
          }
        }
      }
    }
    
    // 🆕 连接间隔选择器
    .connection-interval-selector {
      padding: 12px;
      background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);
      border: 1px solid #a5b4fc;
      border-radius: 8px;
      
      .connection-interval-hint {
        margin-top: 12px;
      }
      
      .selector-header {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 12px;
        
        label {
          margin: 0;
          font-weight: 500;
          color: #3730a3;
          white-space: nowrap;
        }
        
        .number-input {
          flex-shrink: 0;
          width: 140px !important;
          
          :deep(.n-input-number-input) {
            text-align: center;
          }
        }
      }
    }
    
    .concurrency-selector {
      .concurrency-hint {
        margin-top: 8px;
      }
      
      .selector-header {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 8px;
        
        label {
          margin: 0;
          font-weight: 500;
          color: #666;
          white-space: nowrap;
          font-size: 14px;
        }
        
        .number-input {
          flex-shrink: 0;
          width: 140px !important;
          
          :deep(.n-input-number-input) {
            text-align: center;
            font-size: 14px;
            font-weight: 600;
            cursor: text;
          }
          
          :deep(.n-input__input-el) {
            cursor: text !important;
          }
        }
      }
      
      :deep(.n-slider) {
        margin-top: 0;
        margin-bottom: 4px;
        
        .n-slider-rail {
          height: 4px;
        }
        
        .n-slider-handle {
          width: 14px;
          height: 14px;
        }
        
        .n-slider-marks {
          font-size: 11px;
        }
      }
    }
    
    .tower-count-selector {
      padding: 10px 12px;
      background: linear-gradient(135deg, #fef3f3 0%, #ffe5e5 100%);
      border: 1px solid #ffc9c9;
      border-radius: 8px;
      
      .selector-header {
        display: flex;
        align-items: center;
        gap: 8px;
        margin: 0;
        
        label {
          margin: 0;
          font-weight: 500;
          color: #c92a2a;
          white-space: nowrap;
          font-size: 14px;
        }
        
        .number-input {
          flex-shrink: 0;
          width: 110px !important;
          
          :deep(.n-input-number) {
            background: white;
          }
          
          :deep(.n-input-number-input) {
            text-align: center;
            font-size: 14px;
            font-weight: 600;
            cursor: text;
            padding-right: 28px;
          }
          
          :deep(.n-input__input-el) {
            cursor: text !important;
          }
          
          :deep(.n-input__suffix) {
            padding-right: 4px;
          }
        }
      }
    }

    // 自动重试配置
    .auto-retry-config {
      background: rgba(16, 185, 129, 0.05);
      border: 1px solid rgba(16, 185, 129, 0.2);
      border-radius: 8px;
      padding: 12px;
      
      .config-header {
        margin-bottom: 12px;
        
        .config-title {
          font-weight: 500;
          font-size: 14px;
          color: #333;
        }
      }
      
      .config-details {
        margin-top: 12px;
        padding-top: 12px;
        border-top: 1px solid rgba(16, 185, 129, 0.1);
        
        .config-item {
          display: flex;
          align-items: center;
          gap: 12px;
          
          .label {
            font-size: 14px;
            color: #666;
            min-width: 100px;
          }
        }
      }
    }

    .tasks-preview {
      background: rgba(102, 126, 234, 0.05);
      border-radius: 8px;
      padding: 12px;

      .preview-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 12px;
        font-weight: 500;
        color: #666;
      }

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

        .clickable-tag {
          transition: all 0.3s ease;
          position: relative;
          
          &:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
          }
          
          &:active {
            transform: translateY(0);
          }
        }
      }
    }

    // 一键补差子任务详情弹窗样式
    .daily-fix-detail {
      .task-item {
        display: flex;
        align-items: center;
        
        .task-name {
          font-size: 14px;
          color: #333;
        }
      }

      .task-summary {
        padding: 12px;
        background: rgba(102, 126, 234, 0.05);
        border-radius: 8px;
      }
    }

    .control-buttons {
      margin-top: 8px;
    }

    .execution-progress {
      background: rgba(102, 126, 234, 0.05);
      border-radius: 8px;
      padding: 12px;

      .progress-header {
        display: flex;
        justify-content: space-between;
        margin-bottom: 8px;
        font-weight: 500;
        color: #666;
      }
    }

    .stats-panel {
      background: rgba(102, 126, 234, 0.05);
      border-radius: 8px;
      padding: 12px;

      :deep(.n-statistic) {
        &.success .n-statistic-value__content {
          color: #18a058;
        }

        &.failed .n-statistic-value__content {
          color: #d03050;
        }

        &.skipped .n-statistic-value__content {
          color: #f0a020;
        }
        
        &.retry-round .n-statistic-value__content {
          color: #ff9800;
          font-weight: 600;
        }
      }
    }
    
    // 🆕 失败原因统计面板
    .failure-reasons-panel {
      margin-top: 12px;
      
      .failure-reasons-list {
        display: flex;
        flex-direction: column;
        gap: 8px;
      }
      
      .failure-reason-item {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 8px 12px;
        background: rgba(208, 48, 80, 0.05);
        border-radius: 6px;
        border-left: 3px solid #d03050;
        transition: all 0.3s ease;
        
        &:hover {
          background: rgba(208, 48, 80, 0.1);
          transform: translateX(2px);
        }
        
        .reason-text {
          flex: 1;
          font-size: 13px;
          color: #333;
          font-weight: 500;
        }
      }
      
      :deep(.n-card__header) {
        padding: 12px 16px;
        font-weight: 600;
        font-size: 14px;
      }
      
      :deep(.n-card__content) {
        padding: 12px 16px;
      }
    }
  }
}

/* 深色主题适配 */
html.dark .batch-task-panel,
html[data-theme="dark"] .batch-task-panel {
  background: rgba(30, 30, 30, 0.95);

  .panel-header h2 {
    color: #ffffff;
  }

  .template-selector label,
  .concurrency-selector .selector-header label,
  .tower-count-selector .selector-header label,
  .preview-header,
  .progress-header {
    color: #cccccc;
  }

  .tasks-preview,
  .execution-progress,
  .stats-panel {
    background: rgba(255, 255, 255, 0.05);
  }
  
  // 爬塔次数和发车刷新次数
  .tower-count-selector {
    background: linear-gradient(135deg, rgba(255, 99, 99, 0.15) 0%, rgba(255, 150, 150, 0.15) 100%);
    border-color: rgba(255, 150, 150, 0.3);
    
    .selector-header {
      label {
        color: #ff9999;
      }
    }
  }
  
  // 🆕 深色主题下的失败原因统计
  .failure-reasons-panel {
    .failure-reason-item {
      background: rgba(208, 48, 80, 0.15);
      border-left-color: #e57373;
      
      &:hover {
        background: rgba(208, 48, 80, 0.25);
      }
      
      .reason-text {
        color: #e0e0e0;
      }
    }
  }

  // 深色主题下的定时任务控制栏
  .scheduler-quick-control {
    background: linear-gradient(135deg, rgba(255, 193, 7, 0.15) 0%, rgba(255, 152, 0, 0.15) 100%);
    border-color: rgba(255, 193, 7, 0.4);
    
    .control-info {
      .info-text {
        color: #e0e0e0;
        
        strong {
          color: #ffb74d;
        }
        
        span {
          color: #b0b0b0;
        }
      }
    }
  }

  // 深色主题下的提示框
  .scheduler-tooltip {
    p {
      color: #e0e0e0;
      
      strong {
        color: #8ea3f5;
      }
    }
  }
  
  // 🆕 日志控制面板
  .log-control-panel {
    margin-bottom: 16px;
    padding: 12px;
    background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
    border: 1px solid #f59e0b;
    border-radius: 8px;
    
    .log-control-header {
      display: flex;
      align-items: center;
      gap: 8px;
      margin-bottom: 16px;
      font-weight: 600;
      color: #92400e;
      
      .n-icon {
        color: #f59e0b;
      }
    }
    
    .log-control-body {
      display: flex;
      flex-direction: column;
      gap: 16px;
      
      .log-section {
        .section-title {
          font-size: 13px;
          font-weight: 600;
          color: #78350f;
          margin-bottom: 10px;
          padding-bottom: 6px;
          border-bottom: 1px solid rgba(245, 158, 11, 0.3);
        }
        
        .log-switches {
          .log-switch-item {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 4px 12px;
            background: rgba(255, 255, 255, 0.6);
            border-radius: 6px;
            
            span {
              font-size: 13px;
              color: #92400e;
              white-space: nowrap;
            }
          }
        }
      }
    }
  }
}

// 黑市购买详情样式
.blackmarket-detail {
  .purchase-item {
    display: flex;
    align-items: center;
    gap: 12px;
    
    .item-name {
      font-weight: 500;
      min-width: 80px;
    }
    
    .item-price {
      margin-left: auto;
      font-size: 12px;
      color: #999;
    }
  }
}

// 🔥 旋转动画（用于停止loading）
@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>

