<template>
  <div class="report-log-viewer">
    <div class="page-header">
      <div class="header-title">
        <i class="fas fa-file-alt"></i>
        <h2>分析报告与执行日志</h2>
      </div>
      <div class="header-actions">
        <el-button type="primary" size="large" @click="exportSelectedReport">
          <i class="fas fa-file-export"></i> 导出选中报告
        </el-button>
      </div>
    </div>

    <div class="dashboard-content">
      <!-- 左右分割布局 -->
      <div class="split-layout">
        <!-- 左侧报告列表 -->
        <div class="list-section card-panel">
          <div class="section-header">
            <h3>日志列表</h3>
            <el-input v-model="searchQuery" placeholder="搜索报告ID/关键字" size="small" style="width: 150px">
               <template #prefix><i class="fas fa-search"></i></template>
            </el-input>
          </div>
          
          <ul class="report-list">
            <li v-for="log in filteredLogs" :key="log.id || log.reportId" 
                class="report-item" 
                :class="{ active: currentReport?.id === log.id || (currentReport?.reportId && currentReport?.reportId === log.reportId) }"
                @click="selectReport(log)">
              <div class="item-icon" :class="log.status">
                 <i :class="(log.status === 'success' || !log.status) ? 'fas fa-check-circle' : 'fas fa-exclamation-circle'"></i>
              </div>
              <div class="item-content">
                <div class="item-title">{{ log.operation || '系统操作' }}</div>
                <div class="item-meta">
                  <span class="meta-id">{{ log.operation_category || log.log_type || '系统日志' }}</span>
                  <span class="meta-time">{{ formatTime(log.timestamp || log.createdAt || log.created_at) }}</span>
                </div>
              </div>
            </li>
          </ul>
        </div>

        <!-- 右侧报告详情 -->
        <div class="detail-section card-panel" v-if="currentReport">
          <div class="detail-header overview-custom-header">
            <div class="header-left">
               <el-tag effect="dark" :type="currentReport.status === 'success' ? 'success' : (currentReport.status === 'pending' ? 'warning' : 'danger')" size="large" class="status-tag">
                  <i :class="currentReport.status === 'success' ? 'fas fa-check-circle' : (currentReport.status === 'pending' ? 'fas fa-spinner fa-spin' : 'fas fa-times-circle')"></i>
                  {{ currentReport.status === 'success' ? '执行成功' : (currentReport.status === 'pending' ? '处理中' : '执行异常') }}
               </el-tag>
               <span class="report-id-text" :title="currentReport.id || currentReport.reportId"><i class="fas fa-fingerprint"></i> ID: {{ currentReport.id || currentReport.reportId || 'LOG-000' }}</span>
            </div>
            <div class="report-time" v-if="currentReport.duration">
                <i class="fas fa-clock"></i> 耗时: {{ currentReport.duration }}ms
            </div>
          </div>

          <el-tabs v-model="activeTab" class="report-tabs">
            <el-tab-pane label="执行概览" name="overview">
              <div class="detail-body styled-body">
                
                <div class="overview-title-card">
                   <div class="overview-title-icon" :class="'icon-' + getCategoryColor(currentReport.operation_category)">
                      <i :class="getCategoryIconClass(currentReport.operation_category)"></i>
                   </div>
                   <h2 class="overview-title-text">{{ currentReport.operation || '系统操作' }}</h2>
                </div>

                <div class="overview-info-card">
                  <el-descriptions class="custom-descriptions" :column="3" border>
                    <el-descriptions-item>
                      <template #label><div class="desc-label"><i class="fas fa-sitemap"></i> 所属分类</div></template>
                      <el-tag size="small" type="info" effect="plain">{{ currentReport.operation_category || currentReport.log_type || '系统日志' }}</el-tag>
                    </el-descriptions-item>
                    <el-descriptions-item>
                      <template #label><div class="desc-label"><i class="far fa-clock"></i> 执行时间</div></template>
                      <span class="mono">{{ formatTime(currentReport.timestamp || currentReport.createdAt || currentReport.created_at) }}</span>
                    </el-descriptions-item>
                    <el-descriptions-item>
                      <template #label><div class="desc-label"><i class="fas fa-desktop"></i> 操作节点</div></template>
                      <span class="mono">{{ currentReport.client_ip || currentReport.ip_address || '本地系统/客户端' }}</span>
                    </el-descriptions-item>
                    <el-descriptions-item v-if="currentReport.user_id || currentReport.client_id">
                      <template #label><div class="desc-label"><i class="fas fa-user-circle"></i> 操作人员</div></template>
                      {{ currentReport.user_id || currentReport.client_id }}
                    </el-descriptions-item>
                    <el-descriptions-item v-if="currentReport.level">
                      <template #label><div class="desc-label"><i class="fas fa-shield-alt"></i> 安全级别</div></template>
                      <el-tag size="small" :type="currentReport.level === 'error' ? 'danger' : 'success'">{{ currentReport.level }}</el-tag>
                    </el-descriptions-item>
                    <el-descriptions-item v-if="currentReport.action_type">
                      <template #label><div class="desc-label"><i class="fas fa-bolt"></i> 动作分发</div></template>
                      <span class="mono">{{ currentReport.action_type }}</span>
                    </el-descriptions-item>
                  </el-descriptions>
                </div>

                <!-- 详细信息区 -->
                <div class="detail-group mt-4" v-if="currentReport.details || currentReport.errorInfo || currentReport.error_message">
                   <h4 class="group-title"><i class="fas fa-align-left text-primary"></i> 日志详细信息 / 异常信息</h4>
                   <el-alert
                      :title="currentReport.details || currentReport.errorInfo || currentReport.error_message"
                      :type="currentReport.status === 'success' ? 'info' : 'error'"
                      :closable="false"
                      show-icon
                      class="custom-alert-box"
                   />
                </div>
                
                <!-- 业务数据 -->
                <div class="detail-group mt-4" v-if="hasExtraData(currentReport)">
                  <h4 class="group-title"><i class="fas fa-laptop-code text-warning"></i> 业务执行对象负荷 (Payload)</h4>
                  <div class="json-viewer-box">
                    <pre><code>{{ formatExtraData(currentReport) }}</code></pre>
                  </div>
                </div>

              </div>
            </el-tab-pane>

            <el-tab-pane label="模型对比" name="comparison">
              <div class="comparison-view">
                <div class="comparison-mode-switch">
                  <el-radio-group v-model="comparisonMode" size="small">
                    <el-radio-button label="live" :disabled="cadStore.currentCAD?.id === 'creo'" :title="cadStore.currentCAD?.id === 'creo' ? 'Creo模式下不支持实时穿透对比' : ''">实时穿透 (当前模型流程)</el-radio-button>
                    <el-radio-button label="manual">离线文件 (当前模型 vs 离线文件)</el-radio-button>
                  </el-radio-group>
                  <div v-if="cadStore.currentCAD?.id === 'creo'" style="margin-top: 10px; font-size: 13px; color: #e6a23c;">
                    <i class="fas fa-info-circle"></i> 此对比为离线模式对比，Creo 支持将当前模型参数提取，并与导出的轻量化离线文件（.prt）进行参数验证与记录。
                  </div>
                </div>

                <!-- 实时模式内容 -->
                <div v-if="comparisonMode === 'live'" class="live-comparison">
                  <div class="live-flow-container">
                    <!-- 步骤 1: 捕获基准 -->
                    <div class="flow-step" :class="{ 'step-active': cadStore.liveComparisonState.step === 1, 'step-done': cadStore.liveComparisonState.step > 1 }">
                      <div class="step-header">
                        <div class="step-num">1</div>
                        <h3>记录当前模型基准状态</h3>
                      </div>
                      <div class="step-content">
                        <el-button v-if="cadStore.liveComparisonState.step === 1" type="primary" :loading="isCapturingBaseline" @click="captureBaseline" class="live-btn">
                          <i class="fas fa-crosshairs"></i> 一键读取 CAD 当前基准参数
                        </el-button>
                        <div v-else class="captured-data card-panel">
                          <h4><i class="fas fa-cube text-info"></i> 基准原始模型</h4>
                          <ul class="data-list">
                            <li><span class="lbl">模型文件:</span> <span class="val">{{ cadStore.liveComparisonState.baselineData?.name }}</span></li>
                            <li><span class="lbl">内存占用:</span> <span class="val">{{ cadStore.liveComparisonState.baselineData?.mem }}</span></li>
                            <li><span class="lbl">面片数量:</span> <span class="val">{{ cadStore.liveComparisonState.baselineData?.poly }}</span></li>
                            <li><span class="lbl">特征数量:</span> <span class="val">{{ cadStore.liveComparisonState.baselineData?.features }}</span></li>
                          </ul>
                        </div>
                      </div>
                    </div>

                    <!-- 步骤 2: 捕获当前状态并比对 -->
                    <div class="flow-step" :class="{ 'step-active': cadStore.liveComparisonState.step === 2, 'step-done': cadStore.liveComparisonState.step > 2 }">
                      <div class="step-header">
                        <div class="step-num">2</div>
                        <h3>捕获当前状态并生成对比</h3>
                      </div>
                      <div class="step-content">
                        <div v-if="cadStore.liveComparisonState.step === 2" class="wait-msg">
                          <i class="fas fa-info-circle"></i> 记录基准后，您可以前往其他模块或在 CAD 中自由执行各种操作。操作完成后返回此处点击下方按钮：
                        </div>
                        <el-button v-if="cadStore.liveComparisonState.step === 2" type="success" :loading="isCapturingResult" @click="captureResult" class="live-btn" plain>
                          <i class="fas fa-sync-alt"></i> 读取当前最新状态并对比
                        </el-button>

                        <transition name="el-zoom-in-top">
                          <div v-if="cadStore.liveComparisonState.step === 3" class="comparison-results mt-4">
                            <div class="comparison-columns mt-4">
                              <div class="comp-col source-col">
                                <h4><i class="fas fa-cube"></i> 基准状态</h4>
                                <ul class="prop-list">
                                  <li><span class="prop-label">内存占用</span> <span class="prop-value">{{ cadStore.liveComparisonState.baselineData?.mem }}</span></li>
                                  <li><span class="prop-label">面片数量</span> <span class="prop-value">{{ cadStore.liveComparisonState.baselineData?.poly }}</span></li>
                                  <li><span class="prop-label">特征总数</span> <span class="prop-value">{{ cadStore.liveComparisonState.baselineData?.features }}</span></li>
                                </ul>
                              </div>
                              <div class="vs-divider">VS</div>
                              <div class="comp-col target-col">
                                <h4><i class="fas fa-leaf text-success"></i> 最新状态</h4>
                                <ul class="prop-list">
                                  <li><span class="prop-label">内存占用</span> <span class="prop-value text-success">{{ cadStore.liveComparisonState.resultData?.mem }}</span></li>
                                  <li><span class="prop-label">面片数量</span> <span class="prop-value text-success">{{ cadStore.liveComparisonState.resultData?.poly }}</span></li>
                                  <li><span class="prop-label">特征总数</span> <span class="prop-value text-success">{{ cadStore.liveComparisonState.resultData?.features }}</span></li>
                                </ul>
                              </div>
                            </div>

                            <div class="mt-4 flex-center">
                              <el-button plain @click="resetLiveFlow">开启新一轮对比</el-button>
                            </div>
                          </div>
                        </transition>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- 手动/混合模式内容 -->
                <!-- 手动/离线文件对比模式内容 -->
                <div v-else class="manual-comparison">
                  <div class="live-flow-container">
                    <!-- 步骤 1: 捕获基准 -->
                    <div class="flow-step" :class="{ 'step-active': cadStore.manualComparisonState.step === 1, 'step-done': cadStore.manualComparisonState.step > 1 }">
                      <div class="step-header">
                        <div class="step-num">1</div>
                        <h3>记录当前模型基准状态</h3>
                      </div>
                      <div class="step-content">
                        <el-button v-if="cadStore.manualComparisonState.step === 1" type="primary" :loading="isCapturingManualBaseline" @click="captureManualBaseline" class="live-btn">
                          <i class="fas fa-crosshairs"></i> 读取当前 CAD 模型参数作为基准
                        </el-button>
                        <div v-else class="captured-data card-panel">
                          <h4><i class="fas fa-cube text-info"></i> 基准原始模型</h4>
                          <ul class="data-list">
                            <li><span class="lbl">模型文件:</span> <span class="val" :title="cadStore.manualComparisonState.baselineData?.name">{{ cadStore.manualComparisonState.baselineData?.name }}</span></li>
                            <li><span class="lbl">文件大小/内存:</span> <span class="val">{{ cadStore.manualComparisonState.baselineData?.mem }}</span></li>
                            <li><span class="lbl">总体复杂度(特征数):</span> <span class="val text-primary" style="font-weight: bold;">{{ cadStore.manualComparisonState.baselineData?.features }}</span></li>
                            <!-- 具体组成结构拆解 -->
                            <template v-if="cadStore.manualComparisonState.baselineData?.details">
                               <li v-for="(val, key) in cadStore.manualComparisonState.baselineData.details" :key="key" style="padding-left: 20px;">
                                 <span class="lbl" style="font-size: 12px; color: #888;">↳ {{ key }}:</span> 
                                 <span class="val" style="font-size: 12px; color: #888;">{{ val }} 个</span>
                               </li>
                            </template>
                          </ul>
                        </div>
                      </div>
                    </div>

                    <!-- 步骤 2: 填写离线文件路径并比对 -->
                    <div class="flow-step" :class="{ 'step-active': cadStore.manualComparisonState.step === 2, 'step-done': cadStore.manualComparisonState.step > 2 }">
                      <div class="step-header">
                        <div class="step-num">2</div>
                        <h3>自动打开离线文件并比对</h3>
                      </div>
                      <div class="step-content">
                        <div v-if="cadStore.manualComparisonState.step === 2" class="wait-msg">
                          <i class="fas fa-info-circle"></i> 请填写需要对比的离线文件绝对路径 (支持 .rvt, .rfa, .prt, .asm 等格式)：
                        </div>
                        <div v-if="cadStore.manualComparisonState.step === 2" style="display: flex; gap: 10px; margin-top: 15px;">
                          <el-input v-model="cadStore.manualComparisonState.targetFilePath" placeholder="例如: D:\models\example.prt" style="flex: 1;" clearable />
                          <el-button type="success" :loading="isCapturingManualResult" @click="captureManualResult" plain>
                            <i class="fas fa-folder-open"></i> 自动打开并读取参数
                          </el-button>
                        </div>

                        <transition name="el-zoom-in-top">
                          <div v-if="cadStore.manualComparisonState.step === 3" class="comparison-results mt-4">
                            <div class="comparison-columns mt-4">
                              <div class="comp-col source-col">
                                <h4><i class="fas fa-cube"></i> 基准状态</h4>
                                <ul class="prop-list">
                                  <li><span class="prop-label">文件大小/内存</span> <span class="prop-value">{{ cadStore.manualComparisonState.baselineData?.mem }}</span></li>
                                  <li><span class="prop-label">特征及组件总数</span> <span class="prop-value">{{ cadStore.manualComparisonState.baselineData?.features }}</span></li>
                                  <template v-if="cadStore.manualComparisonState.baselineData?.details">
                                    <li v-for="(val, key) in cadStore.manualComparisonState.baselineData.details" :key="key">
                                      <span class="prop-label text-muted" style="padding-left: 10px; font-size: 12px;">↳ {{ key }}</span> 
                                      <span class="prop-value text-muted" style="font-size: 12px;">{{ val }}</span>
                                    </li>
                                  </template>
                                </ul>
                              </div>
                              <div class="vs-divider">VS</div>
                              <div class="comp-col target-col">
                                <h4><i class="fas fa-leaf text-success"></i> 离线文件读取状态</h4>
                                <ul class="prop-list">
                                  <li><span class="prop-label">文件名称</span> <span class="prop-value text-success" :title="cadStore.manualComparisonState.resultData?.name">{{ cadStore.manualComparisonState.resultData?.name }}</span></li>
                                  <li><span class="prop-label">文件大小/内存</span> <span class="prop-value text-success">{{ cadStore.manualComparisonState.resultData?.mem }}</span></li>
                                  <li><span class="prop-label">特征及组件总数</span> <span class="prop-value text-success" style="font-weight: bold;">{{ cadStore.manualComparisonState.resultData?.features }}</span></li>
                                  <template v-if="cadStore.manualComparisonState.resultData?.details">
                                    <li v-for="(val, key) in cadStore.manualComparisonState.resultData.details" :key="key">
                                      <span class="prop-label text-muted" style="padding-left: 10px; font-size: 12px;">↳ {{ key }}</span> 
                                      <span class="prop-value text-muted" style="font-size: 12px;">{{ val }}</span>
                                    </li>
                                  </template>
                                </ul>
                              </div>
                            </div>

                            <div class="mt-4 flex-center">
                              <el-button plain @click="resetManualFlow">开启新一轮比对</el-button>
                            </div>
                          </div>
                        </transition>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
        
        <div class="detail-section empty-state card-panel" v-else>
           <i class="fas fa-inbox empty-icon"></i>
           <p>请选择左侧报告以查看详细信息</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { useCADStore } from '@/stores/cad'
