<script setup lang="ts">
import { ref, computed, nextTick, watch } from 'vue';
import { BASE_PATH } from '@/api/request';
import { getToken } from '@/utils/token';
import feedback from '@/utils/feedback';
import { ElTooltip } from 'element-plus';
import {
  searchExcelData,
  searchExcelDataPage,
  deleteBatch,
  getBatchListPage,
  deleteBatchData,
  type ExcelRowData
} from '@/api/price/excel';
import FilePreview from '@/components/file/preview.vue';

// ==================== 状态定义 ====================

/** 搜索关键字 - 双向绑定到搜索框 */
const searchKeyword = ref('');

/** 当前批次ID - 用于数据列表刷新 */
const currentBatchId = ref('');

/** 搜索加载状态 - 控制下拉 loading 动画 */
const searchLoading = ref(false);

/** 导入按钮加载状态 */
const uploadLoading = ref(false);

/** 弹窗显示状态 */
const detailDialogVisible = ref(false);

/** 当前 Tab 页签 */
const activeTab = ref('table-list');

/** 批次列表数据 - 存储所有导入的表格 */
const batchList = ref<ExcelRowData[]>([]);

/** 批次列表加载状态 */
const batchLoading = ref(false);

/** 批次列表分页参数 */
const batchPagination = ref({
  current: 1,
  size: 10,
  total: 0
});

/** 批次列表搜索关键字 */
const batchKeyword = ref('');

/** 搜索结果数据 - 搜索匹配到的所有数据 */
const searchResultList = ref<ExcelRowData[]>([]);

/** 搜索结果加载状态 */
const searchResultLoading = ref(false);

/** 保存的搜索关键字 - 用于在 autocomplete 选择后恢复原始关键字进行匹配 */
const savedKeyword = ref('');

/** 当前选中的行数据 - 用于卡片详情展示 */
const currentRow = ref<ExcelRowData | null>(null);

/** 动态列名数组 - 从 rowData JSON 解析生成 */
const detailColumns = ref<string[]>([]);

/** 文件预览弹窗状态 */
const previewVisible = ref(false);

/** 预览文件列表 */
const previewFiles = ref<{ fileName: string; filePath: string }[]>([]);

// ==================== 计算属性 ====================

/** 格式化日期 */
const formatDate = (dateStr: string) => {
  if (!dateStr) return '-';
  const date = new Date(dateStr);
  return date.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  });
};

/** 获取纯文本（去掉HTML标签），用于悬浮提示显示 */
const getRawText = (html: string): string => {
  if (!html) return '';
  return html.replace(/<[^>]*>/g, '');
};

/**
 * 高亮关键字
 * @param text - 原始文本
 * @returns 包含高亮的 HTML 字符串
 */
const highlightKeyword = (text: string): string => {
  if (!text) return '';
  const keyword = searchKeyword.value.toLowerCase().trim();
  if (!keyword) return text;
  const regex = new RegExp(`(${escapeRegExp(keyword)})`, 'gi');
  return text.replace(regex, '<mark class="highlight">$1</mark>');
};

/**
 * 获取匹配最佳的字段值（类似百度搜索）
 * @param item - 选中的数据项
 * @param keyword - 用户输入的关键字
 * @returns 匹配最佳的字段 { key, value }
 */
const getBestMatchField = (item: ExcelRowData, keyword: string) => {
  const keywordLower = keyword.toLowerCase();

  if (activeTab.value === 'table-list') {
    // 表格 Tab：直接使用 batchName
    return { key: 'batchName', value: item.batchName || item.fileName || '' };
  }

  // 数据 Tab：解析 rowData，找到匹配次数最多的字段
  try {
    const rowObj = JSON.parse(item.rowData);
    let bestField = { key: '', value: '', matchCount: 0 };

    Object.entries(rowObj).forEach(([key, val]) => {
      const text = String(val);
      const textLower = text.toLowerCase();
      // 统计关键字匹配次数
      const count = (textLower.match(new RegExp(escapeRegExp(keywordLower), 'gi')) || []).length;
      // 优先选择匹配次数多的，其次选择文本更长的
      if (count > bestField.matchCount ||
          (count === bestField.matchCount && text.length > bestField.value.length)) {
        bestField = { key, value: text, matchCount: count };
      }
    });

    return bestField;
  } catch {
    return { key: '', value: '' };
  }
};

// ==================== 搜索相关方法 ====================

