<template>
  <div class="map-list-container">
    <!-- 顶部工具条 -->
    <div class="toolbar-section">
      <!-- 搜索和筛选区 -->
      <div class="toolbar-filters">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索地图名称..."
          prefix-icon="el-icon-search"
          clearable
          class="search-input"
          @input="handleSearch"
        />
        
        <el-select
          v-model="statusFilter"
          placeholder="状态筛选"
          clearable
          class="status-filter"
          @change="handleFilterChange"
        >
          <el-option label="全部状态" value="all" />
          <el-option label="正常" value="ok" />
          <el-option label="不可用" value="down" />
          <el-option label="扫描中" value="scanning" />
        </el-select>
        
        <el-select
          v-model="sortField"
          placeholder="排序方式"
          class="sort-select"
          @change="handleSortChange"
        >
          <el-option label="最近修改" value="updated" />
          <el-option label="名称" value="name" />
          <el-option label="状态" value="status" />
        </el-select>
    </div>

      <!-- 操作按钮区 -->
      <div class="toolbar-actions">
        <el-button
          type="default"
          icon="el-icon-upload2"
          size="small"
          @click="handleImport"
        >
          导入地图
        </el-button>
        
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="small"
          @click="handleCreate"
        >
          新建地图
        </el-button>
        
        <el-button
          class="xt-btn"
          :disabled="selectedMaps.length !== 1"
          icon="el-icon-discover"
          size="small"
          @click="openSelfExplore"
        >
          自主探索
        </el-button>
        
        <el-button
          class="xt-btn"
          :disabled="selectedMaps.length !== 1"
          icon="el-icon-connection"
          size="small"
          @click="openRemoteExplore"
        >
          遥控探索
        </el-button>

        <!-- 视图切换 -->
        <el-button-group class="view-toggle">
          <el-button
            :type="viewMode === 'card' ? 'primary' : 'default'"
            icon="el-icon-s-grid"
            size="small"
            @click="setViewMode('card')"
            title="卡片视图"
          />
          <el-button
            :type="viewMode === 'table' ? 'primary' : 'default'"
            icon="el-icon-menu"
            size="small"
            @click="setViewMode('table')"
            title="表格视图"
          />
        </el-button-group>
      </div>
    </div>



    <!-- 主要内容区域 -->
    <div class="main-content">
      <!-- 卡片视图 -->
      <template v-if="viewMode === 'card'">
        <!-- 加载骨架屏 -->
        <div v-if="loading" class="card-grid" :class="{ compact: isCompactMode }">
          <div v-for="n in 12" :key="n" class="skeleton-card">
            <div class="skeleton-thumb"></div>
            <div class="skeleton-content">
              <div class="skeleton-title"></div>
              <div class="skeleton-remark"></div>
              <div class="skeleton-meta"></div>
            </div>
          </div>
        </div>

        <!-- 空态 -->
        <div v-else-if="mapList.length === 0" class="empty-state">
          <div class="empty-illustration">
            <i class="el-icon-map-location"></i>
          </div>
          <h3 class="empty-title">暂无地图</h3>
          <p class="empty-description">
            {{ hasSearchOrFilter ? '没有找到符合条件的地图' : '您还没有创建任何地图' }}
          </p>
          <div v-if="!hasSearchOrFilter" class="empty-actions">
            <el-button type="primary" icon="el-icon-plus" @click="handleCreate">
              新建地图
            </el-button>
            <el-button type="default" icon="el-icon-upload2" @click="handleImport">
              导入地图
            </el-button>
          </div>
        </div>

        <!-- 地图卡片列表 -->
        <div v-else class="card-grid" :class="{ compact: isCompactMode }">
          <XtMapCard
            v-for="item in displayedList"
            :key="item.id || item.mapId || item.map_id"
            :item="item"
            :selectable="selectedMaps.length > 0"
            :selected="selectedMaps.includes(item.id)"
            :map-file-base="MAP_FILE_BASE"
            @clickNav="handleNavigation"
            @clickEdit="handleEdit"
            @clickMore="handleCardAction"
            @selectChange="handleSelectChange"
          />
        </div>
      </template>

            <!-- 表格视图 -->
      <template v-else>
        <div ref="tableWrap" class="table-wrapper">
          <el-table 
            ref="mapTable"
            v-loading="loading" 
            :data="displayedList" 
            @selection-change="handleTableSelectionChange" 
            class="map-table"
            :fit="true"
            style="width: 100%"
            :border="false"
            :height="useFixedHeight ? tableHeight : null"
            :header-cell-style="() => ({ padding: '10px 12px', whiteSpace: 'nowrap' })"
            :cell-style="() => ({ padding: '10px 12px' })"
            empty-text="暂无地图数据"
          >
                        <el-table-column type="selection" width="56" align="center" :reserve-selection="true"></el-table-column>
            
            <el-table-column
              label="序号"
              type="index"
              :index="indexMethod"
              width="64"
              align="center"
              header-align="center"
              class-name="col-index"
              label-class-name="col-index-header">
            </el-table-column>
            
                        <el-table-column prop="mapName" label="地图名称" min-width="260" show-overflow-tooltip>
          <template slot-scope="scope">
                <div class="table-name">
                  <!-- {{ scope.row.name }} -->
                  {{ scope.row.map }}
                </div>
          </template>
        </el-table-column>
            
            <el-table-column label="缩略图" width="120" align="center">
          <template slot-scope="scope">
                <div class="table-thumb">
                  <img v-if="scope.row.thumbUrl" :src="scope.row.thumbUrl" alt="缩略图" />
                  <i v-else class="el-icon-map-location"></i>
                </div>
          </template>
        </el-table-column>
            
            <el-table-column label="状态" width="120" align="center">
          <template slot-scope="scope">
                <el-tag 
                  :type="getStatusConfig(scope.row.state).type" 
                  size="mini" 
                  effect="plain"
                >
                  <i :class="getStatusConfig(scope.row.state).icon"></i>
                  {{ getStatusConfig(scope.row.state).text }}
                </el-tag>
          </template>
        </el-table-column>
            
            <el-table-column prop="remark" label="备注" min-width="360" show-overflow-tooltip />
            
                        <el-table-column prop="updatedAt" label="更新时间" width="180" align="center">
              <template slot-scope="{ row }">
                {{ formatDateTimeCompat(pickUpdatedAt(row)) }}
    </template>
            </el-table-column>
            
                        <el-table-column label="操作" width="220" header-align="center" align="right">
              <template slot-scope="{ row }">
                <div class="op-cell">
                  <router-link :to="buildNavTo(this, row)" class="op-link">
                    <i class="el-icon-position"></i><span class="op-text">导航</span>
                  </router-link>
                  <router-link :to="buildEditTo(this, row)" class="op-link">
                    <i class="el-icon-edit"></i><span class="op-text">编辑</span>
                  </router-link>
                  <el-dropdown @command="cmd=>onMore(row,cmd)">
                    <span class="el-dropdown-link">
                      <i class="el-icon-more"></i><span class="op-text">更多</span>
                    </span>
                    <el-dropdown-menu slot="dropdown" class="xt-more">
                      <el-dropdown-item command="rename"><i class="el-icon-edit"></i> 重命名</el-dropdown-item>
                      <el-dropdown-item command="download"><i class="el-icon-download"></i> 下载地图</el-dropdown-item>
                      <el-dropdown-item command="build"><i class="el-icon-cpu"></i> 构建地图</el-dropdown-item>
                      <el-dropdown-item divided command="delete" class="is-danger"><i class="el-icon-delete"></i> 删除地图</el-dropdown-item>
                      <el-dropdown-item divided command="calibrate"><i class="el-icon-position"></i> 坐标系标定</el-dropdown-item>
                    </el-dropdown-menu>
                  </el-dropdown>
                </div>
              </template>
            </el-table-column>
      </el-table>
      </div>
    </template>
              </div>

    <!-- 分页 -->
    <div v-if="!loading && mapList.length > 0" class="pagination-section">
      <!-- 密度切换 -->
      <div v-if="total > 60 && viewMode === 'card'" class="density-toggle">
        <el-button-group size="mini">
          <el-button 
            :type="isCompactMode ? 'default' : 'primary'"
            @click="isCompactMode = false"
          >
            常规
          </el-button>
          <el-button 
            :type="isCompactMode ? 'primary' : 'default'"
            @click="isCompactMode = true"
          >
            紧凑
          </el-button>
        </el-button-group>
                </div>

      <el-pagination
        :current-page="currentPage"
        :page-sizes="[12, 24, 48, 96]"
        :page-size="pageSize"
        :total="totalCount"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
      />
              </div>
        <!-- 自主探索配置对话框 -->
    <el-dialog :visible.sync="autoExploreOpen" width="560px" append-to-body :close-on-click-modal="false" class="xt-explore-dialog">
      <span slot="title" class="xt-title">
        自主探索
        <small class="xt-subtitle">为所选地图配置探索规则 · {{ selectedMapName }}</small>
      </span>
      <el-form ref="form" :model="exploreParams" :rules="rules" label-width="120px" class="xt-form">
        <el-form-item label="最大探索时间" prop="maxTime">
          <div class="xt-field">
            <el-input-number 
              v-model="exploreParams.maxTime" 
              :min="1" 
              :step="1" 
              controls-position="right" 
              placeholder="请输入时间"
            />
            <span class="xt-unit">分钟</span>
            <span class="xt-hint">建议 1-10 分钟</span>
          </div>
        </el-form-item>
        <el-form-item label="最远探索距离" prop="maxDistance">
          <div class="xt-field">
            <el-input-number 
              v-model="exploreParams.maxDistance" 
              :min="1" 
              :step="1" 
              controls-position="right" 
              placeholder="请输入距离"
            />
            <span class="xt-unit">米</span>
            <span class="xt-hint">建议不超过 500 米</span>
          </div>
        </el-form-item>
        <el-form-item label="最大探索范围" prop="maxRange">
          <div class="xt-field">
            <el-input-number 
              v-model="exploreParams.maxRange" 
              :min="1" 
              :step="1" 
              controls-position="right" 
              placeholder="请输入范围"
            />
            <span class="xt-unit">平方米</span>
            <span class="xt-hint">建议 100-5000 平方米</span>
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer xt-footer">
        <el-button plain @click="autoExploreCancel">取 消</el-button>
        <el-button type="primary" @click="submitAutoExplore">开 始</el-button>
      </span>
    </el-dialog>

    <!-- 遥控探索确认对话框 -->
    <el-dialog :visible.sync="remoteExploreOpen" width="480px" append-to-body :close-on-click-modal="false" class="xt-confirm-dialog">
      <span slot="title" class="confirm-title">
        <i class="el-icon-warning" style="color: #E6A23C; margin-right: 8px;"></i>
        提示
      </span>
      <div class="confirm-content">
        <p>将对编号为「{{ selectedMapCode }}-{{ selectedMapName }}」的地图执行遥控探索，是否继续？</p>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="remoteExploreCancel">取 消</el-button>
        <el-button type="primary" @click="submitRemoteExplore">确 定</el-button>
      </span>
    </el-dialog>
    <!--  下载地图dia -->
    <el-dialog :title="title" :visible.sync="downloadOpen" width="520px" append-to-body :close-on-click-modal="false">
      <div style="margin-bottom: 20px;">
        <span style="font-weight: bold;">请选择下载的地图组件:</span>
      </div>
      <el-checkbox-group v-model="downLoadTypes" style="margin-bottom: 10px;">
        <el-checkbox label="tree" :checked="true">八叉树</el-checkbox>
        <el-checkbox label="vector" :checked="true">矢量</el-checkbox>
        <el-checkbox label="las" :checked="true">las数量</el-checkbox>
        <el-checkbox label="tile" :checked="true">瓦片地图</el-checkbox>
        <el-checkbox label="task" :checked="true">任务数据</el-checkbox>
      </el-checkbox-group>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitDownload">开 始</el-button>
        <el-button @click="downloadOpen = false">取 消</el-button>
      </div>
    </el-dialog>
    <!--  构建地图dia -->
    <el-dialog :title="title" :visible.sync="constructOpen" width="520px" append-to-body :close-on-click-modal="false">
      <span style="margin-right: 10px;">构建模式:</span>
      <el-radio-group v-model="constructModle" size="mini">
        <el-radio-button label="auto">自动构建</el-radio-button>
        <el-radio-button label="hand">手动构建</el-radio-button>
      </el-radio-group>
      <div v-if="constructModle == 'hand'">
        <p style="margin-top: 20px;">请选择地图及数据:</p>
        <el-checkbox-group v-model="constructTypes" style="margin-bottom: 10px;">
          <el-checkbox label="tree" :checked="true">八叉树</el-checkbox>
          <el-checkbox label="las" :checked="true">las数量</el-checkbox>
          <el-checkbox label="tile" :checked="true">瓦片地图</el-checkbox>
          <el-checkbox label="potree" :checked="true">potree</el-checkbox>
        </el-checkbox-group>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitConstruct">开 始</el-button>
        <el-button @click="constructOpen = false">取 消</el-button>
      </div>
    </el-dialog>
    <div>
        <button @click="publishMsg">发布消息</button>
        <button @click="addTopic">动态订阅 topic3</button>
        <button @click="removeTopic">动态取消 topic2</button>
      </div>

      <MqttComp ref="mqtt" :topics="topics" @message-received="onMessage" />
  </div>