import creoApi from '@/services/creoApi'
import revitApi from '@/services/revitApi'
import pdmsApi from '@/services/pdmsApi'
import websocketService from '@/services/websocketService'

const searchQuery = ref('')
const activeTab = ref('overview')
const comparisonMode = ref('live')

const isCapturingBaseline = ref(false)
const isCapturingResult = ref(false)
const isCapturingManualBaseline = ref(false)
const isCapturingManualResult = ref(false)

const cadStore = useCADStore()

watch(() => cadStore.currentCAD, (newCAD) => {
  if (newCAD && newCAD.id === 'creo') {
    comparisonMode.value = 'manual'
  }
}, { immediate: true })

const captureBaseline = async () => {
  const connectedCAD = cadStore.currentCAD
  if (!connectedCAD) {
    ElMessage.warning('请先连接并打开对应的 CAD 插件和模型')
    return
  }

  isCapturingBaseline.value = true
  try {
    let result;
    let stats = {
      mem: 'API暂未支持',
      poly: 'API暂未支持',
      features: 'API暂未支持'
    }

    if (connectedCAD.id === 'creo') {
      result = await creoApi.getCurrentModel()
      // 如果有可用的层级统计接口，我们用它来获取特征/部件总数
      try {
        const statResult = await creoApi.getHierarchyStatistics()
        if (statResult.success && statResult.data?.data?.statistics) {
           let totalFeatures = 0
           Object.values(statResult.data.data.statistics).forEach(v => totalFeatures += v)
           if(totalFeatures > 0) stats.features = `${totalFeatures} +`
        }
      } catch(e) { /* 忽略层级统计失败 */ }

    } else if (connectedCAD.id === 'revit') {
      result = await revitApi.getCurrentModel()
    } else if (connectedCAD.id === 'pdms') {
      result = await pdmsApi.getCurrentModel()
    }

    if (result && result.success) {
      const respData = result.data?.data || {}
      let fileName = '当前活动模型'
      
      if (connectedCAD.id === 'creo' && respData.fileName) {
        fileName = respData.fileName
      } else if (connectedCAD.id === 'revit' && respData.project?.name) {
        fileName = respData.project.name
      } else if (connectedCAD.id === 'pdms' && respData.ProjectInfo?.ProjectName) {
        fileName = respData.ProjectInfo.ProjectName
      }

      // 提取现有接口可能返回的真实数据大小、面片等（做兼容读取）
      if (respData.fileSize) stats.mem = respData.fileSize
      if (respData.memoryUsage) stats.mem = respData.memoryUsage
      if (respData.polygonCount) stats.poly = respData.polygonCount
      if (respData.featureCount) stats.features = respData.featureCount
      if (respData.componentCount) stats.features = respData.componentCount

      // Revit 新的数据结构专门适配 (data.data.project.xxx)
      if (connectedCAD.id === 'revit' && respData.project) {
        if (respData.project.fileSizeDisplay) stats.mem = respData.project.fileSizeDisplay
        if (respData.project.polygonCount !== undefined) stats.poly = respData.project.polygonCount
        if (respData.project.featureCount !== undefined) stats.features = respData.project.featureCount
      }

      cadStore.liveComparisonState.baselineData = {
        name: fileName,
        mem: stats.mem,
        poly: stats.poly,
        features: stats.features
      }
      cadStore.liveComparisonState.step = 2
      ElMessage.success('基准状态参数读取成功')
    } else {
      throw new Error(result?.error || '未能获取到开启的模型信息')
    }
  } catch (error) {
    ElMessage.error(`获取基准数据失败: ${error.message}`)
  } finally {
    isCapturingBaseline.value = false
  }
}