/**
 * 执行搜索 - el-autocomplete 的 fetch-suggestions 回调格式
 * 
 * 【核心逻辑】
 * 1. el-autocomplete 会传入 (queryString, callback)
 * 2. 根据当前 Tab 调用不同接口：
 *    - 表格列表 Tab: 调用批次列表接口
 *    - 数据列表 Tab: 调用数据搜索接口
 * 3. 将结果通过 callback 传递给下拉组件显示
 * 
 * @param queryString - 用户输入的搜索关键字
 * @param callback - 回调函数，将结果数组传入下拉组件
 */
const performSearch = (queryString: string, callback: (results: ExcelRowData[]) => void) => {
  // 【边界判断】关键字为空时，直接返回空数组
  if (!queryString || !queryString.trim()) {
    callback([]);
    return;
  }

  // 保存用户输入的关键字，用于选择后匹配
  savedKeyword.value = queryString.trim();

  // 【请求开始】开启 loading 状态
  searchLoading.value = true;
  
  if (activeTab.value === 'table-list') {
    /**
     * 【表格列表 Tab】调用批次列表接口
     * 接口地址: POST /price/excel/batch/page
     */
    getBatchListPage(queryString.trim(), 1, 20)
      .then((res: any) => {
        if (res?.records) {
          callback(res.records);
        } else {
          callback([]);
        }
      })
      .catch((error) => {
        console.error('搜索失败:', error);
        callback([]);
      })
      .finally(() => {
        searchLoading.value = false;
      });
  } else {
    /**
     * 【数据列表 Tab】调用数据搜索接口
     * 接口地址: POST /price/excel/search
     */
    searchExcelData(queryString.trim(), 20)
      .then((res: any) => {
        if (res?.records) {
          callback(res.records);
        } else {
          callback([]);
        }
      })
      .catch((error) => {
        console.error('搜索失败:', error);
        callback([]);
      })
      .finally(() => {
        searchLoading.value = false;
      });
  }
};

/**
 * 选中联想结果 - 切换到数据列表 Tab
 * 
 * 【核心逻辑】
 * 1. 保持搜索关键字不变
 * 2. 切换到数据列表 Tab
 * 3. 【重要】不重新请求，数据已经在列表中
 * 
 * @param item - 选中的 ExcelRowData 对象
 */
const handleSelectSuggestion = (item: ExcelRowData) => {
  // 使用保存的原始关键字进行匹配，而不是已被 autocomplete 覆盖的 searchKeyword
  const keyword = savedKeyword.value.toLowerCase().trim();

  // 获取匹配最佳的字段值
  const bestMatch = getBestMatchField(item, keyword);

  // 填入搜索框并自动触发搜索
  nextTick(() => {
    searchKeyword.value = bestMatch.value;
    handleSearchBtnClick();
  });
};

/**
 * 点击搜索按钮 - 根据当前 Tab 执行搜索
 */
const handleSearchBtnClick = () => {
  if (activeTab.value === 'table-list') {
    /**
     * 【表格列表 Tab】调用批次列表接口
     */
    batchPagination.value.current = 1;
    batchKeyword.value = searchKeyword.value;
    loadBatchList();
  } else {
    /**
     * 【数据列表 Tab】调用数据搜索接口
     */
    activeTab.value = 'data-list';
    loadSearchResults(searchKeyword.value);
  }
};

/**
 * 清空搜索框 - 重置筛选效果
 */
const handleClearSearch = () => {
  if (activeTab.value === 'table-list') {
    // 表格列表 Tab：重置分页和批次关键字，重新加载
    batchKeyword.value = '';
    batchPagination.value.current = 1;
    loadBatchList();
  } else {
    // 数据列表 Tab：用空关键字刷新当前批次数据
    loadSearchResults('', currentBatchId.value);
  }
};

/**
 * 解析 rowData JSON 字符串为对象
 * 
 * @param rowData - JSON 字符串
 * @returns 解析后的对象，解析失败返回空对象
 */
const parseRowData = (rowData: string) => {
  try {
    return JSON.parse(rowData);
  } catch {
    return {};
  }
};

/**
 * 格式化 rowData 为带高亮的键值对列表
 * 
 * 【核心逻辑】
 * 解析 rowData JSON，将每个键值对格式化为可读列表
 * 搜索关键字会高亮显示
 * 
 * @param item - ExcelRowData 对象
 * @returns 包含高亮的 HTML 字符串
 */
