<template>
  <div class="page-container">
    <!-- 搜索表单 -->
    <div class="search-form">
      <el-form :model="searchForm" inline data-id="search-form">
        <el-form-item>
          <el-input
            v-model.trim="searchForm.lssId"
            :placeholder="t('LSS ID')"
            clearable
            data-id="search-keyword"
            @keyup.enter="handleSearch"
          />
        </el-form-item>
        <el-form-item>
          <el-input
            v-model.trim="searchForm.lssName"
            :placeholder="t('名称')"
            clearable
            data-id="search-keyword"
            @keyup.enter="handleSearch"
          />
        </el-form-item>
        <el-form-item>
          <el-select v-model="searchForm.status" :placeholder="t('心跳')" clearable data-id="search-enabled">
            <el-option :label="t('全部')" value="" />
            <el-option :label="t('活跃')" value="active" />
            <el-option :label="t('待机')" value="hold" />
            <el-option :label="t('离线')" value="dead" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :icon="Search" data-id="btn-search" @click="handleSearch">
            {{ t('查询') }}
          </el-button>
          <el-button :icon="RefreshRight" data-id="btn-reset" @click="handleReset">{{ t('重置') }}</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 数据表格 -->
    <div class="table-wrapper">
      <el-table
        ref="tableRef"
        v-loading="loading"
        :data="lssList"
        stripe
        size="default"
        data-id="lss-table"
        height="100%"
        @sort-change="handleSortChange"
      >
        <el-table-column prop="lssId" :label="t('LSS ID')" min-width="120" sortable="custom" show-overflow-tooltip />
        <el-table-column prop="lssName" :label="t('名称')" min-width="140" sortable="custom" show-overflow-tooltip />
        <el-table-column prop="address" :label="t('地址')" min-width="180" sortable="custom" show-overflow-tooltip />
        <el-table-column prop="ip" :label="t('IP')" min-width="180" sortable="custom" show-overflow-tooltip />
        <el-table-column :label="t('心跳')" width="220" align="center">
          <template #default="{ row }">
            {{
              row.status === 'active'
                ? t('活跃')
                : row.status === 'hold'
                ? t('待机')
                : row.status === 'dead'
                ? t('离线')
                : '-'
            }}
            |
            {{ formatTime(row.lastHeartbeatAt) }}
          </template>
        </el-table-column>
        <el-table-column :label="t('设备列表')" align="center">
          <template #default="{ row }">
            <el-button type="primary" link @click="handleEdit(row, 'camera')">
              <Icon icon="mdi:cctv" width="20" height="20" />
            </el-button>
          </template>
        </el-table-column>
        <el-table-column :label="t('ably')" align="center" fixed="right">
          <template #default="{ row }">
            {{ row.ablyClientId }}
          </template>
        </el-table-column>
        <el-table-column :label="t('操作')" align="center" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link @click="handleEdit(row, 'detail')">
              <Icon icon="mdi:note-edit-outline" width="20" height="20" />
            </el-button>
            <el-button type="primary" link @click="handleScanDevices(row)">
              <Icon icon="mdi:radar" width="20" height="20" />
            </el-button>
            <el-button type="danger" link @click="handleDelete(row)">
              <Icon icon="mdi:delete" width="20" height="20" />
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- LSS 详情抽屉 -->
    <el-drawer v-model="detailDrawerVisible" :title="t('LSS 节点详情')" direction="rtl" size="500px" destroy-on-close>
      <el-descriptions :column="1" border>
        <el-descriptions-item label="LSS ID">{{ currentLss?.lssId }}</el-descriptions-item>
        <el-descriptions-item label="名称">{{ currentLss?.lssName }}</el-descriptions-item>
        <el-descriptions-item label="地址">{{ currentLss?.address }}</el-descriptions-item>
        <el-descriptions-item label="机器 ID">{{ currentLss?.machineId || '-' }}</el-descriptions-item>
        <el-descriptions-item label="状态">
          <el-tag :type="getStatusTagType(currentLss?.status)" size="small">
            {{ formatStatus(currentLss?.status) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="任务数">
          {{ currentLss?.currentTasks }} / {{ currentLss?.maxTasks }}
        </el-descriptions-item>
        <el-descriptions-item label="FFmpeg 版本">{{ currentLss?.ffmpegVersion || '-' }}</el-descriptions-item>
        <el-descriptions-item label="系统信息">{{ currentLss?.systemInfo || '-' }}</el-descriptions-item>
        <el-descriptions-item label="启用状态">
          <el-tag :type="currentLss?.enabled ? 'success' : 'info'" size="small">
            {{ currentLss?.enabled ? '已启用' : '已禁用' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="创建时间">{{ formatTime(currentLss?.createdAt) }}</el-descriptions-item>
        <el-descriptions-item label="更新时间">{{ formatTime(currentLss?.updatedAt) }}</el-descriptions-item>
      </el-descriptions>
    </el-drawer>

    <!-- LSS 编辑抽屉 -->
    <el-drawer
      v-model="lssEditDrawerVisible"
      direction="rtl"
      :size="editDrawerSize"
      :with-header="false"
      destroy-on-close
      class="lss-edit-drawer"
    >
      <div class="drawer-content">
        <!-- 顶部 Tabs -->
        <el-tabs v-model="editActiveTab" class="drawer-tabs">
          <el-tab-pane :label="t('LSS详情')" name="detail" />
          <el-tab-pane :label="t('摄像头列表')" name="camera" />
          <el-tab-pane :label="t('推币机列表')" name="pusher" />
        </el-tabs>

        <div class="drawer-body">
          <!-- LSS 详情 Tab -->
          <div v-show="editActiveTab === 'detail'" class="lss-detail-form">
            <el-form ref="lssEditFormRef" :model="lssEditForm" label-width="80px" label-position="left">
              <el-form-item label="LSS ID:">
                <span class="form-value">{{ currentLss?.lssId }}</span>
              </el-form-item>
              <el-form-item :label="t('名称') + ':'" prop="lssName">
                <el-input v-model="lssEditForm.lssName" placeholder="请输入名称" style="width: 180px" />
              </el-form-item>
              <el-form-item :label="t('地址') + ':'" prop="address">
                <el-input v-model="lssEditForm.address" placeholder="请输入地址" />
              </el-form-item>
              <el-form-item :label="t('IP') + ':'">
                <span class="form-value">{{ currentLss?.ip }}</span>
              </el-form-item>
              <el-form-item :label="t('心跳') + ':'">
                <span class="heartbeat-status" :class="getHeartbeatClass(currentLss?.status)">
                  {{ formatHeartbeat(currentLss) }}
                  <span class="heartbeat-dot" :class="getHeartbeatClass(currentLss?.status)"></span>
                </span>
                <el-tooltip placement="right" effect="light">
                  <template #content>
                    <div class="heartbeat-tooltip">
                      <div class="tooltip-title">{{ t('心跳状态') }}:</div>
                      <div>{{ t('活跃') }} - {{ t('持续返回中，并且频繁') }}</div>
                      <div>{{ t('待机') }} - {{ t('五分钟内有返回') }}</div>
                      <div>{{ t('离线') }} - {{ t('五分钟内没有返回') }}</div>
                      <div class="tooltip-format">{{ t('表现形式为') }}:</div>
                      <div class="tooltip-example">{{ t('Status') }} [yy-mm-dd 00:00:00]</div>
                    </div>
                  </template>
                  <el-icon class="heartbeat-info-icon">
                    <QuestionFilled />
                  </el-icon>
                </el-tooltip>
              </el-form-item>
              <el-form-item :label="t('ably') + ':'" prop="ably">
                <div class="textarea-wrapper">
                  <el-input
                    disabled
                    type="textarea"
                    :rows="8"
                    v-model="lssEditForm.ably"
                    :placeholder="t('请输入ably信息')"
                    maxlength="1000"
                    show-word-limit
                  />
                </div>
              </el-form-item>
            </el-form>
          </div>

          <!-- 摄像头列表 Tab -->
          <div v-show="editActiveTab === 'camera'" v-loading="cameraLoading" class="tab-content-wrapper">
            <div class="camera-toolbar">
              <el-form :model="cameraSearchForm" inline>
                <el-form-item>
                  <el-input
                    v-model.trim="cameraSearchForm.cameraId"
                    :placeholder="t('设备ID')"
                    clearable
                    style="width: 200px"
                    @keyup.enter="handleCameraSearch"
                  />
                </el-form-item>
                <el-form-item>
                  <el-input
                    v-model.trim="cameraSearchForm.cameraName"
                    :placeholder="t('名称')"
                    clearable
                    style="width: 200px"
                    @keyup.enter="handleCameraSearch"
                  />
                </el-form-item>
                <el-form-item>
                  <el-select v-model="cameraSearchForm.status" :placeholder="t('状态')" clearable style="width: 120px">
                    <el-option :label="t('全部')" value="" />
                    <el-option :label="t('在线')" value="ative" />
                    <el-option :label="t('待机')" value="hold" />
                    <el-option :label="t('离线')" value="dead" />
                  </el-select>
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" :icon="Search" @click="handleCameraSearch">{{ t('查询') }}</el-button>
                  <el-button :icon="RefreshRight" @click="handleCameraReset">{{ t('重置') }}</el-button>
                  <el-button type="primary" :icon="Plus" @click="handleAddCamera">{{ t('新增') }}</el-button>
                </el-form-item>
              </el-form>
            </div>
            <el-empty v-if="!cameraLoading && cameraList.length === 0" :description="t('暂无关联设备')" />
            <el-table v-else :data="cameraList" stripe size="small" border>
              <el-table-column prop="cameraId" :label="t('设备ID')" min-width="100" show-overflow-tooltip />
              <el-table-column prop="cameraName" :label="t('名称')" min-width="100" show-overflow-tooltip />
              <el-table-column :label="t('状态(心跳)')" min-width="140">
                <template #default="{ row }">
                  <span :class="['status-text', row.status === 'active' ? 'status-active' : 'status-dead']">
                    {{ formatCameraStatus(row) }}
                  </span>
                </template>
              </el-table-column>
              <el-table-column :label="t('参数配置')" min-width="80" align="center">
                <template #default="{ row }">
                  <el-button type="primary" link @click="handleViewConfig(row)">{{ t('查看') }}</el-button>
                </template>
              </el-table-column>
              <el-table-column :label="t('运行参数')" min-width="80" align="center">
                <template #default="{ row }">
                  <el-button type="primary" link @click="handleViewRunParams(row)">{{ t('查看') }}</el-button>
                </template>
              </el-table-column>
              <el-table-column prop="brand" :label="t('厂商')" min-width="90">
                <template #default="{ row }">
                  {{ formatBrand(row.vendorName) }}
                </template>
              </el-table-column>
              <el-table-column prop="model" :label="t('型号')" min-width="130" show-overflow-tooltip />
              <el-table-column :label="t('添加时间')" min-width="140">
                <template #default="{ row }">
                  {{ formatTime(row.createdAt) }}
                </template>
              </el-table-column>
              <el-table-column :label="t('设备控制')" min-width="100" align="center" fixed="right">
                <template #default="{ row }">
                  <el-button type="primary" link @click="handleEditCamera(row)">
                    <Icon icon="mdi:note-edit-outline" width="20" height="20" />
                  </el-button>
                  <el-button type="danger" link @click="handleDeleteCamera(row)">
                    <Icon icon="mdi:delete" width="20" height="20" />
                  </el-button>
                  <el-button
                    :tooltip="t('查看Cloudflare Stream')"
                    link
                    :class="['crosshairs-btn', { active: row.streamSn }]"
                    @click="handleViewCamera(row)"
                  >
                    <Icon icon="mdi:crosshairs" width="20" height="20" />
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
            <div v-if="cameraList.length > 0" class="camera-count">
              {{ t('共') }} {{ cameraList.length }} {{ t('个设备') }}
            </div>
          </div>

          <!-- 推币机列表 Tab -->
          <div v-show="editActiveTab === 'pusher'" class="tab-content">
            <el-empty :description="t('暂无推币机数据')" />
          </div>
        </div>

        <div class="drawer-footer">
          <el-button @click="lssEditDrawerVisible = false">{{ t('取消') }}</el-button>
          <el-button type="primary" :loading="lssUpdating" @click="handleUpdateLss">{{ t('更新') }}</el-button>
        </div>
      </div>
    </el-drawer>

    <!-- 设备列表抽屉 -->
    <el-drawer
      v-model="cameraDrawerVisible"
      :title="`${t('设备列表')} - ${currentLss?.lssName || ''}`"
      direction="rtl"
      size="80%"
      destroy-on-close
      class="device-drawer"
    >
      <el-tabs v-model="deviceActiveTab" class="device-tabs">
        <el-tab-pane :label="t('摄像头列表')" name="camera">
          <div v-loading="cameraLoading" class="tab-content-wrapper">
            <div class="camera-toolbar">
              <el-form :model="cameraSearchForm" inline>
                <el-form-item>
                  <el-input
                    v-model.trim="cameraSearchForm.keyword"
                    :placeholder="t('IP / 设备ID / 名称')"
                    clearable
                    style="width: 200px"
                    @keyup.enter="handleCameraSearch"
                  />
                </el-form-item>
                <el-form-item>
                  <el-select v-model="cameraSearchForm.status" :placeholder="t('状态')" clearable style="width: 120px">
                    <el-option :label="t('全部')" value="" />
                    <el-option :label="t('在线')" value="ONLINE" />
                    <el-option :label="t('离线')" value="OFFLINE" />
                  </el-select>
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" :icon="Search" @click="handleCameraSearch">{{ t('查询') }}</el-button>
                  <el-button :icon="RefreshRight" @click="handleCameraReset">{{ t('重置') }}</el-button>
                </el-form-item>
              </el-form>
              <el-button type="primary" :icon="Plus" @click="handleAddCamera">{{ t('新增') }}</el-button>
            </div>
            <el-empty v-if="!cameraLoading && cameraList.length === 0" :description="t('暂无关联设备')" />
            <el-table v-else :data="cameraList" stripe size="small" border>
              <!-- <el-table-column prop="ip" label="本地IP" min-width="110" /> -->
              <el-table-column prop="cameraId" :label="t('设备ID')" min-width="100" show-overflow-tooltip />
              <el-table-column prop="cameraName" :label="t('名称')" min-width="100" show-overflow-tooltip />
              <el-table-column :label="t('状态(心跳)')" min-width="140">
                <template #default="{ row }">
                  <span :class="['status-text', row.status === 'active' ? 'status-active' : 'status-dead']">
                    {{ formatCameraStatus(row) }}
                  </span>
                </template>
              </el-table-column>
              <el-table-column :label="t('参数配置')" min-width="80" align="center">
                <template #default="{ row }">
                  <el-button type="primary" link @click="handleViewConfig(row)">查看</el-button>
                </template>
              </el-table-column>
              <el-table-column :label="t('运行参数')" min-width="80" align="center">
                <template #default="{ row }">
                  <el-button type="primary" link @click="handleViewRunParams(row)">查看</el-button>
                </template>
              </el-table-column>
              <el-table-column prop="brand" :label="t('厂商')" min-width="90">
                <template #default="{ row }">
                  {{ formatBrand(row.brand) }}
                </template>
              </el-table-column>
              <el-table-column prop="model" :label="t('型号')" min-width="130" show-overflow-tooltip />
              <el-table-column :label="t('添加时间')" min-width="140">
                <template #default="{ row }">
                  {{ formatTime(row.createdAt) }}
                </template>
              </el-table-column>
              <el-table-column :label="t('设备控制')" min-width="100" align="center" fixed="right">
                <template #default="{ row }">
                  <el-button type="primary" link :icon="Edit" @click="handleEditCamera(row)" />
                  <el-button type="danger" link :icon="Delete" @click="handleDeleteCamera(row)" />
                  <el-button link :class="['crosshairs-btn', { active: !row.streamSn }]" @click="handleViewCamera(row)">
                    <Icon icon="mdi:crosshairs" />
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
            <div v-if="cameraList.length > 0" class="camera-count">共 {{ cameraList.length }} 个设备</div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="推币机列表" name="pusher">
          <div class="tab-content-wrapper">
            <div class="camera-toolbar">
              <el-form inline>
                <el-form-item>
                  <el-input placeholder="设备ID / 名称" clearable style="width: 200px" />
                </el-form-item>
                <el-form-item>
                  <el-select placeholder="状态" clearable style="width: 120px">
                    <el-option label="全部" value="" />
                    <el-option label="在线" value="ONLINE" />
                    <el-option label="离线" value="OFFLINE" />
                  </el-select>
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" :icon="Search">查询</el-button>
                  <el-button :icon="RefreshRight">重置</el-button>
                </el-form-item>
              </el-form>
              <el-button type="primary" :icon="Plus">{{ t('新增') }}</el-button>
            </div>
            <el-empty description="暂无推币机数据" />
          </div>
        </el-tab-pane>
        <el-tab-pane label="其他设备" name="other">
          <div class="tab-content-wrapper">
            <div class="camera-toolbar">
              <el-form inline>
                <el-form-item>
                  <el-input placeholder="设备ID / 名称" clearable style="width: 200px" />
                </el-form-item>
                <el-form-item>
                  <el-select placeholder="状态" clearable style="width: 120px">
                    <el-option label="全部" value="" />
                    <el-option label="在线" value="ONLINE" />
                    <el-option label="离线" value="OFFLINE" />
                  </el-select>
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" :icon="Search">查询</el-button>
                  <el-button :icon="RefreshRight">重置</el-button>
                </el-form-item>
              </el-form>
              <el-button type="primary" :icon="Plus">{{ t('新增') }}</el-button>
            </div>
            <el-empty description="暂无其他设备数据" />
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-drawer>

    <!-- 摄像头编辑抽屉 -->
    <el-drawer
      v-model="cameraDialogVisible"
      :title="isEditCamera ? '编辑摄像头' : '添加摄像头'"
      direction="rtl"
      size="500px"
      :close-on-click-modal="false"
      destroy-on-close
      class="camera-edit-drawer"
    >
      <el-form ref="cameraFormRef" :model="cameraForm" :rules="cameraRules" label-width="100px">
        <!-- <el-form-item label="IP 地址" prop="ip">
          <el-input v-model="cameraForm.ip" :disabled="isEditCamera" placeholder="请输入 IP 地址" />
        </el-form-item> -->
        <el-form-item label="设备ID" prop="cameraId">
          <el-input v-model="cameraForm.cameraId" :disabled="isEditCamera" placeholder="请输入设备ID" />
        </el-form-item>
        <el-form-item label="设备名称" prop="cameraName">
          <el-input v-model="cameraForm.cameraName" placeholder="请输入设备名称" />
        </el-form-item>
        <el-form-item label="厂商" prop="vendorName">
          <el-select
            v-model="cameraForm.vendorName"
            placeholder="请选择摄像头"
            style="width: 100%"
            filterable
            @change="handleVendorSelect"
          >
            <el-option
              v-for="vendor in [
                { id: 'hikvision', name: '海康威视' },
                { id: 'dahua', name: '大华' },
                { id: 'uniview', name: '宇视' },
                { id: 'other', name: '其他' }
              ]"
              :key="vendor.id"
              :label="vendor.name"
              :value="vendor.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="型号" prop="model">
          <el-input v-model="cameraForm.model" placeholder="请输入型号" />
        </el-form-item>
        <!-- <el-form-item label="摄像头型号" prop="cameraId">
          <el-select v-model="cameraForm.selectedVendorId" placeholder="请选择摄像头" style="width: 100%" filterable
            @change="handleVendorSelect">
            <el-option v-for="vendor in cameraVendorList" :key="vendor.id" :label="vendor.name" :value="vendor.id" />
          </el-select>
        </el-form-item> -->
        <!-- <el-form-item label="名称" prop="name">
          <el-input v-model="cameraForm.name" placeholder="请输入名称" />
        </el-form-item> -->
        <!-- <el-form-item label="端口" prop="port">
          <el-input-number v-model="cameraForm.port" :min="1" :max="65535" style="width: 100%" />
        </el-form-item> -->
        <!-- <el-form-item label="用户名" prop="username">
          <el-input v-model="cameraForm.username" placeholder="请输入用户名" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="cameraForm.password" type="password" show-password placeholder="请输入密码" />
        </el-form-item> -->
        <el-form-item label="参数配置">
          <CodeEditor
            v-model="cameraForm.paramConfig"
            language="json"
            height="200px"
            placeholder="请输入参数配置 (JSON)"
          />
        </el-form-item>
        <br />
        <el-form-item label="设备运行参数">
          <CodeEditor
            v-model="cameraForm.runtimeParams"
            language="json"
            height="200px"
            placeholder="设备运行参数 (JSON)"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="drawer-footer">
          <el-button @click="cameraDialogVisible = false">{{ t('取消') }}</el-button>
          <el-button type="primary" :loading="cameraSubmitting" @click="handleSubmitCamera">{{ t('确定') }}</el-button>
        </div>
      </template>
    </el-drawer>

    <!-- 参数配置/运行参数抽屉 -->
    <el-drawer
      v-model="paramsDialogVisible"
      :title="paramsDialogTitle"
      direction="rtl"
      size="500px"
      :close-on-click-modal="false"
      destroy-on-close
      class="params-drawer"
    >
      <CodeEditor
        v-model="paramsContent"
        language="json"
        height="500px"
        :placeholder="paramsDialogType === 'config' ? '请输入参数配置（JSON 格式）' : '请输入运行参数（JSON 格式）'"
      />
      <template #footer>
        <div class="drawer-footer">
          <el-button @click="paramsDialogVisible = false">{{ t('取消') }}</el-button>
          <el-button type="primary" :loading="paramsSubmitting" @click="handleSaveParams">{{ t('更新') }}</el-button>
        </div>
      </template>
    </el-drawer>

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

<script setup lang="ts">
import { ref, reactive, onMounted, computed, watch } from 'vue'
import { Search, RefreshRight, Delete, View, Edit, VideoCamera, Plus, QuestionFilled } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { listLssNodes, deleteLssNode, setLssNodeEnabled, updateLssNode } from '@/api/lss'
import { adminListCameras, adminAddCamera, adminUpdateCamera, adminDeleteCamera, adminGetCamera } from '@/api/camera'
import { listCameraVendors } from '@/api/camera-vendor'
import { Icon } from '@iconify/vue'
import CodeEditor from '@/components/CodeEditor.vue'
import type {
  LssNodeDTO,
  LssNodeStatus,
  LssNodeListRequest,
  LssHeartbeatStatus,
  CameraInfoDTO,
  CameraAddRequest,
  CameraUpdateRequest,
  CameraVendorDTO,
  IAbly,
  CameraHeartbeatStatus
} from '@/types'
import type { FormInstance, FormRules } from 'element-plus'
import dayjs from 'dayjs'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
const { t } = useI18n({ useScope: 'global' })

const router = useRouter()

// 格式化状态显示
function formatStatus(status: LssNodeStatus | undefined): string {
  switch (status) {
    case 'active':
      return '在线'
    case 'hold':
      return '离线'
    case 'dead':
      return '离线'
    default:
      return '离线'
  }
}

// 获取状态标签类型
function getStatusTagType(status: LssNodeStatus | undefined): 'success' | 'danger' | 'warning' | 'info' {
  switch (status) {
    case 'ONLINE':
      return 'success'
    case 'OFFLINE':
      return 'danger'
    case 'BUSY':
      return 'warning'
    case 'MAINTENANCE':
      return 'info'
    default:
      return 'info'
  }
}

// 格式化时间
function formatTime(time: string | undefined): string {
  if (!time) return '-'
  return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
}

// 格式化摄像头状态
function formatCameraStatus(row: CameraInfoDTO): string {
  if (row.status === 'active') {
    // 大约5秒钟
    return `active [${formatTime(row.updatedAt)}]`
  } else if (row.status === 'hold') {
    // 大约5分钟没有返回
    return `hold [${formatTime(row.updatedAt)}]`
  } else {
    // 大约10分钟没有返回
    return `dead (离线)`
  }
}

// 当前激活的摄像头 ID
const activeCameraId = ref<number | null>(null)

function handleViewCamera(row: CameraInfoDTO) {
  // 切换激活状态
  router.push(`/live-stream?cameraId=${row.cameraId}`)
}

// 格式化品牌
function formatBrand(brand: string | undefined): string {
  const brandMap: Record<string, string> = {
    hikvision: 'HIKVISION',
    dahua: 'DAHUA',
    uniview: 'UNIVIEW',
    other: '其他'
  }
  return brand ? brandMap[brand] || brand.toUpperCase() : '-'
}

// 验证 JSON 格式
function isValidJson(str: string): boolean {
  if (!str || !str.trim()) return true // 空值视为有效
  try {
    JSON.parse(str)
    return true
  } catch {
    return false
  }
}

// 格式化心跳状态
function formatHeartbeat(lss: LssNodeDTO | null | undefined): string {
  if (!lss) return '-'
  const status = lss.heartbeat || (lss.status === 'active' ? 'active' : lss.status === 'hold' ? 'hold' : 'dead')
  const time = lss.heartbeatTime || lss.updatedAt
  if (status === 'active') {
    return `active [${formatTime(time)}]`
  } else if (status === 'hold') {
    return `hold [${formatTime(time)}]`
  } else {
    return `dead (离线)`
  }
}

// 获取心跳状态样式类
function getHeartbeatClass(status: LssHeartbeatStatus | undefined): string {
  switch (status) {
    case 'active':
      return 'status-active'
    case 'hold':
      return 'status-hold'
    case 'dead':
    default:
      return 'status-dead'
  }
}

// 查看参数配置
function handleViewConfig(row: CameraInfoDTO) {
  paramsCamera.value = row
  paramsDialogType.value = 'config'
  paramsDialogTitle.value = `参数配置 - ${row.cameraName}`
  paramsContent.value = row.paramConfig || ''
  paramsDialogVisible.value = true
}

// 查看运行参数
function handleViewRunParams(row: CameraInfoDTO) {
  paramsCamera.value = row
  paramsDialogType.value = 'run'
  paramsDialogTitle.value = `运行参数 - ${row.cameraName}`
  paramsContent.value = row.runtimeParams || ''
  paramsDialogVisible.value = true
}

// 保存参数配置/运行参数
async function handleSaveParams() {
  if (!paramsCamera.value) return

  paramsSubmitting.value = true
  try {
    const data: CameraUpdateRequest = {
      id: paramsCamera.value.id
    }
    if (paramsDialogType.value === 'config') {
      data.paramConfig = paramsContent.value
    } else {
      data.runtimeParams = paramsContent.value
    }

    const res = await adminUpdateCamera(data)
    if (res.success) {
      ElMessage.success('保存成功')
      paramsDialogVisible.value = false
      // 更新本地数据
      if (paramsDialogType.value === 'config') {
        paramsCamera.value.configParams = paramsContent.value
      } else {
        paramsCamera.value.runParams = paramsContent.value
      }
    } else {
      ElMessage.error(res.errMessage || '保存失败')
    }
  } catch (error) {
    console.error('保存参数失败', error)
    ElMessage.error('保存失败')
  } finally {
    paramsSubmitting.value = false
  }
}

const loading = ref(false)
const lssList = ref<(LssNodeDTO & { _switching?: boolean })[]>([])
const tableRef = ref()

// 抽屉状态
const detailDrawerVisible = ref(false)
const currentLss = ref<LssNodeDTO | null>(null)

// LSS 编辑抽屉状态
const lssEditDrawerVisible = ref(false)
const lssUpdating = ref(false)
const editActiveTab = ref('detail')
const lssEditFormRef = ref<FormInstance>()
const lssEditForm = reactive({
  lssName: '',
  address: '',
  ip: '',
  ably: ''
})

// 根据当前 tab 计算抽屉宽度
const editDrawerSize = computed(() => {
  return editActiveTab.value === 'detail' ? '500px' : '80%'
})

// 设备列表抽屉状态
const cameraDrawerVisible = ref(false)
const cameraLoading = ref(false)
const deviceActiveTab = ref('camera')
const cameraList = ref<CameraInfoDTO[]>([])
const cameraVendorList = ref<CameraVendorDTO[]>([])

// 摄像头搜索表单
const cameraSearchForm = reactive({
  cameraId: '',
  cameraName: '',
  status: '' as CameraHeartbeatStatus | ''
})

// 摄像头编辑弹窗状态
const cameraDialogVisible = ref(false)
const cameraFormRef = ref<FormInstance>()
const isEditCamera = ref(false)
const cameraSubmitting = ref(false)
const currentCamera = ref<CameraInfoDTO | null>(null)

// 参数配置/运行参数弹窗状态
const paramsDialogVisible = ref(false)
const paramsDialogTitle = ref('')
const paramsDialogType = ref<'config' | 'run'>('config')
const paramsContent = ref('')
const paramsSubmitting = ref(false)
const paramsCamera = ref<CameraInfoDTO | null>(null)

// 摄像头表单
const cameraForm = reactive({
  selectedVendorId: null as number | null,
  cameraId: '',
  cameraName: '',
  vendorName: '',
  model: '',
  ip: '',
  port: 80,
  username: '',
  password: '',
  brand: '',
  capability: 'switch_only' as 'switch_only' | 'ptz_enabled',
  rtspUrl: '',
  channelNo: '',
  remark: '',
  enabled: true,
  paramConfig: '',
  runtimeParams: ''
})

// 摄像头表单验证规则（动态）
const cameraRules = computed<FormRules>(() => ({}))

// 排序状态
const sortState = reactive<{
  sortBy: string
  sortDir: 'ASC' | 'DESC' | undefined
}>({
  sortBy: '',
  sortDir: undefined
})

// 搜索表单
const searchForm = reactive<{
  lssId: string
  lssName: string
  status: LssNodeStatus | ''
}>({
  lssId: '',
  lssName: '',
  status: ''
})

// 分页相关
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(0)

async function getList() {
  loading.value = true
  try {
    const params: LssNodeListRequest = {
      page: currentPage.value,
      size: pageSize.value
    }

    if (searchForm.lssId) {
      params.lssId = searchForm.lssId
    }

    if (searchForm.lssName) {
      params.lssName = searchForm.lssName
    }

    if (searchForm.status) {
      params.status = searchForm.status
    }

    if (sortState.sortBy) {
      params.sortBy = sortState.sortBy
      params.sortDir = sortState.sortDir
    }

    const res = await listLssNodes(params)
    if (res.success && res.data) {
      lssList.value = res.data.list
      total.value = res.data.total || 0
    } else {
      ElMessage.error(res.errMessage || '获取列表失败')
    }
  } catch (error) {
    console.error('获取 LSS 列表失败', error)
    ElMessage.error('获取列表失败')
  } finally {
    loading.value = false
  }
}

function handleSearch() {
  currentPage.value = 1
  getList()
}

function handleReset() {
  searchForm.lssId = ''
  searchForm.lssName = ''
  searchForm.status = ''
  currentPage.value = 1
  getList()
}

function handleSortChange({ prop, order }: { prop: string; order: 'ascending' | 'descending' | null }) {
  sortState.sortBy = prop || ''
  sortState.sortDir = order === 'ascending' ? 'ASC' : order === 'descending' ? 'DESC' : undefined
  getList()
}

function handleSizeChange(val: number) {
  pageSize.value = val
  currentPage.value = 1
  getList()
}

function handleCurrentChange(val: number) {
  currentPage.value = val
  getList()
}

function handleViewDetail(row: LssNodeDTO) {
  currentLss.value = row
  detailDrawerVisible.value = true
}

function handleScanDevices(row: LssNodeDTO) {
  console.log(row)
}

function handleEdit(row: LssNodeDTO, tab: 'detail' | 'camera' | 'pusher') {
  currentLss.value = row
  lssEditForm.lssName = row.lssName || ''
  lssEditForm.address = row.address || ''
  lssEditForm.ably = JSON.stringify(row.ably)
  editActiveTab.value = tab
  lssEditDrawerVisible.value = true
  // 每次打开抽屉都刷新摄像头列表
  cameraSearchForm.cameraId = ''
  cameraSearchForm.cameraName = ''
  cameraSearchForm.status = ''
  loadCameraList()
}

async function handleCameraList(row: LssNodeDTO) {
  currentLss.value = row
  cameraSearchForm.cameraId = ''
  cameraSearchForm.cameraName = ''
  cameraSearchForm.status = ''
  deviceActiveTab.value = 'camera'
  cameraDrawerVisible.value = true
  await loadCameraList()
}

async function handleUpdateLss() {
  if (!currentLss.value) return

  lssUpdating.value = true
  try {
    const res = await updateLssNode({
      lssId: currentLss.value.lssId,
      lssName: lssEditForm.lssName,
      address: lssEditForm.address,
      ablyInfo: lssEditForm.ably
    })
    if (res.success) {
      ElMessage.success('更新成功')
      lssEditDrawerVisible.value = false
      getList()
    } else {
      ElMessage.error(res.errMessage || '更新失败')
    }
  } catch (error) {
    console.error('更新 LSS 失败', error)
    ElMessage.error('更新失败')
  } finally {
    lssUpdating.value = false
  }
}

async function loadCameraList() {
  if (!currentLss.value) return
  cameraLoading.value = true
  cameraList.value = []

  try {
    const params: any = { lssId: currentLss.value.lssId }

    if (cameraSearchForm.cameraId) {
      params.cameraId = cameraSearchForm.cameraId
    }

    if (cameraSearchForm.cameraName) {
      params.cameraName = cameraSearchForm.cameraName
    }

    if (cameraSearchForm.status) {
      params.status = cameraSearchForm.status
    }

    const res = await adminListCameras(params)
    if (res.success && res.data) {
      cameraList.value = res.data.list || []
    } else {
      ElMessage.error(res.errMessage || '获取摄像头列表失败')
    }
  } catch (error) {
    console.error('获取摄像头列表失败', error)
    ElMessage.error('获取摄像头列表失败')
  } finally {
    cameraLoading.value = false
  }
}

function handleCameraSearch() {
  loadCameraList()
}

function handleCameraReset() {
  cameraSearchForm.cameraId = ''
  cameraSearchForm.cameraName = ''
  cameraSearchForm.status = ''
  loadCameraList()
}

function resetCameraForm() {
  cameraForm.selectedVendorId = null
  cameraForm.cameraId = ''
  cameraForm.cameraName = ''
  cameraForm.vendorName = ''
  cameraForm.model = ''
  cameraForm.ip = ''
  cameraForm.port = 80
  cameraForm.username = ''
  cameraForm.password = ''
  cameraForm.brand = ''
  cameraForm.capability = 'switch_only'
  cameraForm.rtspUrl = ''
  cameraForm.model = ''
  cameraForm.channelNo = ''
  cameraForm.remark = ''
  cameraForm.enabled = true
  cameraForm.paramConfig = ''
  cameraForm.runtimeParams = ''
  cameraFormRef.value?.clearValidate()
}

async function loadCameraVendorList() {
  try {
    const res = await listCameraVendors({ enabled: true })
    if (res.success && res.data) {
      cameraVendorList.value = res.data.list || []
    }
  } catch (error) {
    console.error('获取厂商列表失败', error)
  }
}

function handleVendorSelect(vendorId: number) {
  const vendor = cameraVendorList.value.find((v) => v.id === vendorId)
  if (vendor) {
    cameraForm.brand = vendor.code
    // 设置厂商默认端口
    if (vendor.defaultPort) {
      cameraForm.port = vendor.defaultPort
    }
    // 根据厂商设置默认能力
    cameraForm.capability = vendor.supportPtz ? 'ptz_enabled' : 'switch_only'
  }
}

async function handleAddCamera() {
  isEditCamera.value = false
  currentCamera.value = null
  resetCameraForm()
  await loadCameraVendorList()
  cameraDialogVisible.value = true
}

async function handleEditCamera(row: CameraInfoDTO) {
  isEditCamera.value = true

  try {
    // 通过 API 获取摄像头详情
    const res = await adminGetCamera(row.id)
    if (!res.success || !res.data) {
      ElMessage.error(res.errMessage || '获取摄像头详情失败')
      return
    }

    const camera = res.data
    currentCamera.value = camera
    cameraForm.selectedVendorId = null
    cameraForm.cameraId = camera.cameraId
    cameraForm.cameraName = camera.cameraName
    cameraForm.vendorName = camera.vendorName || ''
    cameraForm.model = camera.model || ''
    cameraForm.ip = camera.ip
    cameraForm.port = camera.port || 80
    cameraForm.username = camera.username || ''
    cameraForm.password = ''
    cameraForm.brand = camera.brand || ''
    cameraForm.capability = camera.capability || 'switch_only'
    cameraForm.rtspUrl = camera.rtspUrl || ''
    cameraForm.model = camera.model || ''
    cameraForm.channelNo = camera.channelNo || ''
    cameraForm.remark = camera.remark || ''
    cameraForm.enabled = camera.enabled
    cameraForm.paramConfig = camera.paramConfig || ''
    cameraForm.runtimeParams = camera.runtimeParams || ''

    await loadCameraVendorList()
    cameraDialogVisible.value = true
  } catch (error) {
    console.error('获取摄像头详情失败', error)
    ElMessage.error('获取摄像头详情失败')
  }
}

async function handleSubmitCamera() {
  if (!cameraFormRef.value) return

  await cameraFormRef.value.validate(async (valid) => {
    if (!valid) return

    // 验证 JSON 格式
    if (!isValidJson(cameraForm.paramConfig)) {
      ElMessage.error('参数配置格式错误，请输入有效的 JSON')
      return
    }
    if (!isValidJson(cameraForm.runtimeParams)) {
      ElMessage.error('设备运行参数格式错误，请输入有效的 JSON')
      return
    }

    cameraSubmitting.value = true
    try {
      if (isEditCamera.value) {
        // 编辑模式：更新摄像头信息
        if (!currentCamera.value) {
          ElMessage.error('摄像头信息错误')
          return
        }
        const data: CameraUpdateRequest = {
          id: currentCamera.value.id,
          cameraName: cameraForm.cameraName,
          vendorName: cameraForm.vendorName,
          model: cameraForm.model,
          port: cameraForm.port,
          username: cameraForm.username,
          brand: cameraForm.brand,
          capability: cameraForm.capability,
          lssId: currentLss.value?.lssId,
          rtspUrl: cameraForm.rtspUrl,
          channelNo: cameraForm.channelNo,
          remark: cameraForm.remark,
          enabled: cameraForm.enabled,
          paramConfig: cameraForm.paramConfig,
          runtimeParams: cameraForm.runtimeParams
        }
        if (cameraForm.password) {
          data.password = cameraForm.password
        }
        const res = await adminUpdateCamera(data)
        if (res.success) {
          ElMessage.success('更新成功')
          cameraDialogVisible.value = false
          loadCameraList()
        } else {
          ElMessage.error(res.errMessage || '更新失败')
        }
      } else {
        // 新增模式：创建摄像头并绑定到当前 LSS
        const data: CameraAddRequest = {
          cameraId: cameraForm.cameraId,
          cameraName: cameraForm.cameraName,
          vendorName: cameraForm.vendorName,
          model: cameraForm.model,
          paramConfig: cameraForm.paramConfig,
          runtimeParams: cameraForm.runtimeParams,
          lssId: currentLss.value?.lssId
        }
        const res = await adminAddCamera(data)
        if (res.success) {
          ElMessage.success('添加成功')
          cameraDialogVisible.value = false
          loadCameraList()
        } else {
          ElMessage.error(res.errMessage || '添加失败')
        }
      }
    } catch (error) {
      console.error('保存摄像头失败', error)
      ElMessage.error('操作失败')
    } finally {
      cameraSubmitting.value = false
    }
  })
}

async function handleDeleteCamera(row: CameraInfoDTO) {
  try {
    await ElMessageBox.confirm(`确定要删除摄像头 "${row.name}" 吗？`, '提示', {
      type: 'warning'
    })
    const res = await adminDeleteCamera(row.id)
    if (res.success) {
      ElMessage.success('删除成功')
      loadCameraList()
    } else {
      ElMessage.error(res.errMessage || '删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除摄像头失败', error)
      ElMessage.error('删除失败')
    }
  }
}

async function handleToggleEnabled(row: LssNodeDTO & { _switching?: boolean }, enabled: boolean) {
  row._switching = true
  try {
    const res = await setLssNodeEnabled(row.lssId, enabled)
    if (res.success) {
      ElMessage.success(enabled ? '已启用' : '已禁用')
    } else {
      // 恢复原状态
      row.enabled = !enabled
      ElMessage.error(res.errMessage || '操作失败')
    }
  } catch (error) {
    row.enabled = !enabled
    console.error('切换启用状态失败', error)
    ElMessage.error('操作失败')
  } finally {
    row._switching = false
  }
}

async function handleDelete(row: LssNodeDTO) {
  try {
    await ElMessageBox.confirm(`确定要删除 LSS 节点 "${row.lssName}" 吗？`, '提示', {
      type: 'warning'
    })
    const res = await deleteLssNode(row.lssId)
    if (res.success) {
      ElMessage.success('删除成功')
      getList()
    } else {
      ElMessage.error(res.errMessage || '删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除失败', error)
      ElMessage.error('删除失败')
    }
  }
}

// 监听 tab 切换，加载对应数据
watch(editActiveTab, (newTab) => {
  if (newTab === 'camera' && currentLss.value) {
    cameraSearchForm.keyword = ''
    cameraSearchForm.status = ''
    loadCameraList()
  }
})

onMounted(() => {
  getList()
})
</script>

<style lang="scss" scoped>
.page-container {
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

.search-form {
  flex-shrink: 0;
  margin-bottom: 16px;
  padding: 16px 16px 4px 16px;
  background: #f5f7fa;

  :deep(.el-form-item) {
    margin-bottom: 12px;
    margin-right: 16px;
  }

  :deep(.el-input),
  :deep(.el-select) {
    width: 160px;
  }

  :deep(.el-button--primary) {
    background-color: #4f46e5;
    border-color: #4f46e5;

    &:hover,
    &:focus {
      background-color: #6366f1;
      border-color: #6366f1;
    }
  }
}

.table-wrapper {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.pagination-container {
  flex-shrink: 0;
  display: flex;
  justify-content: flex-end;
  padding-top: 16px;

  :deep(.el-pagination) {
    .el-pager li.is-active {
      background-color: #4f46e5;
      color: #fff;
    }

    .el-pager li:not(.is-active):hover {
      color: #4f46e5;
    }

    .btn-prev:hover,
    .btn-next:hover {
      color: #4f46e5;
    }
  }
}

.camera-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 16px;

  :deep(.el-form) {
    .el-form-item {
      margin-bottom: 0;
      margin-right: 12px;
    }
  }
}

.camera-count {
  margin-top: 16px;
  text-align: right;
  color: #666;
  font-size: 14px;
}

.status-text {
  font-size: 12px;
}

// 十字瞄准按钮样式
.crosshairs-btn {
  color: var(--color-info);
  transition: color 0.2s;

  &.active {
    color: var(--color-primary);
  }
}

.status-active {
  color: #67c23a;
}

.status-hold {
  color: #e6a23c;
}

.status-dead {
  color: #f56c6c;
}

// 抽屉样式
:deep(.el-drawer) {
  .el-drawer__header {
    margin-bottom: 0;
    padding: 16px 20px;
    border-bottom: 1px solid #e5e7eb;
  }

  .el-drawer__body {
    padding: 16px;
  }

  .el-descriptions {
    .el-descriptions__label {
      width: 100px;
      font-weight: 600;
    }
  }
}

// LSS 编辑抽屉样式
.lss-edit-drawer {
  :deep(.el-drawer__body) {
    padding: 0;
    display: flex;
    flex-direction: column;
    height: 100%;
  }
}

.drawer-content {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.drawer-tabs {
  flex-shrink: 0;
  border-bottom: 1px solid #e5e7eb;

  :deep(.el-tabs__header) {
    margin: 0;
    padding: 0 20px;
  }

  :deep(.el-tabs__nav-wrap::after) {
    display: none;
  }

  :deep(.el-tabs__item) {
    height: 48px;
    line-height: 48px;
    font-size: 14px;
    color: #606266;

    &.is-active {
      color: #409eff;
      font-weight: 500;
    }

    &:hover {
      color: #409eff;
    }
  }

  :deep(.el-tabs__active-bar) {
    background-color: #409eff;
  }
}

.drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

.lss-detail-form {
  :deep(.el-form-item) {
    margin-bottom: 18px;
  }

  :deep(.el-form-item__label) {
    color: #606266;
    font-size: 14px;
  }

  .form-value {
    line-height: 32px;
    color: #303133;
    font-size: 14px;
  }

  .textarea-wrapper {
    width: 100%;
  }
}

.heartbeat-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  line-height: 32px;
  font-size: 14px;
}

.heartbeat-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;

  &.status-active {
    background-color: #67c23a;
  }

  &.status-hold {
    background-color: #e6a23c;
  }

  &.status-dead {
    background-color: #f56c6c;
  }
}

.heartbeat-info-icon {
  margin-left: 8px;
  color: #909399;
  cursor: pointer;

  &:hover {
    color: #409eff;
  }
}

.heartbeat-tooltip {
  font-size: 12px;
  line-height: 1.6;

  .tooltip-title {
    font-weight: 500;
    margin-bottom: 4px;
  }

  .tooltip-format {
    margin-top: 8px;
    font-weight: 500;
  }

  .tooltip-example {
    color: #409eff;
  }
}

.tab-content {
  min-height: 200px;
}

// 设备列表抽屉样式
.device-drawer {
  :deep(.el-drawer__body) {
    padding: 0;
  }
}

.device-tabs {
  height: 100%;
  display: flex;
  flex-direction: column;

  :deep(.el-tabs__header) {
    margin: 0;
    padding: 0 20px;
    flex-shrink: 0;
    border-bottom: 1px solid #e5e7eb;
  }

  :deep(.el-tabs__nav-wrap::after) {
    display: none;
  }

  :deep(.el-tabs__item) {
    height: 48px;
    line-height: 48px;
    font-size: 14px;
    color: #606266;

    &.is-active {
      color: #409eff;
      font-weight: 500;
    }

    &:hover {
      color: #409eff;
    }
  }

  :deep(.el-tabs__active-bar) {
    background-color: #409eff;
  }

  :deep(.el-tabs__content) {
    flex: 1;
    overflow: hidden;
    padding: 16px;
  }

  :deep(.el-tab-pane) {
    height: 100%;
    overflow-y: auto;
  }
}

.tab-content-wrapper {
  height: 100%;
}

.drawer-footer {
  flex-shrink: 0;
  display: flex;
  justify-content: flex-end;
  padding: 12px 20px;
  border-top: 1px solid #e5e7eb;
  gap: 12px;
}

// 表格样式
:deep(.el-table) {
  --el-table-row-hover-bg-color: #f0f0ff;

  .el-table__row--striped td.el-table__cell {
    background-color: #f8f9fc;
  }

  .el-table__header th {
    background-color: #f5f7fa;
    color: #333;
    font-weight: 600;
  }

  .el-button--primary.is-link {
    color: #4f46e5;

    &:hover {
      color: #6366f1;
    }
  }

  .caret-wrapper {
    .sort-caret.ascending {
      border-bottom-color: #4f46e5;
    }

    .sort-caret.descending {
      border-top-color: #4f46e5;
    }
  }
}
</style>