const captureResult = async () => {
  const connectedCAD = cadStore.currentCAD
  if (!connectedCAD) {
    ElMessage.warning('请先连接对应的 CAD 插件')
    return
  }

  isCapturingResult.value = true
  try {
    let result;
    let stats = {
      mem: 'API暂未支持',
      poly: 'API暂未支持',
      features: 'API暂未支持'
    }

    if (connectedCAD.id === 'creo') {
      result = await creoApi.getCurrentModel()
      try {
        const statResult = await creoApi.getHierarchyStatistics()
        if (statResult.success && statResult.data?.data?.statistics) {
           let totalFeatures = 0
           Object.values(statResult.data.data.statistics).forEach(v => totalFeatures += v)
           if(totalFeatures > 0) stats.features = `${totalFeatures} +`
        }
      } catch(e) { }
    } else if (connectedCAD.id === 'revit') {
      result = await revitApi.getCurrentModel()
    } else if (connectedCAD.id === 'pdms') {
      result = await pdmsApi.getCurrentModel()
    }

    if (result && result.success) {
      const respData = result.data?.data || {}
      
      // 提取现有接口可能返回的真实数据大小、面片等（做兼容读取）
      if (respData.fileSize) stats.mem = respData.fileSize
      if (respData.memoryUsage) stats.mem = respData.memoryUsage
      if (respData.polygonCount) stats.poly = respData.polygonCount
      if (respData.featureCount) stats.features = respData.featureCount
      if (respData.componentCount) stats.features = respData.componentCount

      // Revit 新的数据结构专门适配 (data.data.project.xxx)
      if (connectedCAD.id === 'revit' && respData.project) {
        if (respData.project.fileSizeDisplay) stats.mem = respData.project.fileSizeDisplay
        if (respData.project.polygonCount !== undefined) stats.poly = respData.project.polygonCount
        if (respData.project.featureCount !== undefined) stats.features = respData.project.featureCount
      }

      cadStore.liveComparisonState.resultData = {
        mem: stats.mem,
        poly: stats.poly,
        features: stats.features
      }
      cadStore.liveComparisonState.step = 3
      ElMessage.success('新状态已成功捕获并生成对比报告')
    } else {
      throw new Error(result?.error || '未能获取到轻量化后模型信息')
    }
  } catch (error) {
    ElMessage.error(`获取轻量化结果失败: ${error.message}`)
  } finally {
    isCapturingResult.value = false
  }
}