const getCardPreview = (item: ExcelRowData) => {
  try {
    const rowObj = JSON.parse(item.rowData);
    const keyword = searchKeyword.value.toLowerCase().trim();
    
    // 转换为键值对数组
    const entries = Object.entries(rowObj).map(([key, value]) => {
      let displayValue = typeof value === 'object' 
        ? JSON.stringify(value) 
        : String(value);
      
      // 高亮匹配的关键字
      const highlightText = (text: string) => {
        if (!keyword) return text;
        const regex = new RegExp(`(${escapeRegExp(keyword)})`, 'gi');
        return text.replace(regex, '<mark class="highlight">$1</mark>');
      };
      
      return {
        key: highlightText(key),
        value: highlightText(displayValue)
      };
    });
    
    return entries;
  } catch {
    return [];
  }
};

/**
 * 转义正则特殊字符
 */
const escapeRegExp = (string: string) => {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
};

// ==================== 表格列表相关方法 ====================

/**
 * 加载所有批次列表
 * 
 * 【核心逻辑】
 * 1. 调用搜索接口（关键字为空）获取所有数据
 * 2. 按批次分组汇总信息
 */
const loadBatchList = async () => {
  debugger
  batchLoading.value = true;
  
  try {
    const res: any = await getBatchListPage(
      batchKeyword.value,
      batchPagination.value.current,
      batchPagination.value.size
    );
    
    if (res?.records) {
      batchList.value = res.records;
      batchPagination.value.total = res.total || res.records.length;
    }
  } catch (error) {
    console.error('加载批次列表失败:', error);
  } finally {
    batchLoading.value = false;
  }
};

/**
 * 查看批次下的所有数据
 * 
 * @param batch - 批次信息
 */
const viewBatchData = (batch: ExcelRowData) => {
  /**
   * 【UI 操作】切换到数据列表 Tab
   */
  activeTab.value = 'data-list';
  
  /**
   * 【数据赋值】保存批次名称到搜索关键字
   */
  searchKeyword.value = batch.batchName;
  
  /**
   * 【数据赋值】保存批次ID用于刷新
   */
  currentBatchId.value = batch.batchId;
  
  /**
   * 【数据赋值】加载该批次的所有数据
   */
  loadSearchResults('', batch.batchId);
};

// ==================== 数据列表相关方法 ====================

/**
 * 加载搜索结果
 * 
 * @param keyword - 搜索关键字（可选）
 * @param batchId - 批次ID（可选）
 */
const loadSearchResults = async (keyword: string = '', batchId?: string) => {
  searchResultLoading.value = true;
  
  try {
    /**
     * 【API 请求】分页搜索数据
     * 接口地址: POST /price/excel/search
     */
    const res: any = await searchExcelDataPage({
      keyword,
      batchId,
      current: 1,
      size: 100  // 获取更多数据用于卡片展示
    });
    
    if (res?.records) {
      /**
       * 【数据赋值】保存搜索结果
       */
      searchResultList.value = res.records;
    }
  } catch (error) {
    console.error('加载搜索结果失败:', error);
    feedback.msgError('加载数据失败');
  } finally {
    searchResultLoading.value = false;
  }
};

/**
 * 查看数据卡片详情
 * 
 * @param item - ExcelRowData 对象
 */
const viewDataDetail = (item: ExcelRowData) => {
  /**
   * 【数据赋值】保存当前行数据
   */
  currentRow.value = item;
  
  /**
   * 【数据解析】从 rowData JSON 中提取列名
   */
  try {
    const rowObj = JSON.parse(item.rowData);
    /**
     * 【数据赋值】将 JSON 对象的键名作为表格列名
     */
    detailColumns.value = Object.keys(rowObj);
  } catch {
    detailColumns.value = [];
  }
  
  /**
   * 【UI 操作】打开详情弹窗
   */
  detailDialogVisible.value = true;
};

// ==================== 导入相关方法 ====================

/**
 * 上传前校验
 * 
 * 【校验规则】
 * 1. 文件格式必须是 .xls 或 .xlsx
 * 2. 文件大小不能超过 100MB
 * 
 * @param file - 上传的文件对象
 * @returns 校验通过返回 true，否则返回 false
 */
const beforeUpload = (file: File) => {
  // 【文件格式校验】只允许 Excel 文件
  const isExcel = file.name.endsWith('.xls') || file.name.endsWith('.xlsx');
  if (!isExcel) {
    feedback.msgError('只能上传 Excel 文件');
    return false;
  }
  
  // 【文件大小校验】限制 100MB
  const isLt100M = file.size / 1024 / 1024 < 100;
  if (!isLt100M) {
    feedback.msgError('文件大小不能超过 100MB');
    return false;
  }
  
  // 【UI 状态】开启上传 loading
  uploadLoading.value = true;
  return true;
};