</template>

<script>
import MqttComp from "@/components/Mqtt/mqttComp.vue";
// 导入地图卡片组件
import XtMapCard from '@/components/XtMapCard'
// 导入日期格式化工具
import { formatDateTimeCompat, pickUpdatedAt } from '@/utils/datefmt'
// 导入路由辅助函数
import { buildNavTo, buildEditTo, buildCalibrateTo, buildConstructTo, pickId } from '@/utils/route-helpers'
// 安全获取数组函数
function pickArray(...arrs){ 
  for(const a of arrs){ 
    if(Array.isArray(a) && a.length>=0) return a 
  } 
  return [] 
}

// 尝试导入真实 API，失败则使用 Mock
let mapApi
try {
  // 尝试导入真实 API（如果存在）
  mapApi = require('@/api/map/index.js')
} catch (error) {
  // Fallback 到 Mock API
  mapApi = require('@/api/mock/maps')
}

// 地图文件服务基础URL（可根据实际情况调整）
const MAP_FILE_BASE = 'http://101.35.49.102:9000' // 示例地址，实际使用时请替换

export default {
  name: "MapList",
  
  components: {
    XtMapCard,
     MqttComp,
  },
  
  data() {
    return {
      //  topics: ["/robot4inspection/a477be75f66fe3cb/task/target/action/goto/reply","/robot4inspection/a477be75f66fe3cb/task/target/event/arrive"], // 初始订阅的 topic
      topics:[],
      // 常量
      MAP_FILE_BASE,
      
      // 视图模式
      viewMode: 'card', // 'card' | 'table'
      
      // 加载状态
      loading: false,
      
      // 数据
      mapList: [],
      total: 0,
      currentPage: 1,
      pageSize: 12,

      // Mock 数据
   /*    mockMapList: [
        {
          id: 1,
          code: 'SH001',
          name: '上海办公楼一层',
          mapName: '上海办公楼一层',
          showImg: 'https://placehold.co/320x180/4f46e5/white?text=Office+Floor+1',
          thumbUrl: 'https://placehold.co/320x180/4f46e5/white?text=Office+Floor+1',
          status: 'ok',
          use: true,
          top: true,
          remark: '主要办公区域地图，包含接待区、办公区、会议室',
          updatedAt: '2024-01-15T14:22:00Z'
        },
        {
          id: 2,
          code: 'FC001',
          name: '工厂车间A区',
          mapName: '工厂车间A区',
          showImg: 'https://placehold.co/320x180/dc2626/white?text=Factory+A',
          thumbUrl: 'https://placehold.co/320x180/dc2626/white?text=Factory+A',
          status: 'down',
          use: false,
          top: false,
          remark: '生产车间A区域，设备较多，需要定期更新',
          updatedAt: '2024-01-12T09:12:00Z'
        },
        {
          id: 3,
          code: 'WH001',
          name: '仓库主区域',
          mapName: '仓库主区域',
          showImg: 'https://placehold.co/320x180/f59e0b/white?text=Warehouse',
          thumbUrl: 'https://placehold.co/320x180/f59e0b/white?text=Warehouse',
          status: 'scanning',
          use: false,
          top: true,
          remark: '仓库主要存储区域，正在进行地图更新扫描',
          updatedAt: '2024-01-14T16:45:00Z'
        },
        {
          id: 4,
          code: 'RD002',
          name: '研发中心二楼',
          mapName: '研发中心二楼',
          showImg: 'https://placehold.co/320x180/059669/white?text=R%26D+Floor+2',
          thumbUrl: 'https://placehold.co/320x180/059669/white?text=R%26D+Floor+2',
          status: 'ok',
          use: false,
          top: false,
          remark: '研发中心实验室区域，包含多个实验室和会议室',
          updatedAt: '2024-01-11T11:30:00Z'
        },
        {
          id: 5,
          code: 'PK001',
          name: '停车场地下一层',
          mapName: '停车场地下一层',
          showImg: 'https://placehold.co/320x180/7c3aed/white?text=Parking+B1',
          thumbUrl: 'https://placehold.co/320x180/7c3aed/white?text=Parking+B1',
          status: 'ok',
          use: false,
          top: false,
          remark: '地下停车场区域图，包含车位信息和通道标识',
          updatedAt: '2024-01-10T08:15:00Z'
        },
        {
          id: 6,
          code: 'CF001',
          name: '食堂餐厅区域',
          mapName: '食堂餐厅区域',
          showImg: 'https://placehold.co/320x180/ea580c/white?text=Cafeteria',
          thumbUrl: 'https://placehold.co/320x180/ea580c/white?text=Cafeteria',
          status: 'scanning',
          use: false,
          top: false,
          remark: '员工食堂及餐厅区域，包含用餐区和厨房区域',
          updatedAt: '2024-01-09T12:40:00Z'
        },
        {
          id: 7,
          code: 'OD001',
          name: '户外园区',
          mapName: '户外园区',
          showImg: 'https://placehold.co/320x180/16a34a/white?text=Outdoor+Park',
          thumbUrl: 'https://placehold.co/320x180/16a34a/white?text=Outdoor+Park',
          status: 'ok',
          use: false,
          top: false,
          remark: '公司户外园区，包含步行道、休息区和绿化带',
          updatedAt: '2024-01-08T15:20:00Z'
        },
        {
          id: 8,
          code: 'MC001',
          name: '会议中心',
          mapName: '会议中心',
          showImg: 'https://placehold.co/320x180/0891b2/white?text=Conference',
          thumbUrl: 'https://placehold.co/320x180/0891b2/white?text=Conference',
          status: 'down',
          use: false,
          top: false,
          remark: '多功能会议中心，包含大型会议厅和小型讨论室',
          updatedAt: '2024-01-07T10:05:00Z'
        }
      ], */
      
      // 搜索和筛选
      searchKeyword: '',
      statusFilter: 'all',
      sortField: 'updated',
      sortOrder: 'desc',
      searchDebounceTimer: null,
      
      // 选择状态
      selectedMaps: [],
      
      // UI状态
      isCompactMode: false,
      useFixedHeight: false,
      tableHeight: 520, // 表格高度
      

      
      // 弹窗状态（保留原有对话框）
      title: "",
      autoExploreOpen: false,   // 自主探索弹框
      remoteExploreOpen: false, // 遥控探索确认弹框
      downloadOpen: false,
      constructOpen: false,
      constructModle: 'hand',
      exploreParams: {
        maxTime: null,
        maxDistance: null,
        maxRange: null
      },
      downLoadTypes: [],
      constructTypes: [],
      rules: {
        maxTime: [
          { required: true, message: "最长时间不能为空", trigger: "blur" }
        ],
        maxDistance: [
          { required: true, message: "最远距离不能为空", trigger: "blur" }
        ],
        maxRange: [
          { required: true, message: "最大范围不能为空", trigger: "blur" }
        ],
      }
    };
  },

  computed: {
    // 原始数据：兼容不同变量名
    rawList(){
      // 按出现频率降序尝试
      return pickArray(this.mapList)
    },
    
    // 供表格/卡片使用的数据（先不做筛选，只做分页裁切；如果你已有筛选，请把你现有的筛选结果放到最前面）
    displayedList(){
      // 如果已有筛选后的数据，优先使用
      /* if (this.searchKeyword.trim() || this.statusFilter !== 'all') {
        // 使用现有的筛选逻辑
        let filteredData = [...this.mockMapList]
        
        // 搜索过滤
        if (this.searchKeyword.trim()) {
          const keyword = this.searchKeyword.toLowerCase()
          filteredData = filteredData.filter(item => 
            item.name.toLowerCase().includes(keyword) ||
            item.remark.toLowerCase().includes(keyword)
          )
        }
        
        // 状态筛选
        if (this.statusFilter !== 'all') {
          filteredData = filteredData.filter(item => item.status === this.statusFilter)
        }
        
        // 排序
        filteredData.sort((a, b) => {
          let aVal, bVal
          
          switch (this.sortField) {
            case 'name':
              aVal = a.name.toLowerCase()
              bVal = b.name.toLowerCase()
              break
            case 'status':
              // 状态优先级：ok > scanning > down
              const statusOrder = { ok: 2, scanning: 1, down: 0 }
              aVal = statusOrder[a.status] || 0
              bVal = statusOrder[b.status] || 0
              break
            case 'updated':
            default:
              aVal = new Date(a.updatedAt).getTime()
              bVal = new Date(b.updatedAt).getTime()
              break
          }

          if (this.sortOrder === 'asc') {
            return aVal > bVal ? 1 : aVal < bVal ? -1 : 0
          } else {
            return aVal < bVal ? 1 : aVal > bVal ? -1 : 0
          }
        })
        
        // 分页
        const start = (this.currentPage - 1) * this.pageSize
        const end = start + this.pageSize
        return filteredData.slice(start, end)
      }
       */
      // 否则使用通用分页逻辑
      const src = this.rawList || []
      console.log('src', src);
      
      const page = this.pagination?.page || this.pageNum || this.currentPage || 1
      const size = this.pagination?.pageSize || this.pageSize || 10
      const start = (page-1)*size
      return src.slice(start, start+size)
    },
    
    totalCount(){
/*       if (this.searchKeyword.trim() || this.statusFilter !== 'all') {
        // 使用现有的筛选逻辑计算总数
        let filteredData = [...this.mockMapList]
        
        // 搜索过滤
        if (this.searchKeyword.trim()) {
          const keyword = this.searchKeyword.toLowerCase()
          filteredData = filteredData.filter(item => 
            item.name.toLowerCase().includes(keyword) ||
            item.remark.toLowerCase().includes(keyword)
          )
        }
        
        // 状态筛选
        if (this.statusFilter !== 'all') {
          filteredData = filteredData.filter(item => item.status === this.statusFilter)
        }
        
        return filteredData.length
      } */
      
      const src = this.rawList || []
      return src.length
    },

    // 是否有搜索或筛选条件
    hasSearchOrFilter() {
      return this.searchKeyword.trim() || this.statusFilter !== 'all'
    },

    // 获取选中的地图名称
    selectedMapName() {
      if (this.selectedMaps.length === 1) {
        const selectedMap = this.displayedList.find(map => map.id === this.selectedMaps[0]) || 
                           this.rawList.find(map => map.id === this.selectedMaps[0])
        return selectedMap ? selectedMap.name : ''
      }
      return ''
    },

    // 获取选中的地图编号
    selectedMapCode() {
      if (this.selectedMaps.length === 1) {
        const selectedMap = this.displayedList.find(map => map.id === this.selectedMaps[0]) || 
                           this.rawList.find(map => map.id === this.selectedMaps[0])
        return selectedMap ? (selectedMap.code || selectedMap.id) : ''
      }
      return ''
    }
  },

  created() {
    this.loadViewMode()
    this.calculateTableHeight()
  },
  
  watch: {
    displayedList() {
      this.$nextTick(() => this.$refs.mapTable && this.$refs.mapTable.doLayout())
    }
  },

  mounted() {
    this.getList()
    this.calcTableHeight()
    window.addEventListener('resize', this.onResize)
    // 添加键盘监听
    this.addKeyboardListeners()
    
    // 表格渲染后重排一次，防止列宽缓存
    this.$nextTick(() => { 
      this.$refs.mapTable && this.$refs.mapTable.doLayout() 
    })
  },

  beforeDestroy() {
    window.removeEventListener('resize', this.onResize)
    // 移除键盘监听
    this.removeKeyboardListeners()
  },
  methods: {
    onMessage({ topic, message }) {
        console.log("收到消息:", topic, message);
      },

      publishMsg() {
        this.$refs.mqtt.publish("/robot4inspection/508b02dc5bcdca22/task/target/action/goto", {
        "timestamp" : 12345678,
        "args": [{"roadmap": "demo","nid": [10]}]
      });
    },

      addTopic() {
        if (!this.topics.includes("topic3")) this.topics.push("topic3");
      },

      removeTopic() {
        this.topics = this.topics.filter((t) => t !== "/robot4inspection/508b02dc5bcdca22/localization/pose");
      },
    // 获取地图列表
    async getList() {
      this.loading = true
      
      // 模拟加载延迟
      // await new Promise(resolve => setTimeout(resolve, 300))
      
      try {
        // TODO: 后续接入真实接口时，取消注释以下代码
        
        // const params = {
        //   page: this.currentPage,
        //   pageSize: this.pageSize,
        //   keyword: this.searchKeyword,
        //   status: this.statusFilter,
        //   sort: this.sortField,
        //   order: this.sortOrder
        // }

        const response = await mapApi.getMapList()
        console.log('Fetched map list:', response);
        
        if (response) {
          // this.mapList = this.processMapList(response)
          const { maps = [], states = [], total = 0 } = response || {}
  
          // 合并成对象数组 [{ map: 'demo', state: 'available' }]
          this.mapList = maps.map((map, index) => ({
            map,
            state: states[index] || null
          }))
          const test = await  mapApi.getMapThumbnail(this.mapList[0].map)
          console.log('Processed map list:', test);
          const url = URL.createObjectURL(test)
           
          this.$set(this.mapList[0], 'thumbUrl', url) 
          
          
        }
       
        
        // 使用 Mock 数据 - 确保 mapList 被设置
        // this.mapList = [...this.mockMapList]
        
        let filteredData = [...this.mapList]
        
        // 搜索过滤
        if (this.searchKeyword.trim()) {
          const keyword = this.searchKeyword.toLowerCase()
          filteredData = filteredData.filter(item => 
            item.name.toLowerCase().includes(keyword) ||
            item.remark.toLowerCase().includes(keyword)
          )
        }
        
        // 状态筛选
        if (this.statusFilter !== 'all') {
          filteredData = filteredData.filter(item => item.status === this.statusFilter)
        }
        
        // 排序
        filteredData.sort((a, b) => {
          let aVal, bVal
          
          switch (this.sortField) {
            case 'name':
              aVal = a.name.toLowerCase()
              bVal = b.name.toLowerCase()
              break
            case 'status':
              // 状态优先级：ok > scanning > down
              const statusOrder = { ok: 2, scanning: 1, down: 0 }
              aVal = statusOrder[a.status] || 0
              bVal = statusOrder[b.status] || 0
              break
            case 'updated':
            default:
              aVal = new Date(a.updatedAt).getTime()
              bVal = new Date(b.updatedAt).getTime()
              break
          }

          if (this.sortOrder === 'asc') {
            return aVal > bVal ? 1 : aVal < bVal ? -1 : 0
          } else {
            return aVal < bVal ? 1 : aVal > bVal ? -1 : 0
          }
        })
        
        // 分页
        this.total = filteredData.length
        const start = (this.currentPage - 1) * this.pageSize
        const end = start + this.pageSize
        const pagedData = filteredData.slice(start, end)
        
        // 处理后的数据仍然赋值给 mapList，但原始数据已保存
        this.mapList = this.processMapList(pagedData)
        
      } catch (error) {
        this.$message.error('获取地图列表失败: ' + error.message)
        this.mapList = []
        this.total = 0
      } finally {
        this.loading = false
        this.relayout()
      }
    },

    // 处理地图列表数据
    processMapList(list) {
      return list.map(item => ({
        ...item
      }))
    },

    // 表格相关方法
    calcTableHeight() {
      this.$nextTick(() => {
        if (!this.$refs.tableWrap) return
        const top = this.$refs.tableWrap.getBoundingClientRect().top
        this.tableHeight = window.innerHeight - top - 120 // 预留分页/外边距
        // 当行数 * 行高 + 表头高度 > 可用高度时，才启用固定高度（出现纵向滚动）
        const rowH = 48, headerH = 48
        const need = (this.mapList.length * rowH + headerH) > this.tableHeight
        this.useFixedHeight = need
        this.$refs.mapTable && this.$refs.mapTable.doLayout()
      })
    },

    onResize() {
      this.calcTableHeight()
    },

    relayout() {
      this.$nextTick(() => this.$refs.mapTable && this.$refs.mapTable.doLayout())
    },

    // 搜索处理（防抖）
    handleSearch() {
      clearTimeout(this.searchDebounceTimer)
      this.searchDebounceTimer = setTimeout(() => {
        this.currentPage = 1
        this.getList()
      }, 300)
    },

    // 筛选变化处理
    handleFilterChange() {
      this.currentPage = 1
      this.getList()
    },

    // 排序变化处理
    handleSortChange() {
      this.currentPage = 1
      this.getList()
    },

    // 页码变化
    handlePageChange(page) {
      this.currentPage = page
      this.getList()
      // 滚动到顶部
      this.$nextTick(() => {
        window.scrollTo({ top: 0, behavior: 'smooth' })
      })
    },

    // 页大小变化
    handleSizeChange(size) {
      this.pageSize = size
      this.currentPage = 1
      this.getList()
    },

    // 视图模式切换
    setViewMode(mode) {
      this.viewMode = mode
      this.saveViewMode()
      if (mode === 'table') {
        this.$nextTick(() => {
          this.calcTableHeight()
          this.relayout()
        })
      }
    },

    // 卡片选择变化
    handleSelectChange(id, checked) {
      if (checked) {
        if (!this.selectedMaps.includes(id)) {
          this.selectedMaps.push(id)
        }
      } else {
        const index = this.selectedMaps.indexOf(id)
        if (index > -1) {
          this.selectedMaps.splice(index, 1)
        }
      }
    },

    // 表格选择变化
    handleTableSelectionChange(selection) {
      this.selectedMaps = selection.map(item => item.id)
    },

    // 清除选择
    clearSelection() {
      this.selectedMaps = []
    },



    // 导航
    handleNavigation(id) {
      this.$router.push(`/map/navigation?id=${id}`)
    },

    // 编辑
    handleEdit(id) {
      this.$router.push(`/map/edit?id=${id}`)
    },

    // 表格操作方法
    goNav(row) {
      this.handleNavigation(row.id)
    },

    goEdit(row) {
      this.handleEdit(row.id)
    },

    async onMore(row, cmd) {
      const id = pickId(row);
      switch(cmd) {
        case 'rename':
          // 优先：已有重命名弹框/方法
          if (typeof this.openRenameDialog === 'function') return this.openRenameDialog(row);
          if (this.renameDialog) { this.renameDialog.visible = true; this.renameDialog.row = row; return; }
          // 兜底：Element prompt
          this.$prompt('请输入新的地图名称', '重命名', {
            inputValue: row.mapName || row.name || '',
            inputPattern: /\S+/,
            inputErrorMessage: '名称不能为空'
          }).then(({ value }) => {
            // 若有旧方法：this.renameMap(id, value)
            if (typeof this.renameMap === 'function') return this.renameMap(id, value);
            row.mapName = value; 
            row.name = value;
            this.$message.success('已重命名'); // mock 刷新
          }).catch(()=>{});
          break;

        case 'download':
          // 打开下载对话框
          this.title = `下载地图 - ${row.name || row.mapName || ''}`;
          this.currentRow = row;
          this.downloadOpen = true;
          break;

        case 'build':
          // 优先：旧路由/方法
          if (typeof this.openBuildDialog === 'function') return this.openBuildDialog(row);
          if (typeof this.constructOpen === 'boolean') {
          this.constructOpen = true;
            this.title = `构建地图 - ${row.name || row.mapName || ''}`;
            this.currentRow = row;
            return;
          }
          if (typeof this.toBuildPage === 'function') return this.toBuildPage(row);
          return this.$router.push(buildConstructTo(row));

        case 'delete':
          // 优先：旧删除方法
          if (typeof this.handleDelete === 'function') {
            return this.$confirm('确认删除该地图？此操作不可恢复', '删除地图', {type: 'warning'})
              .then(() => this.handleDelete([id]))
              .catch(() => {});
          }
          if (typeof this.deleteMap === 'function') {
            return this.$confirm('确认删除该地图？此操作不可恢复', '删除地图', {type: 'warning'})
              .then(() => this.deleteMap(id))
              .catch(() => {});
          }
          this.$confirm('确认删除该地图？此操作不可恢复', '删除地图', {type: 'warning'})
            .then(() => { 
              this.$emit && this.$emit('remove', row); 
              this.$message.success('已删除（mock）'); 
            })
            .catch(() => {});
          break;

        case 'calibrate':
          // 优先：旧路由/方法
          if (typeof this.openCalibration === 'function') return this.openCalibration(row);
          return this.$router.push(buildCalibrateTo(row));
          
        default:
          // 兼容原有的操作
          return this.handleCardAction(row.id, cmd);
      }
    },

    // 序号计算方法
    indexMethod(i) {
      const p = this.pagination?.page || this.pageNum || this.currentPage || 1
      const ps = this.pagination?.pageSize || this.pageSize || 10
      return (p - 1) * ps + i + 1
    },

    // 卡片更多操作
    async handleCardAction(id, action) {
      switch (action) {
        case 'publish':
          await this.handlePublish([id])
          break
        case 'copy':
          await this.handleCopy(id)
          break
        case 'download':
          await this.handleDownload(id)
          break
        case 'delete':
          await this.handleDelete([id])
          break
      }
    },

    // 创建地图
    async handleCreate() {
      try {
        const { value } = await this.$prompt('请输入地图名称', '新建地图', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPattern: /^[\w\u4e00-\u9fa5_-]+$/,
        inputErrorMessage: '地图名格式不正确'
        })

        const response = await mapApi.createMap({ name: value })
        if (response.code === 200) {
          this.$message.success('地图创建成功')
          this.getList()
        }
      } catch (error) {
        if (error !== 'cancel') {
          this.$message.error('创建失败: ' + error.message)
        }
      }
    },

    // 导入地图
    handleImport() {
      this.$message.info('导入功能开发中...')
    },

    // 发布地图
    async handlePublish(ids) {
      try {
        await this.$confirm(`确定要发布选中的 ${ids.length} 个地图吗？`, '发布确认', {
          type: 'warning'
        })

        const response = await mapApi.publishMaps(ids)
        if (response.code === 200) {
          this.$message.success(response.message)
          this.getList()
          this.clearSelection()
        }
      } catch (error) {
        if (error !== 'cancel') {
          this.$message.error('发布失败: ' + error.message)
        }
      }
    },

    // 复制地图
    async handleCopy(id) {
      try {
        const { value } = await this.$prompt('请输入新地图名称', '复制地图', {
          confirmButtonText: '确定',
          cancelButtonText: '取消'
        })

        const response = await mapApi.copyMap(id, value)
        if (response.code === 200) {
          this.$message.success('地图复制成功')
          this.getList()
        }
      } catch (error) {
        if (error !== 'cancel') {
          this.$message.error('复制失败: ' + error.message)
        }
      }
    },

    // 下载地图
    async handleDownload(id) {
      try {
        const response = await mapApi.downloadMap(id, ['tree', 'vector', 'tile'])
        if (response.code === 200) {
          // 创建临时下载链接
          const link = document.createElement('a')
          link.href = response.data.downloadUrl
          link.download = `map_${id}.zip`
          link.click()
          this.$message.success('下载已开始')
        }
      } catch (error) {
        this.$message.error('下载失败: ' + error.message)
      }
    },

    // 删除地图
    async handleDelete(ids) {
      try {
        await this.$confirm(`确定要删除选中的 ${ids.length} 个地图吗？删除后无法恢复。`, '删除确认', {
          type: 'warning',
          confirmButtonText: '确定删除',
          cancelButtonText: '取消'
        })

        const response = await mapApi.deleteMap(ids)
        if (response.code === 200) {
          this.$message.success(response.message)
          this.getList()
          this.clearSelection()
        }
      } catch (error) {
        if (error !== 'cancel') {
          this.$message.error('删除失败: ' + error.message)
        }
      }
    },

    // 批量操作
    async handleBatchPublish() {
      await this.handlePublish(this.selectedMaps)
    },

    async handleBatchDelete() {
      await this.handleDelete(this.selectedMaps)
    },

    // 获取状态配置
    getStatusConfig(status) {
      const configs = {
        available: { type: 'success', icon: 'el-icon-check', text: '正常' },
        unavailable: { type: 'danger', icon: 'el-icon-close', text: '不可用' },
        building : { type: 'warning', icon: 'el-icon-loading', text: '正在建图' },
        recording  : { type: 'warning', icon: 'el-icon-loading', text: '正在录制' }
      }
      return configs[status] || configs.ok
    },

    // 格式化时间
    formatDateTimeCompat,
    pickUpdatedAt,

    // 路由辅助函数
    buildNavTo(vm, row){ 
      return buildNavTo(row);
    },
    buildEditTo(vm, row){ 
      return buildEditTo(row);
    },
    pickId,

    // 本地存储相关
    loadViewMode() {
      try {
        const stored = localStorage.getItem('xt-map-view-mode')
        if (stored && ['card', 'table'].includes(stored)) {
          this.viewMode = stored
        }
      } catch (error) {
        console.warn('Failed to load view mode:', error)
      }
    },

    saveViewMode() {
      try {
        localStorage.setItem('xt-map-view-mode', this.viewMode)
      } catch (error) {
        console.warn('Failed to save view mode:', error)
      }
    },

    // 打开自主探索弹框
    openSelfExplore() {
      if (this.selectedMaps.length !== 1) {
        this.$message.warning('请选择一个地图进行自主探索')
        return
      }
      this.autoExploreOpen = true
    },

    // 打开遥控探索确认弹框
    openRemoteExplore() {
      if (this.selectedMaps.length !== 1) {
        this.$message.warning('请选择一个地图进行遥控探索')
        return
      }
      this.remoteExploreOpen = true
    },

    // 键盘监听方法
    addKeyboardListeners() {
      this.handleKeyboard = (event) => {
        if (this.autoExploreOpen) {
          if (event.key === 'Enter') {
            event.preventDefault()
            this.submitAutoExplore()
          } else if (event.key === 'Escape') {
            event.preventDefault()
            this.autoExploreCancel()
          }
        } else if (this.remoteExploreOpen) {
          if (event.key === 'Enter') {
            event.preventDefault()
            this.submitRemoteExplore()
          } else if (event.key === 'Escape') {
            event.preventDefault()
            this.remoteExploreCancel()
          }
        }
      }
      document.addEventListener('keydown', this.handleKeyboard)
    },

    removeKeyboardListeners() {
      if (this.handleKeyboard) {
        document.removeEventListener('keydown', this.handleKeyboard)
      }
    },

    // 自主探索相关方法
    autoExploreCancel() {
      this.autoExploreOpen = false
    },

    submitAutoExplore() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.$message.success('已开始自主探索...')
          this.autoExploreOpen = false
        }
      })
    },

    // 遥控探索相关方法
    remoteExploreCancel() {
      this.remoteExploreOpen = false
    },

    submitRemoteExplore() {
      this.$message.success('已开始遥控探索...')
      this.remoteExploreOpen = false
    },

    submitDownload() {
      console.log('Download types:', this.downLoadTypes)
      this.downloadOpen = false
      this.$message.success('下载已开始')
    },

    submitConstruct() {
      console.log('Construct mode:', this.constructModle)
      this.constructOpen = false
      this.$message.success('构建已开始')
    }
  }
};
</script>