const resetLiveFlow = () => {
  cadStore.resetLiveComparison()
}

const captureManualBaseline = async () => {
  const connectedCAD = cadStore.currentCAD
  if (!connectedCAD) {
    ElMessage.warning('请先连接并打开对应的 CAD 插件和模型')
    return
  }

  isCapturingManualBaseline.value = true
  try {
    let result;
    let stats = {
      mem: 'API暂未支持',
      poly: 'API暂未支持',
      features: 'API暂未支持'
    }

    if (connectedCAD.id === 'creo') {
      result = await creoApi.getCurrentModel()
      try {
        const statResult = await creoApi.getHierarchyStatistics()
        if (statResult.success && statResult.data?.data?.statistics) {
           let totalFeatures = 0
           const detailsObj = statResult.data.data.statistics
           Object.values(detailsObj).forEach(v => totalFeatures += v)
           if(totalFeatures > 0) {
             stats.features = `${totalFeatures}`
             stats.details = detailsObj
           }
        }
      } catch(e) { }
    } else if (connectedCAD.id === 'revit') {
      result = await revitApi.getCurrentModel()
    } else if (connectedCAD.id === 'pdms') {
      result = await pdmsApi.getCurrentModel()
    }

    if (result && result.success) {
      const respData = result.data?.data || {}
      let fileName = '当前活动模型'
      
      if (connectedCAD.id === 'creo' && respData.fileName) fileName = respData.fileName
      else if (connectedCAD.id === 'revit' && respData.project?.name) fileName = respData.project.name
      else if (connectedCAD.id === 'pdms' && respData.ProjectInfo?.ProjectName) fileName = respData.ProjectInfo.ProjectName

      if (respData.fileSize) stats.mem = respData.fileSize
      if (respData.memoryUsage) stats.mem = respData.memoryUsage
      if (respData.polygonCount) stats.poly = respData.polygonCount
      if (respData.featureCount) stats.features = respData.featureCount
      if (respData.componentCount) stats.features = respData.componentCount

      if (connectedCAD.id === 'revit' && respData.project) {
        if (respData.project.fileSizeDisplay) stats.mem = respData.project.fileSizeDisplay
        if (respData.project.polygonCount !== undefined) stats.poly = respData.project.polygonCount
        if (respData.project.featureCount !== undefined) stats.features = respData.project.featureCount
      }

      cadStore.manualComparisonState.baselineData = {
        name: fileName,
        mem: stats.mem,
        poly: stats.poly,
        features: stats.features,
        details: stats.details || null
      }
      cadStore.manualComparisonState.step = 2
      ElMessage.success('基准状态参数读取成功')
    } else {
      throw new Error(result?.error || '未能获取到开启的模型信息')
    }
  } catch (error) {
    ElMessage.error(`获取基准数据失败: ${error.message}`)
  } finally {
    isCapturingManualBaseline.value = false
  }
}