/**
 * 上传成功回调
 * 
 * @param response - 后端返回的响应数据
 */
const handleUploadSuccess = (response: any) => {
  // 【UI 状态】关闭上传 loading
  uploadLoading.value = false;
  
  // 【响应判断】根据 code 判断是否成功
  if (response?.code === 200) {
    feedback.msgSuccess('导入成功');
    
    /**
     * 【数据刷新】重新加载表格列表
     */
    loadBatchList();
  } else {
    feedback.msgError(response?.message || '导入失败');
  }
};

/**
 * 上传失败回调
 */
const handleUploadError = () => {
  // 【UI 状态】关闭上传 loading
  uploadLoading.value = false;
  feedback.msgError('上传失败');
};

// ==================== 弹窗方法 ====================

/**
 * 关闭弹窗
 */
const handleCloseDialog = () => {
  // 【UI 操作】关闭弹窗
  detailDialogVisible.value = false;
  // 【数据清理】清空已选数据
  currentRow.value = null;
  detailColumns.value = [];
};

/**
 * 打开文件预览
 * @param row - 批次数据行
 */
const handleFilePreview = (row: ExcelRowData) => {
  debugger
  previewFiles.value = [{ fileName: row.fileName, filePath: row.filePath }];
  previewVisible.value = true;
};

// ==================== 分页处理 ====================

/**
 * 批次列表分页变化
 */
const handleBatchPageChange = (page: number) => {
  batchPagination.value.current = page;
  loadBatchList();
};

/**
 * 批次列表每页条数变化
 */
const handleBatchSizeChange = (size: number) => {
  batchPagination.value.size = size;
  batchPagination.value.current = 1;
  loadBatchList();
};

// ==================== 删除操作 ====================

/**
 * 删除批次
 */
const handleDeleteBatch = async (batch: ExcelRowData) => {
  try {
    await feedback.confirm('确定删除该批次吗？删除后数据将无法恢复！', '确定');
    await deleteBatchData(batch.batchName);
    feedback.msgSuccess('删除成功');
    loadBatchList();
  } catch (error: any) {
    if (error !== 'cancel') {
      feedback.msgError(error.message);
    }
  }
};

// ==================== 响应式监听 ====================

/**
 * 监听搜索关键字变化，当清空时自动刷新当前 Tab 数据
 */
watch(searchKeyword, (newVal, oldVal) => {
  // 当关键字从有值变为空时，刷新数据
  if (oldVal && oldVal.length > 0 && (!newVal || newVal.length === 0)) {
    handleClearSearch();
  }
});

// ==================== 初始化 ====================

/**
 * 【生命周期】组件挂载时加载数据
 */
loadBatchList();
</script>