<style lang="scss" scoped>
.map-list-container {
  min-height: 100vh;
  background: var(--color-bg-secondary);
  padding: var(--spacing-6);

  .toolbar-section {
    background: var(--color-bg-card);
    border-radius: 12px;
    padding: var(--spacing-5);
    margin-bottom: var(--spacing-6);
    box-shadow: 0 6px 18px rgba(2, 6, 23, 0.05);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-4);

    .toolbar-filters {
      display: flex;
      align-items: center;
      gap: var(--spacing-3);

      .search-input {
        width: 260px;
      }

      .status-filter,
      .sort-select {
        width: 140px;
      }

      .el-input,
      .el-select {
        ::v-deep .el-input__inner {
          border-radius: var(--radius-lg);
          transition: all var(--duration-200) var(--ease-out);

          &:focus {
            border-color: var(--color-primary);
            box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.15);
          }
        }
      }
    }

    .toolbar-actions {
      display: flex;
      align-items: center;
      gap: var(--spacing-3);

      .el-button {
        border-radius: var(--radius-base);
        font-weight: var(--font-weight-medium);
      }

      .view-toggle {
        margin-left: var(--spacing-2);

        .el-button {
          padding: 8px 12px;
          border-radius: var(--radius-base);

          &:first-child {
            border-top-right-radius: 0;
            border-bottom-right-radius: 0;
          }

          &:last-child {
            border-top-left-radius: 0;
            border-bottom-left-radius: 0;
          }
        }
      }
    }
  }



  .main-content {
    margin-bottom: var(--spacing-6);

    // 卡片网格
    .card-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
      gap: var(--spacing-6);

      &.compact {
        gap: var(--spacing-4);
        grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
      }

      @media (min-width: 1440px) {
        grid-template-columns: repeat(3, 1fr);

        &.compact {
          grid-template-columns: repeat(4, 1fr);
        }
      }
    }

    // 骨架屏
    .skeleton-card {
      background: var(--color-bg-card);
      border-radius: 12px;
      overflow: hidden;
      box-shadow: 0 6px 18px rgba(2, 6, 23, 0.05);

      .skeleton-thumb {
        height: 160px;
        background: linear-gradient(90deg, var(--color-bg-secondary) 25%, var(--color-bg-tertiary) 50%, var(--color-bg-secondary) 75%);
        background-size: 200% 100%;
        animation: skeleton-loading 1.5s infinite;
      }

      .skeleton-content {
        padding: 16px;

        .skeleton-title,
        .skeleton-remark,
        .skeleton-meta {
          background: linear-gradient(90deg, var(--color-bg-secondary) 25%, var(--color-bg-tertiary) 50%, var(--color-bg-secondary) 75%);
          background-size: 200% 100%;
          animation: skeleton-loading 1.5s infinite;
          border-radius: var(--radius-base);
        }

        .skeleton-title {
          height: 20px;
          margin-bottom: var(--spacing-3);
          width: 80%;
        }

        .skeleton-remark {
          height: 14px;
          margin-bottom: var(--spacing-2);
  width: 100%;
}

        .skeleton-meta {
          height: 12px;
          width: 60%;
        }
      }
    }

        // 表格容器
    .table-wrapper {
      background: var(--color-bg-card);
      border-radius: 12px;
      overflow: hidden;
      box-shadow: 0 6px 18px rgba(2, 6, 23, 0.05);
    }

    // 表格
    .map-table {
      ::v-deep .el-table__header {
        background: var(--color-bg-secondary);
      }

      ::v-deep .el-table__body {
        .el-table__row {
          &:hover {
            background: var(--color-bg-secondary);
          }
        }
      }

      ::v-deep .el-table__header th,
      ::v-deep .el-table__body td {
        padding: 10px 12px;
      }

      ::v-deep .el-table-column--selection .cell {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 10px 8px;
      }

      /* 表头"序号"不换行、居中 */
      ::v-deep .col-index-header .cell {
        white-space: nowrap;
        text-align: center;
        padding: 10px 8px;
      }

      /* 序号数字等宽、居中、颜色稍弱一点 */
      ::v-deep .col-index .cell {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 10px 8px;
        color: var(--color-text-secondary, #6b7280);
        font-variant-numeric: tabular-nums; /* 等宽数字 */
      }

      ::v-deep .cell {
        line-height: 20px;
        white-space: nowrap;
      }

      /* 避免某些主题对固定列的默认阴影/间距影响布局（现在已不固定，这里只是兜底） */
      ::v-deep .el-table__fixed-right {
        right: 0;
        box-shadow: none;
      }

      .table-name {
        display: flex;
        align-items: center;
        gap: var(--spacing-2);
      }

      .table-thumb {
        width: 40px;
        height: 24px;
        border-radius: var(--radius-base);
        overflow: hidden;
        background: var(--color-bg-secondary);
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 0 auto;

        img {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }

        i {
          color: var(--color-text-quaternary);
          font-size: var(--font-size-sm);
        }
      }

            .op-cell {
        display: flex;
        justify-content: flex-end;
        align-items: center;
        gap: 8px;
      }

      .op-link {
        display: inline-flex;
        align-items: center;
        color: var(--color-primary, #1d4ed8);
        text-decoration: none;
        font-size: var(--font-size-sm);
        transition: color 0.2s ease;

        &:hover {
          color: var(--color-primary-light);
          text-decoration: none;
        }
}

.el-dropdown-link {
        color: var(--color-primary);
  cursor: pointer;
        display: inline-flex;
        align-items: center;
        font-size: var(--font-size-sm);

        &:hover {
          color: var(--color-primary-light);
        }
      }

      .op-text {
        margin-left: 4px;
      }
      
      .xt-more .is-danger { 
        color: #e11d48; 
      }
      .xt-more .is-danger i { 
        color: #e11d48; 
      }
    }

    // 空态
    .empty-state {
      text-align: center;
      padding: var(--spacing-12) var(--spacing-6);
      background: var(--color-bg-card);
      border-radius: 12px;
      box-shadow: 0 6px 18px rgba(2, 6, 23, 0.05);

      .empty-illustration {
        margin-bottom: var(--spacing-6);

        i {
          font-size: 80px;
          color: var(--color-text-quaternary);
          opacity: 0.6;
        }
      }

      .empty-title {
        color: var(--color-text-primary);
        font-size: var(--font-size-xl);
        font-weight: var(--font-weight-semibold);
        margin: 0 0 var(--spacing-3) 0;
      }

      .empty-description {
        color: var(--color-text-secondary);
        font-size: var(--font-size-base);
        margin: 0 0 var(--spacing-6) 0;
        line-height: var(--line-height-relaxed);
      }

      .empty-actions {
        display: flex;
        justify-content: center;
        gap: var(--spacing-3);

        .el-button {
          border-radius: var(--radius-base);
          font-weight: var(--font-weight-medium);
        }
      }
    }
  }

  .pagination-section {
    background: var(--color-bg-card);
    border-radius: 12px;
    padding: var(--spacing-4) var(--spacing-5);
    box-shadow: 0 6px 18px rgba(2, 6, 23, 0.05);
    display: flex;
    align-items: center;
    justify-content: space-between;

    .density-toggle {
      .el-button-group {
        .el-button {
          padding: 4px 12px;
          font-size: var(--font-size-xs);
          border-radius: var(--radius-base);

          &:first-child {
            border-top-right-radius: 0;
            border-bottom-right-radius: 0;
          }

          &:last-child {
            border-top-left-radius: 0;
            border-bottom-left-radius: 0;
          }
        }
      }
    }

    .el-pagination {
      ::v-deep .el-pager {
        .number {
          border-radius: var(--radius-base);
          margin: 0 2px;
        }
      }

      ::v-deep .btn-prev,
      ::v-deep .btn-next {
        border-radius: var(--radius-base);
      }
    }
  }

    // 探索按钮样式
  .xt-btn {
    border-radius: var(--radius-base);
    font-weight: var(--font-weight-medium);
    transition: all var(--duration-200) var(--ease-out);

    &:disabled {
      opacity: 0.6;
      cursor: not-allowed;
    }

    &:hover:not(:disabled) {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    }
  }

  // 探索弹框样式
  .xt-explore-dialog ::v-deep .el-dialog {
    border-radius: 12px;
  }

  .xt-explore-dialog ::v-deep .el-dialog__body {
    padding: 18px 20px 6px;
  }

  /* 字体与间距 */
  .xt-title {
    display: flex;
    flex-direction: column;
    font-weight: 600;
    font-size: 16px;
  }

  .xt-subtitle {
  font-size: 12px;
    color: var(--text-secondary, #6b7280);
    font-weight: 400;
    margin-top: 4px;
  }

  .xt-form {
    background: white;
    border-radius: 12px;
    padding: 24px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);

    .el-form-item {
      margin-bottom: 24px;

      &:last-child {
        margin-bottom: 0;
      }

      .el-form-item__label {
        color: #333;
        font-size: 14px;
        font-weight: 500;
        line-height: 1.4;
      }
    }
  }

  .xt-field {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .xt-unit {
    color: #666;
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
  }

  .xt-hint {
    color: #888;
    font-size: 12px;
    margin-left: auto;
    white-space: nowrap;
  }

  .xt-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    padding: 16px 0;

    .el-button {
      padding: 10px 24px;
      border-radius: 8px;
      font-weight: 500;
      transition: all 0.2s ease;
      border: none;

      &.el-button--default {
        background: #f1f5f9;
        color: #64748b;
        
        &:hover {
          background: #e2e8f0;
          color: #475569;
          transform: translateY(-1px);
          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
        }
      }

      &.el-button--primary {
        background: linear-gradient(135deg, #10b981, #059669);
        color: white;
        
        &:hover {
          background: linear-gradient(135deg, #059669, #047857);
          transform: translateY(-1px);
          box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
        }
      }
    }
  }

    /* 输入框外层容器样式 */
  .xt-explore-dialog ::v-deep .el-input-number {
    width: 160px;
    border-radius: 24px;
    overflow: hidden;
    border: 1.5px solid #d1d5db;
    transition: all 0.2s ease;
    background: white;

    &:hover {
      border-color: #9ca3af;
    }

    &:focus-within,
    &.is-focus {
      border-color: #08C28E;
      box-shadow: 0 0 0 2px rgba(8, 194, 142, 0.2);
    }

    .el-input__inner {
      height: 40px;
      line-height: 40px;
      border: none;
      border-radius: 0;
      box-shadow: none;
      padding-right: 40px;
      font-size: 14px;
      background: transparent;

      &:focus {
        outline: none;
        border: none;
        box-shadow: none;
      }

      &::placeholder {
        color: #9ca3af;
        font-size: 13px;
      }
    }
  }

  /* 右侧加减按钮 */
  .xt-explore-dialog ::v-deep .el-input-number.is-controls-right .el-input-number__increase,
  .xt-explore-dialog ::v-deep .el-input-number.is-controls-right .el-input-number__decrease {
  right: 0;
    border: none;
    border-left: 1.5px solid #d1d5db;
    width: 35px;
    height: 20px;
    border-radius: 0;
    background: #f9fafb;
    color: #6b7280;
    transition: all 0.2s ease;

    &:hover {
      background: #f3f4f6;
      color: #374151;
    }
  }

  // 遥控探索确认弹框样式
  .xt-confirm-dialog {
    ::v-deep .el-dialog {
      border-radius: 12px;
    }

    .confirm-title {
      display: flex;
      align-items: center;
      font-size: 16px;
      font-weight: 600;
      color: #333;
    }

    .confirm-content {
      padding: 20px 0;
      
      p {
        margin: 0;
        font-size: 14px;
        line-height: 1.6;
        color: #666;
      }
    }

    ::v-deep .el-dialog__footer {
      padding: 16px 24px 24px;
      
      .el-button {
        padding: 8px 20px;
        border-radius: 6px;
        font-weight: 500;
        
        &.el-button--primary {
          background: linear-gradient(135deg, #10b981, #059669);
          border-color: #10b981;
          
          &:hover {
            background: linear-gradient(135deg, #059669, #047857);
            border-color: #059669;
          }
        }
      }
    }
  }

  // 保留的对话框样式
  ::v-deep .el-dialog__body {
    padding: var(--spacing-5);
  }
}

// 骨架屏动画
@keyframes skeleton-loading {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

// 暗色主题适配
html.dark {
  .map-list-container {
    .toolbar-section {
      background: var(--color-bg-tertiary);
      box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
    }



    .skeleton-card {
      background: var(--color-bg-tertiary);
      box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
    }

    .table-wrapper {
      background: var(--color-bg-tertiary);
      box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
    }

    .map-table {
      ::v-deep .el-table__header {
        background: var(--color-bg-quaternary);
      }

      ::v-deep .el-table__body {
        .el-table__row {
          &:hover {
            background: var(--color-bg-quaternary);
          }
        }
      }
    }

    .empty-state,
    .pagination-section {
      background: var(--color-bg-tertiary);
      box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
    }

    // 暗色主题下的探索弹框样式
    .xt-explore-dialog {
      ::v-deep .el-dialog {
        background: #1e293b;
        box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
      }

      ::v-deep .el-dialog__header {
        background: linear-gradient(135deg, #334155, #475569);
        border-bottom: 1px solid #475569;
      }

      ::v-deep .el-dialog__body,
      ::v-deep .el-dialog__footer {
        background: #1e293b;
      }

      ::v-deep .el-dialog__footer {
        border-top: 1px solid #475569;
      }

      .xt-title {
        color: #f1f5f9;
      }

      .xt-subtitle {
        color: #94a3b8;
      }

      .xt-form {
        background: #0f172a;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);

        .el-form-item__label {
          color: #e2e8f0 !important;
        }
      }

      .xt-unit {
        color: #cbd5e1;
      }

      .xt-hint {
        color: #94a3b8;
      }

      ::v-deep .el-input-number {
        background: #0f172a;
        border-color: #475569;

        &:hover {
          border-color: #64748b;
        }

        &:focus-within,
        &.is-focus {
          border-color: #08C28E;
          box-shadow: 0 0 0 2px rgba(8, 194, 142, 0.3);
        }

        .el-input__inner {
          background: transparent;
          color: #e2e8f0;

          &::placeholder {
            color: #64748b;
          }
        }
      }

      ::v-deep .el-input-number__increase,
      ::v-deep .el-input-number__decrease {
        background: #334155;
        border-color: #475569;
        color: #94a3b8;

        &:hover {
          background: #475569;
          color: #e2e8f0;
        }
      }

      .xt-footer {
        .el-button {
          &.el-button--default {
            background: #334155;
            color: #94a3b8;
            
            &:hover {
              background: #475569;
              color: #e2e8f0;
            }
          }

          &.el-button--primary {
            background: linear-gradient(135deg, #10b981, #059669);
            color: white;
            
            &:hover {
              background: linear-gradient(135deg, #059669, #047857);
            }
          }
        }
      }
    }

    // 暗色主题下的确认弹框样式
    .xt-confirm-dialog {
      ::v-deep .el-dialog {
        background: #1e293b;
      }

      .confirm-title {
        color: #f1f5f9;
      }

      .confirm-content p {
        color: #cbd5e1;
      }

      ::v-deep .el-dialog__footer {
        background: #1e293b;
        
        .el-button {
          &:not(.el-button--primary) {
            background: #334155;
            color: #94a3b8;
            border-color: #475569;
            
            &:hover {
              background: #475569;
              color: #e2e8f0;
            }
          }
        }
      }
    }
  }
}

// 响应式设计
@media (max-width: 1439px) {
  .map-list-container {
    .main-content {
      .card-grid {
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));

        &.compact {
          grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
        }
      }
    }
  }
}

@media (max-width: 768px) {
  .map-list-container {
    padding: var(--spacing-4);

    .toolbar-section {
      flex-direction: column;
      align-items: stretch;
      gap: var(--spacing-4);

      .toolbar-filters {
        flex-direction: column;
        align-items: stretch;

        .search-input,
        .status-filter,
        .sort-select {
          width: 100%;
        }
      }

      .toolbar-actions {
        justify-content: space-between;
        flex-wrap: wrap;

        .view-toggle {
          margin-left: 0;
          order: -1;
        }
      }
    }

    .main-content {
      .card-grid {
        grid-template-columns: 1fr;
        gap: var(--spacing-4);

        &.compact {
          gap: var(--spacing-3);
        }
      }
    }

    .pagination-section {
      flex-direction: column;
      gap: var(--spacing-3);

      .density-toggle {
        order: 1;
      }
    }
  }
}
</style>