const captureManualResult = async () => {
  const filePath = cadStore.manualComparisonState.targetFilePath
  if (!filePath || filePath.trim() === '') {
    ElMessage.warning('请填写离线模型的绝对路径')
    return
  }

  const ext = filePath.split('.').pop().toLowerCase()
  let apiToUse = null
  let cadType = ''

  if (['rvt', 'rfa'].includes(ext)) {
    apiToUse = revitApi
    cadType = 'revit'
  } else if (['prt', 'asm'].includes(ext)) {
    apiToUse = creoApi
    cadType = 'creo'
  } else {
    ElMessage.warning(`暂不支持的离线文件后缀: .${ext}，目前自动打开支持 .rvt, .rfa, .prt, .asm`)
    return
  }

  isCapturingManualResult.value = true
  try {
    // 假设 apiToUse 是挂载在配置里的或者能通过某些方式访问
    // 调用打开指定的离线文件
    const openRes = await apiToUse.openModelFile(filePath)
    if (!openRes || !openRes.success) {
      throw new Error(openRes?.error || '打开离线模型文件失败')
    }

    let result = await apiToUse.getCurrentModel()
    let stats = { mem: 'API暂未支持', poly: 'API暂未支持', features: 'API暂未支持' }

    if (cadType === 'creo') {
      try {
        const statResult = await creoApi.getHierarchyStatistics()
        if (statResult.success && statResult.data?.data?.statistics) {
           let totalFeatures = 0
           const detailsObj = statResult.data.data.statistics
           Object.values(detailsObj).forEach(v => totalFeatures += v)
           if(totalFeatures > 0) {
             stats.features = `${totalFeatures}`
             stats.details = detailsObj
           }
        }
      } catch(e) { }
    }

    if (result && result.success) {
      const respData = result.data?.data || {}
      
      // 提取文件名
      let fileName = filePath.split('\\').pop().split('/').pop()

      if (respData.fileSize) stats.mem = respData.fileSize
      if (respData.memoryUsage) stats.mem = respData.memoryUsage
      if (respData.polygonCount) stats.poly = respData.polygonCount
      if (respData.featureCount) stats.features = respData.featureCount
      if (respData.componentCount) stats.features = respData.componentCount

      if (cadType === 'revit' && respData.project) {
        if (respData.project.fileSizeDisplay) stats.mem = respData.project.fileSizeDisplay
        if (respData.project.polygonCount !== undefined) stats.poly = respData.project.polygonCount
        if (respData.project.featureCount !== undefined) stats.features = respData.project.featureCount
      }

      cadStore.manualComparisonState.resultData = {
        name: fileName,
        mem: stats.mem,
        poly: stats.poly,
        features: stats.features,
        details: stats.details || null
      }
      cadStore.manualComparisonState.step = 3
      ElMessage.success('离线模型已成功打开并读取参数')
    } else {
      throw new Error(result?.error || '未能获取到离线模型信息')
    }
  } catch (error) {
    ElMessage.error(`获取离线模型数据失败: ${error.message}`)
  } finally {
    isCapturingManualResult.value = false
  }
}

const resetManualFlow = () => {
  cadStore.resetManualComparison()
}

// 模拟报告数据
const mockReports = [
  {
    reportId: 'REP-20260226-001',
    operation: '批量薄壳化分析',
    status: 'success',
    duration: 12.5,
    createdAt: '2026-02-26 10:15:30',
    summary: '薄壳化特征分析完成',
    resultMetrics: { modelCount: 1, featureCount: 45, processedCount: 12 },
    featureDetails: [
      { featureName: 'PRT_001_HOLE', featureType: '盲孔', recommendedAction: '安全删除', recommendedSteps: ['选中特征', '执行删除操作', '验证干涉'] },
      { featureName: 'FILLET_002', featureType: '倒角', recommendedAction: '建议保留', recommendedSteps: ['标记为特征', '跳过删除向导'] },
      { featureName: 'POCKET_003', featureType: '凹槽', recommendedAction: '用户确认', recommendedSteps: ['提示用户审查该凸台'] }
    ],
    comparisonData: {
      sourceFormat: 'ASM (Creo)',
      targetFormat: '几何优化 PRT',
      sizeReduction: '76.5%',
      polygonReduction: '45.2%',
      sourceProps: {
        '文件大小': '125.4 MB',
        '多边形体积': '1,245,600 面片',
        '特征/部件总数': '4,520 个',
        '装配体层级': '12 层级',
        '外包络体积': '15.42 m³'
      },
      targetProps: {
        '文件大小': '29.5 MB',
        '多边形体积': '682,100 面片',
        '特征/部件总数': '342 个 (不可见件全清除)',
        '装配体层级': '单层 (已重组成一个实体)',
        '外包络体积': '15.41 m³ (误差 <0.1%)'
      }
    },
    errorInfo: null
  },
  {
    reportId: 'REP-20260226-002',
    operation: '层级清理任务',
    status: 'failed',
    duration: 3.2,
    createdAt: '2026-02-26 09:12:05',
    summary: '内部API连接超时',
    resultMetrics: { modelCount: 1, featureCount: 0, processedCount: 0 },
    featureDetails: [],
    errorInfo: '[Error] ConnectTimeout: Unable to connect to CAD service on port 4501. Attempted 3 retries.'
  },
  {
    reportId: 'REP-20260225-003',
    operation: '模型几何复杂度',
    status: 'success',
    duration: 8.4,
    createdAt: '2026-02-25 16:40:00',
    summary: '几何复杂度计算完成',
    resultMetrics: { modelCount: 3, featureCount: 156, processedCount: 156 },
    featureDetails: [
      { featureName: 'ASSEMBLY_ROOT', featureType: '装配体', recommendedAction: '多面体降级', recommendedSteps: ['抽取包络', '简化三角面'] }
    ],
    errorInfo: null
  }
]