<template>
  <div class="container">
    <!-- 页面标题 -->
    <h2 class="mb-20">价格库搜索</h2>
    
    <!-- ==================== 搜索区域 ==================== -->
    <div class="search-section mb-20">
      <el-row :gutter="20">
        <el-col :span="20">
          <el-autocomplete
            v-model="searchKeyword"
            :fetch-suggestions="performSearch"
            :placeholder="activeTab === 'table-list' ? '输入关键字搜索表格...' : '输入关键字搜索表格数据...'"
            :trigger-on-focus="false"
            clearable
            :debounce="300"
            :loading="searchLoading"
            value-key="fileName"
            class="search-input"
            popper-class="search-suggestions-popper"
            @select="handleSelectSuggestion"
            @clear="handleClearSearch"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
            <!-- 自定义下拉项模板 -->
            <template #default="{ item }">
              <div class="suggestion-item">
                <template v-if="activeTab === 'table-list'">
                  <!-- 表格列表 Tab：显示批次名称 -->
                  <div class="batch-name-item">
                    <el-icon><Document /></el-icon>
                    <span v-html="highlightKeyword(item.batchName || item.fileName || '')"></span>
                  </div>
                </template>
                <template v-else>
                  <!-- 数据列表 Tab：显示行数据预览 -->
                  <div class="row-data-list">
                    <el-tooltip
                      v-for="(field, index) in getCardPreview(item)" 
                      :key="index"
                      :content="getRawText(field.value)"
                      placement="bottom"
                      effect="light"
                      :enterable="true"
                      :show-after="300"
                      :hide-after="0"
                    >
                      <div class="row-field">
                        <span class="field-key" v-html="field.key"></span>
                        <span class="field-separator">:</span>
                        <span class="field-value" v-html="field.value"></span>
                      </div>
                    </el-tooltip>
                  </div>
                </template>
              </div>
            </template>
          </el-autocomplete>
        </el-col>
        <el-col :span="4">
          <el-button type="primary" class="search-btn" @click="handleSearchBtnClick">
            <el-icon><Search /></el-icon>
            搜索
          </el-button>
        </el-col>
      </el-row>
    </div>
    
    <!-- ==================== 导入区域 ==================== -->
    <div class="upload-section">
      <div class="upload-card">
        <div class="upload-content">
          <div class="upload-icon-wrapper">
            <el-icon class="upload-icon"><Upload /></el-icon>
          </div>
          <div class="upload-text">
            <div class="upload-title">上传 Excel 文件</div>
            <div class="upload-tips">支持 .xls 和 .xlsx 格式，单个文件不超过 100MB</div>
          </div>
        </div>
        <el-upload
          :action="`${BASE_PATH}/price/excel/import`"
          :headers="{ Authorization: getToken() }"
          :before-upload="beforeUpload"
          :on-success="handleUploadSuccess"
          :on-error="handleUploadError"
          :show-file-list="false"
          :accept="'.xls,.xlsx'"
          class="upload-trigger"
        >
          <el-button type="primary" :loading="uploadLoading" class="upload-btn">
            <el-icon v-if="!uploadLoading"><Upload /></el-icon>
            {{ uploadLoading ? '上传中...' : '选择文件' }}
          </el-button>
        </el-upload>
      </div>
    </div>
    
    <!-- ==================== 列表展示区域 ==================== -->
    <div class="list-section">
      <!-- Tab 切换 -->
      <el-tabs v-model="activeTab" class="content-tabs">
        <!-- 表格列表 Tab -->
        <el-tab-pane label="表格列表" name="table-list">
          <template #label>
            <div class="tab-label">
              <el-icon><FolderOpened /></el-icon>
              <span>表格列表</span>
              <el-badge :value="batchPagination.total" type="primary" />
            </div>
          </template>
          
          <!-- 表格列表 - 表格布局 -->
          <div class="batch-table" v-loading="batchLoading">
            <el-empty v-if="batchList.length === 0" description="暂无导入的表格" />
            <el-table 
              v-else
              :data="batchList" 
              border 
              stripe
              style="width: 100%"
              @row-click="viewBatchData"
            >
              <el-table-column label="文件名" prop="fileName" min-width="180">
                <template #default="{ row }">
                  <div class="file-name-cell">
                    <el-icon class="file-icon"><Document /></el-icon>
                    <span class="file-name-link" @click.stop="handleFilePreview(row)">{{ row.fileName }}</span>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="批次名称" prop="batchName" min-width="200">
                <template #default="{ row }">
                  <el-tag type="info" effect="plain">{{ row.batchName }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="上传时间" prop="uploadTime" width="160">
                <template #default="{ row }">
                  <span class="time-text">
                    <el-icon><Clock /></el-icon>
                    {{ formatDate(row.uploadTime) }}
                  </span>
                </template>
              </el-table-column>
              <el-table-column label="上传人" prop="uploadUserName" width="120" align="center">
                <template #default="{ row }">
                  <el-tag size="small" type="success">{{ row.uploadUserName }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="数据条数" prop="rowIndex" width="100" align="center">
                <template #default="{ row }">
                  <el-tag size="small" type="primary">
                    <el-icon><List /></el-icon>
                    {{ row.rowIndex }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="150" align="center">
                <template #default="{ row }">
                  <el-button type="primary" size="small" @click.stop="viewBatchData(row)">
                    查看
                  </el-button>
                  <el-button type="danger" size="small" @click.stop="handleDeleteBatch(row)">
                    删除
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
            
            <!-- 分页组件 -->
            <div class="pagination-wrapper" v-if="batchList.length > 0">
              <el-pagination
                v-model:current-page="batchPagination.current"
                v-model:page-size="batchPagination.size"
                :page-sizes="[10, 20, 50, 100]"
                :total="batchPagination.total"
                layout="total, sizes, prev, pager, next, jumper"
                @current-change="handleBatchPageChange"
                @size-change="handleBatchSizeChange"
              />
            </div>
          </div>
        </el-tab-pane>
        
        <!-- 数据列表 Tab -->
        <el-tab-pane label="数据列表" name="data-list">
          <template #label>
            <div class="tab-label">
              <el-icon><DataLine /></el-icon>
              <span>数据列表</span>
              <el-badge :value="searchResultList.length" type="success" />
            </div>
          </template>
          
          <!-- 搜索结果提示 -->
          <div class="search-tip" v-if="searchKeyword">
            <el-icon><InfoFilled /></el-icon>
            当前显示：<strong>{{ searchKeyword }}</strong> 相关的 {{ searchResultList.length }} 条数据
          </div>
          
          <!-- 数据列表 - 卡片布局 -->
          <div class="card-list" v-loading="searchResultLoading">
            <el-empty v-if="searchResultList.length === 0" description="请通过上方搜索框搜索数据" />
            <div 
              v-for="(item, index) in searchResultList" 
              :key="item.id || index"
              class="data-card"
              @click="viewDataDetail(item)"
            >
              <div class="data-card-header">
                <div class="data-source">
                  <el-icon class="source-icon"><Document /></el-icon>
                  <span class="source-name clickable" @click.stop="handleFilePreview(item)">{{ item.fileName }}</span>
                  <el-tag size="small" type="info">{{ item.sheetName }}</el-tag>
                </div>
                <span class="row-number">第 {{ item.rowIndex }} 行</span>
              </div>
              <div class="data-card-body">
                <div class="row-data-list">
                  <el-tooltip
                    v-for="(field, fIdx) in getCardPreview(item)"
                    :key="fIdx"
                    :content="getRawText(field.value)"
                    placement="bottom"
                    effect="light"
                    :enterable="true"
                    :show-after="300"
                    :hide-after="0"
                  >
                    <div class="row-field">
                      <span class="field-key" v-html="field.key"></span>
                      <span class="field-separator">:</span>
                      <span class="field-value" v-html="field.value"></span>
                    </div>
                  </el-tooltip>
                </div>
              </div>
              <div class="data-card-footer">
                <span class="batch-name" v-if="item.batchName">
                  <el-icon><Folder /></el-icon>
                  {{ item.batchName }}
                </span>
                <el-button type="primary" link size="small">
                  查看详情
                  <el-icon><View /></el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
    
    <!-- ==================== 数据详情弹窗 ==================== -->
    <el-dialog
      v-model="detailDialogVisible"
      title="数据详情"
      width="900px"
      :close-on-click-modal="false"
      @close="handleCloseDialog"
      class="detail-dialog"
    >
      <!-- 数据源信息卡片 -->
      <div class="info-card mb-16">
        <div class="card-header">
          <el-icon><Document /></el-icon>
          <span>数据来源</span>
        </div>
        <el-descriptions :column="2" border size="small">
          <el-descriptions-item label="文件名">
            <el-tag type="primary" effect="plain">{{ currentRow?.fileName }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="Sheet名称">
            <el-tag type="success" effect="plain">{{ currentRow?.sheetName }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="Excel行号">
            <span class="row-index">第 {{ currentRow?.rowIndex }} 行</span>
          </el-descriptions-item>
          <el-descriptions-item label="批次名称">
            {{ currentRow?.batchName || '默认批次' }}
          </el-descriptions-item>
        </el-descriptions>
      </div>
      
      <!-- 数据内容展示 -->
      <div class="data-card">
        <div class="card-header">
          <el-icon><DataLine /></el-icon>
          <span>数据内容</span>
        </div>
        
        <!-- 表格视图 -->
        <div class="table-section">
          <div class="section-title">表格视图</div>
          <el-table 
            :data="[parseRowData(currentRow?.rowData || '')]" 
            border 
            size="small"
            stripe
            max-height="300"
            class="detail-table"
          >
            <el-table-column
              v-for="col in detailColumns"
              :key="col"
              :prop="col"
              :label="col"
              min-width="120"
              show-overflow-tooltip
            />
          </el-table>
        </div>
        
        <!-- JSON原始数据 -->
        <el-collapse>
          <el-collapse-item title="查看原始JSON" name="json">
            <pre class="json-block">{{ currentRow?.rowData }}</pre>
          </el-collapse-item>
        </el-collapse>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleCloseDialog">关闭</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 文件预览组件 -->
    <FilePreview :files="previewFiles" :show="previewVisible" @update:show="previewVisible = $event" />
  </div>
</template>

<style scoped lang="scss">
// ==================== 搜索区域样式 ====================
.search-section {
  .search-input {
    width: 100%;
    
    :deep(.el-input__wrapper) {
      width: 100%;
    }
  }
  
  .search-btn {
    width: 100%;
  }
}

// ==================== 导入区域样式 ====================
.upload-section {
  margin-bottom: 20px;
}

.upload-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24px 32px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(102, 126, 234, 0.3);
  
  .upload-content {
    display: flex;
    align-items: center;
    gap: 20px;
    
    .upload-icon-wrapper {
      width: 64px;
      height: 64px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: rgba(255, 255, 255, 0.2);
      border-radius: 16px;
      backdrop-filter: blur(10px);
      
      .upload-icon {
        font-size: 32px;
        color: #fff;
      }
    }
    
    .upload-text {
      .upload-title {
        font-size: 20px;
        font-weight: 600;
        color: #fff;
        margin-bottom: 6px;
      }
      
      .upload-tips {
        font-size: 14px;
        color: rgba(255, 255, 255, 0.8);
      }
    }
  }
  
  .upload-trigger {
    .upload-btn {
      padding: 12px 32px;
      font-size: 16px;
      font-weight: 500;
      background: #fff;
      color: #667eea;
      border: none;
      border-radius: 10px;
      transition: all 0.3s ease;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
      
      &:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
      }
      
      .el-icon {
        margin-right: 8px;
      }
    }
  }
}

// ==================== 列表区域样式 ====================
.list-section {
  background: #fff;
  border-radius: 8px;
  padding: 20px;
  border: 1px solid rgba(198, 208, 251, 1);
}

.content-tabs {
  :deep(.el-tabs__header) {
    margin-bottom: 20px;
  }
  
  :deep(.el-tabs__nav-wrap::after) {
    height: 1px;
  }
}

.tab-label {
  display: flex;
  align-items: center;
  gap: 6px;
  
  .el-badge {
    margin-left: 4px;
  }
}

// ==================== 表格列表样式 ====================
.batch-table {
  .file-name-cell {
    display: flex;
    align-items: center;
    gap: 8px;

    .file-icon {
      color: var(--primary-color);
      font-size: 18px;
    }

    .file-name-link {
      color: var(--primary-color);
      cursor: pointer;
      transition: all 0.2s;

      &:hover {
        text-decoration: underline;
        font-weight: 500;
      }
    }
  }
  
  .file-name-text {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: #666;
  }
  
  .time-text {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: #999;
    font-size: 13px;
  }
}

// ==================== 数据列表卡片 ====================
.search-tip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  background: #f0f6ff;
  border-radius: 6px;
  margin-bottom: 16px;
  font-size: 13px;
  color: #666;
  
  strong {
    color: var(--primary-color);
  }
}

.card-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.data-card {
  background: #ffffff;
  border: 1px solid #e4e7ed;
  border-radius: 12px;
  padding: 16px 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
  
  &:hover {
    border-color: #409eff;
    box-shadow: 0 4px 16px rgba(64, 158, 255, 0.2);
    transform: translateY(-1px);
  }
  
  .data-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 2px solid #f0f2f5;
    
    .data-source {
      display: flex;
      align-items: center;
      gap: 10px;
      
      .source-icon {
        color: #409eff;
        font-size: 20px;
      }
      
      .source-name {
        font-weight: 600;
        font-size: 15px;
        color: #303133;

        &.clickable {
          color: var(--primary-color);
          cursor: pointer;
          transition: all 0.2s;

          &:hover {
            text-decoration: underline;
            font-weight: 500;
          }
        }
      }
    }
    
    .row-number {
      font-size: 13px;
      color: #606266;
      background: #f4f4f5;
      padding: 4px 12px;
      border-radius: 12px;
      font-weight: 500;
    }
  }
  
  .data-card-body {
    margin-bottom: 12px;
    
    .row-data-list {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 8px 16px;
    }
    
    .row-field {
      display: flex;
      align-items: baseline;
      gap: 6px;
      padding: 8px 12px;
      background: #f8f9fa;
      border-radius: 8px;
      font-size: 13px;
      line-height: 1.4;
      border-left: 3px solid #409eff;
      overflow: hidden;
      
      .field-key {
        color: #409eff;
        font-weight: 600;
        white-space: nowrap;
      }
      
      .field-separator {
        color: #909399;
      }
      
      .field-value {
        color: #303133;
        word-break: break-word;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
  }
  
  .data-card-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-top: 12px;
    border-top: 2px solid #f0f2f5;
    
    .batch-name {
      display: flex;
      align-items: center;
      gap: 6px;
      font-size: 13px;
      color: #909399;
    }
  }
}

// ==================== 下拉列表样式 ====================
.suggestion-item {
  padding: 12px;
  margin-bottom: 8px;
  background: rgba(240, 247, 255, 0.6);
  border: 1px solid #b3d8fd;
  border-left: 4px solid #66b1ff;
  border-radius: 6px;
  transition: all 0.2s ease;
  
  &:hover {
    background: rgba(64, 158, 255, 0.1);
    border-color: #409eff;
    transform: translateX(3px);
  }
  
  &:last-child {
    margin-bottom: 0;
  }
  
  .row-data-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6px 12px;
  }
  
  .row-field {
    display: flex;
    align-items: baseline;
    gap: 4px;
    padding: 4px 8px;
    background: rgba(0, 0, 0, 0.03);
    border-radius: 4px;
    font-size: 12px;
    line-height: 1.4;
    overflow: hidden;
    
    .field-key {
      color: #409eff;
      font-weight: 600;
      white-space: nowrap;
    }
    
    .field-separator {
      color: #909399;
    }
    
    .field-value {
      color: #606266;
      word-break: break-word;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}

// ==================== 悬浮提示样式 ====================
.el-tooltip__popper {
  font-size: 13px !important;
  line-height: 1.6 !important;
  max-width: 400px !important;
  padding: 10px 14px !important;
  background: rgba(50, 50, 50, 0.95) !important;
  border-radius: 8px !important;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15) !important;
  
  .el-tooltip__arrow::before {
    background: rgba(50, 50, 50, 0.95) !important;
  }
}

:deep(.highlight) {
  background: linear-gradient(135deg, #ffe58f 0%, #ffd591 100%);
  color: #d48806;
  padding: 1px 4px;
  border-radius: 4px;
  font-weight: 700;
  box-shadow: 0 1px 2px rgba(212, 136, 6, 0.2);
}

// ==================== 弹窗样式 ====================
.info-card {
  background: linear-gradient(135deg, #f8f9ff 0%, #eef1ff 100%);
  border: 1px solid #d9e2ff;
  border-radius: 8px;
  padding: 16px;
  
  .card-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    color: var(--primary-color);
    font-weight: 600;
    font-size: 14px;
  }
  
  .row-index {
    color: var(--primary-color);
    font-weight: 600;
  }
}

.data-card {
  background: #fff;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  padding: 16px;
  
  .card-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 16px;
    color: var(--primary-color);
    font-weight: 600;
    font-size: 14px;
  }
  
  .table-section {
    margin-bottom: 16px;
    
    .section-title {
      font-size: 13px;
      color: #666;
      margin-bottom: 10px;
      font-weight: 500;
    }
    
    .detail-table {
      border-radius: 6px;
      overflow: hidden;
    }
  }
  
  .json-block {
    margin: 0;
    padding: 12px;
    background: #f5f7fa;
    border-radius: 6px;
    font-size: 12px;
    color: #606266;
    white-space: pre-wrap;
    word-break: break-all;
    max-height: 200px;
    overflow: auto;
    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  }
}

// ==================== Element Plus 深度样式 ====================
:deep(.el-autocomplete) {
  width: 100%;
  
  .el-input {
    width: 100%;
  }
}

:deep(.el-table) {
  border-radius: 6px;
  
  .el-table__header th {
    background-color: #f5f7fa;
    color: #333;
    font-weight: 600;
  }
  
  .el-table__row:hover > td {
    background-color: #f0f6ff;
  }
}

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

:deep(.el-dialog__footer) {
  border-top: 1px solid #ebeef5;
  padding: 12px 24px;
}

:deep(.el-collapse) {
  border: none;
  
  .el-collapse-item__header {
    font-size: 13px;
    color: #666;
    background: transparent;
    border: none;
  }
  
  .el-collapse-item__wrap {
    border: none;
    background: transparent;
  }
  
  .el-collapse-item__content {
    padding-bottom: 0;
  }
}

.dialog-footer {
  text-align: right;
}

// 下拉建议弹窗
:deep(.search-suggestions-popper) {
  .el-autocomplete-suggestion__wrap {
    padding: 8px 12px;
  }
  
  li {
    padding: 0 !important;
    background: transparent !important;
  }
}

// 批次名称下拉项样式
.batch-name-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 4px;
  font-size: 14px;
  color: #333;
  
  .el-icon {
    color: #409eff;
    flex-shrink: 0;
  }
  
  span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

// 分页组件样式
.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
  padding: 16px 0;
  
  :deep(.el-pagination) {
    .el-pagination__total {
      font-size: 14px;
      color: #606266;
    }
  }
}
</style>