const logs = ref([...mockReports]) // 初始使用 mock, 等待 ws 同步
const currentReport = ref(logs.value[0])

// --- WebSocket 日志同步逻辑开始 --- //
let listeners = []

const initListeners = () => {
  const onLogUpdate = (logData) => {
    let newLogs = []
    if (Array.isArray(logData)) {
      newLogs = [...logData].sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
    } else if (logData.logs) {
      newLogs = [...logData.logs].sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
    }
    
    // 如果获取到了真实的后台日志，我们就直接覆盖 mock
    if (newLogs.length > 0) {
      logs.value = newLogs
      // 若当前没有选中日志，或者选中的日志在新的列表里找不到
      if (!currentReport.value || !logs.value.find(l => l.id === currentReport.value.id)) {
         currentReport.value = logs.value[0]
      }
    }
  }
  
  websocketService.on('onLogUpdate', onLogUpdate)
  listeners.push(['onLogUpdate', onLogUpdate])

  // 组件挂载时主动查询一次日志
  websocketService.queryLogs()
}

const removeListeners = () => {
  listeners.forEach(([event, callback]) => {
    websocketService.off(event, callback)
  })
  listeners = []
}

onMounted(() => {
  initListeners()
})

onUnmounted(() => {
  removeListeners()
})

// --- WebSocket 日志同步逻辑结束 --- //

const filteredLogs = computed(() => {
  if (!searchQuery.value) return logs.value
  const q = searchQuery.value.toLowerCase()
  return logs.value.filter(log => 
      (log.operation && log.operation.toLowerCase().includes(q)) || 
      (log.operation_category && log.operation_category.toLowerCase().includes(q))
  )
})

const selectReport = (log) => {
  currentReport.value = log
}

const formatTime = (timestamp) => {
  if (!timestamp) return ''
  try {
    const date = new Date(timestamp)
    return date.toLocaleString('zh-CN', {
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    })
  } catch {
    return timestamp
  }
}

const getActionClass = (action) => {
  if (!action) return ''
  if (action.includes('删除')) return 'text-success'
  if (action.includes('确认')) return 'text-warning'
  return 'text-info'
}

const getCategoryColor = (category) => {
  if (category === 'CAD操作') return 'primary'
  if (category === '软件控制') return 'success'
  if (category === '系统服务') return 'warning'
  return 'info'
}

const getCategoryIconClass = (category) => {
  if (category === 'CAD操作') return 'fas fa-cogs'
  if (category === '软件控制') return 'fas fa-desktop'
  if (category === '系统服务') return 'fas fa-server'
  return 'fas fa-gear'
}

const hasExtraData = (log) => {
  const omitKeys = ['id', 'reportId', 'log_id', 'operation', 'operation_category', 'log_type', 'timestamp', 'createdAt', 'created_at', 'status', 'duration', 'details', 'errorInfo', 'error_message', 'user_id', 'client_id', 'client_ip', 'ip_address', 'resultMetrics', 'featureDetails', 'comparisonData', 'level', 'action_type']
  return Object.keys(log).some(key => !omitKeys.includes(key))
}

const formatExtraData = (log) => {
  const omitKeys = ['id', 'reportId', 'log_id', 'operation', 'operation_category', 'log_type', 'timestamp', 'createdAt', 'created_at', 'status', 'duration', 'details', 'errorInfo', 'error_message', 'user_id', 'client_id', 'client_ip', 'ip_address', 'resultMetrics', 'featureDetails', 'comparisonData', 'level', 'action_type']
  const extra = {}
  Object.keys(log).forEach(key => {
    if (!omitKeys.includes(key)) extra[key] = log[key]
  })
  return JSON.stringify(extra, null, 2)
}

const exportSelectedReport = () => {
  if (!currentReport.value) return ElMessage.warning('没有可导出的报告')
  // 模拟导出 PDF/JSON
  ElMessage.success(`报告 ${currentReport.value.reportId} 成功导出！`)
}
</script>

<style scoped>
.report-log-viewer {
  height: 100%;
  padding: var(--spacing-xl);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xl);
  background: var(--color-bg-primary);
  color: var(--color-text-primary);
  overflow-y: hidden;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}

.header-title {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.header-title h2 {
  font-size: var(--font-size-2xl);
  font-weight: 600;
  margin: 0;
  background: linear-gradient(90deg, var(--color-primary), #8bc34a);
  -webkit-background-clip: text;
  color: transparent;
}

.header-title i {
  font-size: var(--font-size-2xl);
  color: var(--color-primary);
}

.dashboard-content {
  flex: 1;
  min-height: 0;
  display: flex;
}

.split-layout {
  display: flex;
  gap: var(--spacing-xl);
  width: 100%;
  height: 100%;
}

.card-panel {
  background: var(--color-bg-card);
  border-radius: var(--size-border-radius-lg);
  border: 1px solid var(--color-border-primary);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.list-section {
  width: 320px;
  flex-shrink: 0;
}

.detail-section {
  flex: 1;
}

.section-header {
  padding: var(--spacing-lg);
  border-bottom: 1px solid var(--color-border-primary);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.section-header h3 {
  margin: 0;
  font-size: var(--font-size-lg);
}

.report-list {
  list-style: none;
  padding: 0;
  margin: 0;
  overflow-y: auto;
  flex: 1;
}

.report-item {
  display: flex;
  gap: var(--spacing-md);
  padding: var(--spacing-md) var(--spacing-lg);
  border-bottom: 1px solid var(--color-border-primary);
  cursor: pointer;
  transition: background 0.2s;
}

.report-item:hover {
  background: var(--color-white-rgb-05);
}

.report-item.active {
  background: rgba(var(--color-primary-rgb), 0.1);
  border-left: 3px solid var(--color-primary);
}

.item-icon {
  font-size: 20px;
  display: flex;
  align-items: center;
}
.item-icon.success { color: var(--color-success); }
.item-icon.failed { color: var(--color-error); }

.item-content {
  flex: 1;
  min-width: 0;
}

.item-title {
  font-weight: 600;
  font-size: var(--font-size-base);
  margin-bottom: 4px;
}

.item-meta {
  display: flex;
  justify-content: space-between;
  font-size: var(--font-size-xs);
  color: var(--color-text-tertiary);
}

.detail-header {
  padding: var(--spacing-lg);
  border-bottom: 1px solid var(--color-border-primary);
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--color-white-rgb-05);
}

.report-id-badge {
  font-size: var(--font-size-lg);
  font-weight: 600;
}
.report-id-badge i { color: var(--color-primary); margin-right: 5px; }

.report-time {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.detail-body {
  padding: var(--spacing-lg);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xl);
}

.stat-summary {
  display: flex;
  gap: var(--spacing-lg);
}

.summary-box {
  flex: 1;
  background: var(--color-bg-primary);
  border: 1px dashed var(--color-border-primary);
  padding: var(--spacing-md);
  border-radius: var(--size-border-radius);
  text-align: center;
}

.box-label {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  margin-bottom: var(--spacing-xs);
}

.box-value {
  font-size: 24px;
  font-weight: bold;
}
.box-value.accent {
  color: var(--color-primary);
}

.group-title {
  font-size: var(--font-size-lg);
  margin: 0 0 var(--spacing-md) 0;
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
}

.group-title i { color: var(--color-primary); }
.group-title.error-text { color: var(--color-error); }
.group-title.error-text i { color: var(--color-error); }

.step-text {
  font-size: 13px;
  color: var(--color-text-secondary);
}

.text-success { color: var(--color-success); font-weight: bold; }
.text-warning { color: var(--color-warning); font-weight: bold; }
.text-info { color: var(--color-text-primary); }

.error-console {
  background: #1e1e1e;
  color: #ff5252;
  font-family: monospace;
  padding: var(--spacing-md);
  border-radius: var(--size-border-radius);
  white-space: pre-wrap;
  word-break: break-all;
  border-left: 4px solid var(--color-error);
}

.empty-state {
  align-items: center;
  justify-content: center;
  color: var(--color-text-secondary);
  font-size: var(--font-size-lg);
}

.empty-icon {
  font-size: 48px;
  margin-bottom: var(--spacing-md);
  opacity: 0.5;
}

/* 覆盖 Element UI 样式以支持深色模式 */
:deep(.el-table) {
  --el-table-bg-color: var(--color-bg-primary);
  --el-table-tr-bg-color: var(--color-bg-primary);
  --el-table-header-bg-color: var(--color-white-rgb-05);
  --el-table-border-color: var(--color-border-primary);
  --el-table-text-color: var(--color-text-primary);
  --el-table-header-text-color: var(--color-text-primary);
}

/* 对比视图样式 */
.report-tabs {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

:deep(.el-tabs__content) {
  flex: 1;
  overflow-y: auto;
  padding: 0;
}

:deep(.el-tabs__header) {
  margin-bottom: 0;
  padding: 0 var(--spacing-lg);
  background: var(--color-bg-primary);
  border-bottom: 1px solid var(--color-border-primary);
}

.comparison-view {
  padding: var(--spacing-lg);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xl);
}

.comparison-mode-switch {
  display: flex;
  justify-content: center;
  margin-bottom: var(--spacing-md);
}

.result-badges {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-md);
  margin-bottom: var(--spacing-lg);
  font-size: var(--font-size-lg);
}

.badge-arrow {
  color: var(--color-text-secondary);
}

.compress-rates {
  display: flex;
  gap: var(--spacing-lg);
  margin-bottom: var(--spacing-xl);
}

.rate-card {
  flex: 1;
  background: var(--color-white-rgb-05);
  border-radius: var(--size-border-radius);
  padding: var(--spacing-lg);
  text-align: center;
  border: 1px solid var(--color-border-primary);
}

.rate-title {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  margin-bottom: var(--spacing-sm);
}

.rate-value {
  font-size: 32px;
  font-weight: bold;
}

.comparison-columns {
  display: flex;
  gap: var(--spacing-lg);
  align-items: stretch;
}

.comp-col {
  flex: 1;
  background: var(--color-bg-primary);
  border: 1px dashed var(--color-border-primary);
  border-radius: var(--size-border-radius);
  padding: var(--spacing-lg);
}

.comp-col h4 {
  margin: 0 0 var(--spacing-lg) 0;
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  color: var(--color-text-primary);
  border-bottom: 1px solid var(--color-border-primary);
  padding-bottom: var(--spacing-sm);
}

.vs-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 24px;
  color: var(--color-text-tertiary);
  padding: 0 var(--spacing-md);
}

.prop-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.prop-list li {
  display: flex;
  justify-content: space-between;
  padding: var(--spacing-sm) 0;
  border-bottom: 1px solid var(--color-white-rgb-05);
}

.prop-list li:last-child {
  border-bottom: none;
}

.prop-label {
  color: var(--color-text-secondary);
}

.prop-value {
  font-weight: 500;
  text-align: right;
}

.empty-data {
  text-align: center;
  padding: 40px;
  color: var(--color-text-tertiary);
  font-size: var(--font-size-lg);
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: center;
}

.empty-data i {
  font-size: 48px;
}

.upload-panels {
  display: flex;
  gap: var(--spacing-xl);
  align-items: center;
  margin-bottom: var(--spacing-xl);
}

.upload-box {
  flex: 1;
  height: 200px;
  border: 2px dashed var(--color-border-primary);
  border-radius: var(--size-border-radius-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-md);
  color: var(--color-text-secondary);
  transition: all 0.3s;
  cursor: pointer;
  background: var(--color-bg-primary);
}

.upload-box:hover {
  border-color: var(--color-primary);
  background: rgba(var(--color-primary-rgb), 0.05);
}

.upload-box.target:hover {
  border-color: var(--color-success);
  background: rgba(var(--color-success-rgb), 0.05);
}

.upload-box.baseline-source {
  cursor: default;
  border-style: solid;
  border-color: var(--color-primary);
  background: rgba(var(--color-primary-rgb), 0.02);
}

.baseline-source .status-indicator {
  width: 60px;
  height: 60px;
  background: rgba(var(--color-primary-rgb), 0.1);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--spacing-sm);
}

.baseline-source .status-indicator i {
  font-size: 28px;
  color: var(--color-primary);
}

.baseline-source .source-title {
  font-size: var(--font-size-lg);
  font-weight: 600;
  color: var(--color-text-primary);
  margin: 0;
}

.baseline-source .source-desc {
  font-size: var(--font-size-sm);
  color: var(--color-text-tertiary);
  margin: 0;
  text-align: center;
  padding: 0 var(--spacing-lg);
}

.upload-box i {
  font-size: 48px;
  color: var(--color-text-tertiary);
}

.upload-box:hover i {
  color: var(--color-primary);
}
.upload-box.target:hover i {
  color: var(--color-success);
}

.vs-icon {
  font-size: 32px;
  font-weight: bold;
  color: var(--color-text-tertiary);
}

.manual-actions {
  text-align: center;
}

/* 实时流程逻辑样式 */
.live-flow-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.flow-step {
  background: var(--color-bg-primary);
  border: 1px solid var(--color-border-primary);
  border-radius: 12px;
  padding: 20px;
  opacity: 0.5;
  transition: all 0.3s;
}

.flow-step.step-active {
  opacity: 1;
  border-color: var(--color-primary);
  box-shadow: 0 0 10px rgba(var(--color-primary-rgb), 0.1);
}

.flow-step.step-done {
  opacity: 0.8;
  border-color: var(--color-success);
}

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

.step-num {
  width: 32px;
  height: 32px;
  background: var(--color-white-rgb-05);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  color: var(--color-text-secondary);
}

.step-active .step-num {
  background: var(--color-primary);
  color: #fff;
}

.step-done .step-num {
  background: var(--color-success);
  color: #fff;
}

.step-header h3 {
  margin: 0;
  font-size: 16px;
  color: var(--color-text-primary);
}

.step-content {
  padding-left: 44px;
}

.live-btn {
  border-radius: 8px;
  min-width: 200px;
}

.wait-msg {
  color: var(--color-text-secondary);
  font-size: 14px;
  margin-bottom: 12px;
}

.success-msg {
  color: var(--color-text-primary);
  font-size: 14px;
}

.success-msg i {
  margin-right: 6px;
  font-size: 16px;
}

.captured-data {
  padding: 16px;
  background: rgba(var(--color-primary-rgb), 0.05);
  border: 1px dashed var(--color-primary);
  max-width: 400px;
}

.captured-data h4 {
  margin: 0 0 12px 0;
  font-size: 15px;
}

.data-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.data-list li {
  display: flex;
  margin-bottom: 8px;
  font-size: 14px;
}

.data-list .lbl {
  color: var(--color-text-secondary);
  width: 80px;
}

.data-list .val {
  color: var(--color-text-primary);
  font-weight: 500;
}

.mt-4 {
  margin-top: 16px;
}

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

/* 新增美化：执行概览 */
.overview-custom-header {
  padding: 16px 24px !important;
  background: var(--color-bg-primary) !important;
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
}

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

.status-tag {
  font-weight: 600;
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  height: 32px;
}

.report-id-text {
  font-family: var(--font-family-mono);
  color: var(--color-text-secondary);
  font-size: 14px;
}

.styled-body {
  max-width: 1000px;
  margin: 0 auto;
}

.overview-title-card {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px dashed var(--color-border-primary);
}

.overview-title-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
}

.overview-title-icon.icon-primary { background: rgba(var(--color-primary-rgb), 0.1); color: var(--color-primary); }
.overview-title-icon.icon-success { background: rgba(var(--color-success-rgb), 0.1); color: var(--color-success); }
.overview-title-icon.icon-warning { background: rgba(var(--color-warning-rgb), 0.1); color: var(--color-warning); }
.overview-title-icon.icon-info { background: rgba(255, 255, 255, 0.05); color: var(--color-text-secondary); }

.overview-title-text {
  font-size: 24px;
  font-weight: 600;
  margin: 0;
  color: var(--color-text-primary);
}

.overview-info-card {
  border-radius: var(--size-border-radius-lg);
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  margin-bottom: var(--spacing-xl);
}

:deep(.el-descriptions__label.el-descriptions__cell.is-bordered-label) {
  background-color: var(--color-bg-tertiary, #2b2b2b);
  color: var(--color-text-primary);
  border-color: var(--color-border-primary);
}

:deep(.el-descriptions__content.el-descriptions__cell.is-bordered-content) {
  background-color: var(--color-bg-secondary, #1f1f1f);
  color: var(--color-text-secondary);
  border-color: var(--color-border-primary);
}

:deep(.el-descriptions) {
  border: 1px solid var(--color-border-primary);
  border-radius: var(--size-border-radius-lg);
  overflow: hidden;
}

:deep(.el-descriptions .el-descriptions__table) {
  border-radius: var(--size-border-radius-lg);
}

.desc-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  color: var(--color-text-primary);
}

.mono {
  font-family: var(--font-family-mono);
  color: var(--color-text-regular);
}

.custom-alert-box {
  border-radius: var(--size-border-radius-lg);
  white-space: pre-wrap;
  word-break: break-all;
  padding: 16px;
  align-items: flex-start;
  background-color: rgba(var(--color-primary-rgb), 0.1);
  border: 1px solid rgba(var(--color-primary-rgb), 0.2);
}

:deep(.custom-alert-box .el-alert__title) {
  color: var(--color-text-primary);
  font-size: 14px;
}

.json-viewer-box {
  background: #1e1e1e;
  border-radius: var(--size-border-radius-lg);
  padding: 16px;
  overflow-x: auto;
  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.2);
}

.json-viewer-box pre {
  margin: 0;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 13px;
  line-height: 1.5;
  color: #9cdcfe;
}
</style>
