<template>
  <ArtTableFullScreen>
    <div class="device-list-page" id="table-full-screen">
      <!-- 搜索栏 -->
      <ArtSearchBar
        v-model:filter="searchForm"
        :items="searchFormItems"
        @reset="handleReset"
        @search="handleSearch"
      ></ArtSearchBar>

      <ElCard shadow="never" class="art-table-card">
        <!-- 表格头部 -->
        <ArtTableHeader
          :columnList="columnOptions"
          v-model:columns="columnChecks"
          @refresh="handleRefresh"
        >
          <template #left>
            <ElButton
              type="primary"
              @click="handleBatchAllocate"
              :disabled="!selectedDevices.length"
              v-permission="'device:batch_allocate'"
            >
              批量分配
            </ElButton>
            <ElButton
              @click="handleBatchRecall"
              :disabled="!selectedDevices.length"
              v-permission="'device:batch_recall'"
            >
              批量回收
            </ElButton>
            <ElButton
              type="info"
              :disabled="!selectedDevices.length"
              @click="handleBatchSetSeries"
              v-permission="'device:batch_set_series'"
            >
              批量设置套餐系列
            </ElButton>
            <ElButton
              type="primary"
              :disabled="!selectedDevices.length"
              @click="showBatchRealnamePolicyDialog"
              v-permission="'device:realname_policy'"
            >
              批量修改实名顺序
            </ElButton>
            <ElButton
              type="primary"
              :disabled="!selectedDevices.length"
              @click="showEnterpriseDeviceAuthorizeDialog"
              v-permission="'devices:authorize_enterprise'"
            >
              授权设备给企业
            </ElButton>
            <ElButton
              type="warning"
              :disabled="!selectedDevices.length"
              @click="showEnterpriseDeviceRecallDialog"
              v-permission="'devices:recall_enterprise_authorization'"
            >
              撤销设备授权
            </ElButton>
            <ElButton type="primary" @click="showExportDialog" v-permission="'devices:export'">
              导出
            </ElButton>
          </template>
        </ArtTableHeader>

        <!-- 表格 -->
        <ArtTable
          ref="tableRef"
          row-key="id"
          :loading="loading"
          :data="deviceList"
          :currentPage="pagination.page"
          :pageSize="pagination.pageSize"
          :total="pagination.total"
          :marginTop="10"
          :actions="getActions"
          :actionsWidth="180"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          @selection-change="handleSelectionChange"
        >
          <template #default>
            <ElTableColumn type="selection" width="55" />
            <ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
          </template>
        </ArtTable>

        <!-- 批量分配对话框 -->
        <ElDialog v-model="allocateDialogVisible" title="批量分配设备" width="600px">
          <ElForm
            ref="allocateFormRef"
            :model="allocateForm"
            :rules="allocateRules"
            label-width="120px"
          >
            <ElFormItem label="已选设备数">
              <span style="font-weight: bold; color: #409eff">{{ selectedDevices.length }}</span> 台
            </ElFormItem>
            <ElFormItem label="店铺" prop="target_shop_id">
              <ElCascader
                v-model="allocateForm.target_shop_id"
                :options="shopCascadeOptions"
                :props="shopCascadeProps"
                placeholder="请选择目标店铺"
                clearable
                filterable
                style="width: 100%"
              />
            </ElFormItem>
            <ElFormItem label="备注">
              <ElInput
                v-model="allocateForm.remark"
                type="textarea"
                :rows="3"
                placeholder="请输入备注信息（选填）"
              />
            </ElFormItem>
          </ElForm>

          <!-- 分配结果 -->
          <div v-if="allocateResult" style="margin-top: 20px">
            <ElAlert
              :type="allocateResult.fail_count === 0 ? 'success' : 'warning'"
              :closable="false"
              style="margin-bottom: 10px"
            >
              <template #title>
                成功分配 {{ allocateResult.success_count }} 台，失败
                {{ allocateResult.fail_count }} 台
              </template>
            </ElAlert>
            <div v-if="allocateResult.failed_items && allocateResult.failed_items.length > 0">
              <div style="margin-bottom: 10px; font-weight: bold">失败详情：</div>
              <div
                v-for="item in allocateResult.failed_items"
                :key="item.device_id"
                style="margin-bottom: 8px; font-size: 12px; color: #f56c6c"
              >
                设备号: {{ item.virtual_no }} - {{ item.reason }}
              </div>
            </div>
          </div>

          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="handleCloseAllocateDialog">
                {{ allocateResult ? '关闭' : '取消' }}
              </ElButton>
              <ElButton
                v-if="!allocateResult"
                type="primary"
                @click="handleConfirmAllocate"
                :loading="allocateLoading"
              >
                确认分配
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 批量回收对话框 -->
        <ElDialog v-model="recallDialogVisible" title="批量回收设备" width="600px">
          <ElForm ref="recallFormRef" :model="recallForm" label-width="120px">
            <ElFormItem label="已选设备数">
              <span style="font-weight: bold; color: #e6a23c">{{ selectedDevices.length }}</span> 台
            </ElFormItem>
            <ElFormItem label="备注">
              <ElInput
                v-model="recallForm.remark"
                type="textarea"
                :rows="3"
                placeholder="请输入备注信息（选填）"
              />
            </ElFormItem>
          </ElForm>

          <!-- 回收结果 -->
          <div v-if="recallResult" style="margin-top: 20px">
            <ElAlert
              :type="recallResult.fail_count === 0 ? 'success' : 'warning'"
              :closable="false"
              style="margin-bottom: 10px"
            >
              <template #title>
                成功回收 {{ recallResult.success_count }} 台，失败 {{ recallResult.fail_count }} 台
              </template>
            </ElAlert>
            <div v-if="recallResult.failed_items && recallResult.failed_items.length > 0">
              <div style="margin-bottom: 10px; font-weight: bold">失败详情：</div>
              <div
                v-for="item in recallResult.failed_items"
                :key="item.device_id"
                style="margin-bottom: 8px; font-size: 12px; color: #f56c6c"
              >
                设备号: {{ item.virtual_no }} - {{ item.reason }}
              </div>
            </div>
          </div>

          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="handleCloseRecallDialog">
                {{ recallResult ? '关闭' : '取消' }}
              </ElButton>
              <ElButton
                v-if="!recallResult"
                type="primary"
                @click="handleConfirmRecall"
                :loading="recallLoading"
              >
                确认回收
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 批量设置套餐系列绑定对话框 -->
        <ElDialog
          v-model="seriesBindingDialogVisible"
          title="批量设置设备套餐系列绑定"
          width="35%"
          @close="handleCloseSeriesBindingDialog"
        >
          <ElForm
            ref="seriesBindingFormRef"
            :model="seriesBindingForm"
            :rules="seriesBindingRules"
            label-width="120px"
          >
            <ElFormItem label="已选设备数">
              <span style="font-weight: bold; color: #409eff">{{ selectedDevices.length }}</span> 台
            </ElFormItem>
            <ElFormItem label="选设备方式" prop="selection_type">
              <ElRadioGroup v-model="seriesBindingForm.selection_type">
                <ElRadio label="list">设备ID列表</ElRadio>
                <ElRadio label="range">设备号范围</ElRadio>
                <ElRadio label="filter">筛选条件</ElRadio>
              </ElRadioGroup>
            </ElFormItem>

            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.LIST"
              label="设备列表"
            >
              <div>已选择 {{ selectedDevices.length }} 台设备</div>
            </ElFormItem>

            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.RANGE"
              label="起始设备号"
              prop="virtual_no_start"
            >
              <ElInput
                v-model="seriesBindingForm.virtual_no_start"
                placeholder="请输入起始设备号"
              />
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.RANGE"
              label="结束设备号"
              prop="virtual_no_end"
            >
              <ElInput v-model="seriesBindingForm.virtual_no_end" placeholder="请输入结束设备号" />
            </ElFormItem>

            <div
              v-if="
                seriesBindingForm.selection_type === DeviceSelectionType.RANGE &&
                seriesBindingRangeCountText
              "
              class="range-allocation-hint range-allocation-hint--device"
            >
              共分配{{ seriesBindingRangeCountText }}台设备
            </div>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="设备号"
            >
              <ElInput
                v-model="seriesBindingForm.virtual_no"
                placeholder="请输入设备号"
                clearable
              />
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="设备名称"
            >
              <ElInput
                v-model="seriesBindingForm.device_name"
                placeholder="请输入设备名称"
                clearable
              />
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="设备类型"
            >
              <ElInput
                v-model="seriesBindingForm.device_type"
                placeholder="请输入设备类型"
                clearable
              />
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="制造商"
            >
              <ElInput
                v-model="seriesBindingForm.manufacturer"
                placeholder="请输入制造商"
                clearable
              />
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="状态"
            >
              <ElSelect
                v-model="seriesBindingForm.status"
                placeholder="请选择状态"
                clearable
                style="width: 100%"
              >
                <ElOption label="在库" :value="1" />
                <ElOption label="已分销" :value="2" />
                <ElOption label="已激活" :value="3" />
                <ElOption label="已停用" :value="4" />
              </ElSelect>
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="批次号"
            >
              <ElSelect
                v-model="seriesBindingForm.batch_no"
                placeholder="请选择或搜索批次号"
                clearable
                filterable
                remote
                :remote-method="handleSearchBatchNo"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in searchBatchNoOptions"
                  :key="item.id"
                  :label="item.batch_no"
                  :value="item.batch_no"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="店铺名称"
            >
              <ElCascader
                v-model="seriesBindingForm.shop_id_path"
                :options="seriesBindingShopCascadeOptions"
                :props="seriesBindingShopCascadeProps"
                placeholder="请选择店铺名称"
                clearable
                filterable
                style="width: 100%"
              />
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="当前套餐系列"
            >
              <ElSelect
                v-model="seriesBindingForm.filter_series_id"
                placeholder="请选择或搜索当前套餐系列"
                clearable
                filterable
                remote
                :remote-method="searchSeries"
                style="width: 100%"
              >
                <ElOption
                  v-for="series in searchSeriesOptions"
                  :key="series.id"
                  :label="series.series_name"
                  :value="series.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === DeviceSelectionType.FILTER"
              label="创建设备时间"
            >
              <ElDatePicker
                v-model="seriesBindingForm.created_at_range"
                type="daterange"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                value-format="YYYY-MM-DD"
                style="width: 100%"
              />
            </ElFormItem>

            <ElFormItem label="目标套餐系列" prop="series_id">
              <ElSelect
                v-model="seriesBindingForm.series_id"
                placeholder="请选择或搜索套餐系列"
                style="width: 100%"
                filterable
                remote
                reserve-keyword
                :remote-method="searchPackageSeries"
                :loading="seriesLoading"
                clearable
              >
                <ElOption
                  v-for="series in packageSeriesList"
                  :key="series.id"
                  :label="series.series_name"
                  :value="series.id"
                  :disabled="series.status !== 1"
                />
              </ElSelect>
            </ElFormItem>
          </ElForm>

          <!-- 设置结果 -->
          <div v-if="seriesBindingResult" style="margin-top: 20px">
            <ElAlert
              :type="seriesBindingResult.fail_count === 0 ? 'success' : 'warning'"
              :closable="false"
              style="margin-bottom: 10px"
            >
              <template #title>
                成功设置 {{ seriesBindingResult.success_count }} 台，失败
                {{ seriesBindingResult.fail_count }} 台
              </template>
            </ElAlert>
            <div
              v-if="seriesBindingResult.failed_items && seriesBindingResult.failed_items.length > 0"
            >
              <div style="margin-bottom: 10px; font-weight: bold">失败详情：</div>
              <div
                v-for="item in seriesBindingResult.failed_items"
                :key="item.device_id"
                style="margin-bottom: 8px; font-size: 12px; color: #f56c6c"
              >
                设备号: {{ item.virtual_no }} - {{ item.reason }}
              </div>
            </div>
          </div>

          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="handleCloseSeriesBindingDialog">
                {{ seriesBindingResult ? '关闭' : '取消' }}
              </ElButton>
              <ElButton
                v-if="!seriesBindingResult"
                type="primary"
                @click="handleConfirmSeriesBinding"
                :loading="seriesBindingLoading"
              >
                确认设置
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 设备详情弹窗 -->
        <ElDialog v-model="deviceDetailDialogVisible" title="设备详情" width="1000px">
          <div v-if="deviceDetailLoading" style="padding: 40px 0; text-align: center">
            <ElIcon class="is-loading" :size="40">
              <Loading />
            </ElIcon>
          </div>
          <div v-else-if="currentDeviceDetail">
            <!-- 设备基本信息 -->
            <ElDescriptions :column="3" border style="margin-bottom: 20px">
              <ElDescriptionsItem label="设备ID">{{ currentDeviceDetail.id }}</ElDescriptionsItem>
              <ElDescriptionsItem label="设备号" :span="2">{{
                currentDeviceDetail.virtual_no
              }}</ElDescriptionsItem>

              <ElDescriptionsItem label="设备名称">{{
                currentDeviceDetail.device_name || '-'
              }}</ElDescriptionsItem>
              <ElDescriptionsItem label="设备型号">{{
                currentDeviceDetail.device_model || '-'
              }}</ElDescriptionsItem>
              <ElDescriptionsItem label="设备类型">{{
                currentDeviceDetail.device_type || '-'
              }}</ElDescriptionsItem>

              <ElDescriptionsItem label="制造商">{{
                currentDeviceDetail.manufacturer || '-'
              }}</ElDescriptionsItem>
              <ElDescriptionsItem label="最大插槽数">{{
                currentDeviceDetail.max_sim_slots
              }}</ElDescriptionsItem>
              <ElDescriptionsItem label="已绑定卡数量">{{
                currentDeviceDetail.bound_card_count
              }}</ElDescriptionsItem>

              <ElDescriptionsItem label="状态">
                <ElTag :type="getDeviceStatusTagType(currentDeviceDetail.status)">
                  {{ currentDeviceDetail.status_name }}
                </ElTag>
              </ElDescriptionsItem>
              <ElDescriptionsItem label="批次号" :span="2">{{
                currentDeviceDetail.batch_no || '-'
              }}</ElDescriptionsItem>

              <ElDescriptionsItem label="创建时间" :span="3">{{
                formatDateTime(currentDeviceDetail.created_at) || '-'
              }}</ElDescriptionsItem>
            </ElDescriptions>
          </div>
        </ElDialog>

        <!-- 绑定卡片列表弹窗 -->
        <ElDialog v-model="deviceCardsDialogVisible" title="设备绑定的卡" width="60%">
          <!-- 绑定新卡表单 -->
          <ElCard shadow="never" class="bind-card-section" style="margin-bottom: 20px">
            <template #header>
              <div style="font-weight: bold">绑定新卡</div>
            </template>
            <ElForm
              ref="bindCardFormRef"
              :model="bindCardForm"
              :rules="bindCardRules"
              label-width="80"
            >
              <ElRow :gutter="20">
                <ElCol :span="6">
                  <ElFormItem label="搜索类型" prop="search_type">
                    <ElSelect
                      v-model="bindCardForm.search_type"
                      placeholder="请选择搜索类型"
                      style="width: 100%"
                    >
                      <ElOption label="ICCID" value="iccid" />
                      <ElOption label="运营商名称" value="carrier_name" />
                    </ElSelect>
                  </ElFormItem>
                </ElCol>
                <ElCol :span="9">
                  <ElFormItem label="ICCID" prop="iot_card_id">
                    <ElSelect
                      v-model="bindCardForm.iot_card_id"
                      :placeholder="
                        bindCardForm.search_type === 'carrier_name'
                          ? '请选择或搜索运营商名称'
                          : '请选择或搜索ICCID'
                      "
                      filterable
                      remote
                      reserve-keyword
                      :remote-method="searchIotCards"
                      :loading="iotCardSearchLoading"
                      clearable
                      style="width: 100%"
                    >
                      <ElOption
                        v-for="card in iotCardList"
                        :key="card.id"
                        :label="`${card.iccid} ${card.carrier_name ? '(' + card.carrier_name + ')' : ''}`"
                        :value="card.id"
                      />
                      <ElOption
                        v-if="iotCardList.length === 0 && !iotCardSearchLoading"
                        label="未找到相关数据"
                        value=""
                        disabled
                      />
                    </ElSelect>
                  </ElFormItem>
                </ElCol>
                <ElCol :span="6">
                  <ElFormItem label="插槽位置" prop="slot_position">
                    <ElSelect
                      v-model="bindCardForm.slot_position"
                      placeholder="请选择插槽位置"
                      style="width: 100%"
                    >
                      <ElOption
                        v-for="i in currentDeviceDetail?.max_sim_slots || 4"
                        :key="i"
                        :label="`插槽 ${i}`"
                        :value="i"
                      />
                    </ElSelect>
                  </ElFormItem>
                </ElCol>
                <ElCol :span="3">
                  <ElButton
                    v-permission="'device:bind_card'"
                    type="primary"
                    @click="handleConfirmBindCard"
                    :loading="bindCardLoading"
                    style="width: 100%"
                  >
                    确认绑定
                  </ElButton>
                </ElCol>
              </ElRow>
            </ElForm>
          </ElCard>

          <!-- 已绑定卡片列表 -->
          <div v-if="deviceCardsLoading" style="padding: 40px 0; text-align: center">
            <ElIcon class="is-loading" :size="40">
              <Loading />
            </ElIcon>
          </div>
          <div v-else>
            <ElTable :data="deviceCards" border style="width: 100%">
              <ElTableColumn prop="slot_position" label="插槽位置" width="120">
                <template #default="{ row }">
                  <div style="display: flex; gap: 10px; align-items: center">
                    <span>SIM-{{ row.slot_position }}</span>
                    <ElTag v-if="row.is_current" type="success" size="small">当前</ElTag>
                  </div>
                </template>
              </ElTableColumn>
              <ElTableColumn prop="iccid" label="ICCID" min-width="120" />
              <ElTableColumn prop="msisdn" label="接入号" width="160" />
              <ElTableColumn prop="network_status" label="网络状态" width="100">
                <template #default="{ row }">
                  <ElTag :type="getNetworkStatusTagType(row.network_status)">
                    {{ getNetworkStatusText(row.network_status) }}
                  </ElTag>
                </template>
              </ElTableColumn>
              <ElTableColumn prop="bind_time" label="绑定时间" width="180">
                <template #default="{ row }">
                  {{ formatDateTime(row.bind_time) || '-' }}
                </template>
              </ElTableColumn>
              <ElTableColumn label="操作" width="100" fixed="right" align="center">
                <template #default="{ row }">
                  <ElButton
                    v-permission="'device:unbind_card'"
                    type="danger"
                    size="small"
                    link
                    @click="handleUnbindCard(row)"
                  >
                    解绑
                  </ElButton>
                </template>
              </ElTableColumn>
            </ElTable>
            <div
              v-if="deviceCards.length === 0"
              style="padding: 20px; color: #909399; text-align: center"
            >
              暂无设备绑定的卡
            </div>
          </div>
        </ElDialog>

        <!-- 切换SIM卡对话框 -->
        <SwitchCardDialog
          v-model="switchCardDialogVisible"
          :device-info="currentOperatingImei"
          :cards="deviceBindingCards"
          :loading="loadingDeviceCards"
          :confirm-loading="switchCardLoading"
          @confirm="handleConfirmSwitchCard"
        />

        <!-- 设置切卡模式对话框 -->
        <SwitchModeDialog
          v-model="switchModeDialogVisible"
          :device-identifier="currentOperatingDeviceIdentifier"
          :current-mode="currentDeviceSwitchMode"
          :cards="switchModeCards"
          :has-imei="currentOperatingDeviceHasImei"
          :confirm-loading="switchModeLoading"
          @confirm="handleConfirmSwitchMode"
        />

        <!-- 实名认证策略对话框 -->
        <RealnamePolicyDialog
          v-model="realnamePolicyDialogVisible"
          :asset-identifier="currentRealnamePolicyAsset"
          :current-policy="currentRealnamePolicy"
          @confirm="handleConfirmRealnamePolicy"
        />
        <BatchRealnamePolicyDialog
          v-model="batchRealnamePolicyDialogVisible"
          :selected-count="selectedDevices.length"
          asset-unit="台设备"
          :loading="batchRealnamePolicyLoading"
          :error-message="batchRealnamePolicyError"
          device-policy-hint
          @confirm="handleConfirmBatchRealnamePolicy"
        />

        <!-- 操作审计日志弹窗 -->
        <OperationLogsDialog
          v-model="operationLogsDialogVisible"
          :identifier="operationLogsIdentifier"
          download-permission="device:download_log_file"
        />
        <ElDialog
          v-model="enterpriseDeviceAuthorizeDialogVisible"
          title="授权设备给企业"
          width="620px"
          @close="handleEnterpriseDeviceAuthorizeDialogClose"
        >
          <ElForm
            ref="enterpriseDeviceAuthorizeFormRef"
            :model="enterpriseDeviceAuthorizeForm"
            :rules="enterpriseDeviceAuthorizeRules"
            label-width="120px"
          >
            <ElFormItem label="授权企业" prop="enterprise_id">
              <ElSelect
                v-model="enterpriseDeviceAuthorizeForm.enterprise_id"
                placeholder="请选择或搜索企业"
                clearable
                filterable
                remote
                reserve-keyword
                :remote-method="handleSearchEnterprise"
                :loading="enterpriseLoading"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in enterpriseOptions"
                  :key="item.id"
                  :label="item.enterprise_name"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="选设备方式" prop="selection_type">
              <ElRadioGroup v-model="enterpriseDeviceAuthorizeForm.selection_type">
                <ElRadio label="list">设备号列表</ElRadio>
                <ElRadio label="filter">筛选条件</ElRadio>
              </ElRadioGroup>
            </ElFormItem>
            <ElFormItem
              v-if="enterpriseDeviceAuthorizeForm.selection_type === DeviceSelectionType.LIST"
              label="设备号列表"
            >
              <div>已选择 {{ selectedDevices.length }} 台设备</div>
            </ElFormItem>
            <template
              v-if="enterpriseDeviceAuthorizeForm.selection_type === DeviceSelectionType.FILTER"
            >
              <ElFormItem label="设备号">
                <ElInput
                  v-model="enterpriseDeviceAuthorizeForm.virtual_no"
                  placeholder="请输入设备号"
                  clearable
                />
              </ElFormItem>
              <ElFormItem label="批次号">
                <ElSelect
                  v-model="enterpriseDeviceAuthorizeForm.batch_no"
                  placeholder="请选择或搜索批次号"
                  clearable
                  filterable
                  remote
                  :remote-method="handleSearchBatchNo"
                  style="width: 100%"
                >
                  <ElOption
                    v-for="item in searchBatchNoOptions"
                    :key="item.id"
                    :label="item.batch_no"
                    :value="item.batch_no"
                  />
                </ElSelect>
              </ElFormItem>
              <ElFormItem label="店铺名称">
                <ElCascader
                  v-model="enterpriseDeviceAuthorizeForm.shop_id_path"
                  :options="shopCascadeOptions"
                  :props="shopCascadeProps"
                  placeholder="请选择店铺名称"
                  clearable
                  filterable
                  style="width: 100%"
                />
              </ElFormItem>
            </template>
            <ElFormItem label="备注">
              <ElInput
                v-model="enterpriseDeviceAuthorizeForm.remark"
                type="textarea"
                :rows="3"
                placeholder="请输入备注信息"
              />
            </ElFormItem>
          </ElForm>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="enterpriseDeviceAuthorizeDialogVisible = false">取消</ElButton>
              <ElButton
                type="primary"
                @click="handleEnterpriseDeviceAuthorize"
                :loading="enterpriseDeviceAuthorizeLoading"
              >
                确认授权
              </ElButton>
            </div>
          </template>
        </ElDialog>
        <ElDialog
          v-model="enterpriseDeviceRecallDialogVisible"
          title="撤销设备授权"
          width="620px"
          @close="handleEnterpriseDeviceRecallDialogClose"
        >
          <ElForm
            ref="enterpriseDeviceRecallFormRef"
            :model="enterpriseDeviceRecallForm"
            :rules="enterpriseDeviceRecallRules"
            label-width="120px"
          >
            <ElFormItem label="授权企业" prop="enterprise_id">
              <ElSelect
                v-model="enterpriseDeviceRecallForm.enterprise_id"
                placeholder="请选择或搜索企业"
                clearable
                filterable
                remote
                reserve-keyword
                :remote-method="handleSearchEnterprise"
                :loading="enterpriseLoading"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in enterpriseOptions"
                  :key="item.id"
                  :label="item.enterprise_name"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem label="选设备方式" prop="selection_type">
              <ElRadioGroup v-model="enterpriseDeviceRecallForm.selection_type">
                <ElRadio label="list">设备号列表</ElRadio>
                <ElRadio label="filter">筛选条件</ElRadio>
              </ElRadioGroup>
            </ElFormItem>
            <ElFormItem
              v-if="enterpriseDeviceRecallForm.selection_type === DeviceSelectionType.LIST"
              label="设备号列表"
            >
              <div>已选择 {{ selectedDevices.length }} 台设备</div>
            </ElFormItem>
            <template
              v-if="enterpriseDeviceRecallForm.selection_type === DeviceSelectionType.FILTER"
            >
              <ElFormItem label="设备号">
                <ElInput
                  v-model="enterpriseDeviceRecallForm.virtual_no"
                  placeholder="请输入设备号"
                  clearable
                />
              </ElFormItem>
              <ElFormItem label="批次号">
                <ElSelect
                  v-model="enterpriseDeviceRecallForm.batch_no"
                  placeholder="请选择或搜索批次号"
                  clearable
                  filterable
                  remote
                  :remote-method="handleSearchBatchNo"
                  style="width: 100%"
                >
                  <ElOption
                    v-for="item in searchBatchNoOptions"
                    :key="item.id"
                    :label="item.batch_no"
                    :value="item.batch_no"
                  />
                </ElSelect>
              </ElFormItem>
            </template>
          </ElForm>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="enterpriseDeviceRecallDialogVisible = false">取消</ElButton>
              <ElButton
                type="primary"
                @click="handleEnterpriseDeviceRecall"
                :loading="enterpriseDeviceRecallLoading"
              >
                确认撤销
              </ElButton>
            </div>
          </template>
        </ElDialog>
        <ElDialog
          v-model="enterpriseDeviceResultDialogVisible"
          :title="enterpriseDeviceResultTitle"
          width="700px"
        >
          <ElDescriptions :column="2" border>
            <ElDescriptionsItem label="成功数">
              <ElTag type="success">{{ enterpriseDeviceOperationResult.success_count }}</ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem label="失败数">
              <ElTag type="danger">{{ enterpriseDeviceOperationResult.fail_count }}</ElTag>
            </ElDescriptionsItem>
          </ElDescriptions>
          <div
            v-if="
              enterpriseDeviceOperationResult.failed_items &&
              enterpriseDeviceOperationResult.failed_items.length > 0
            "
            style="margin-top: 20px"
          >
            <ElDivider content-position="left">失败项详情</ElDivider>
            <ElTable :data="enterpriseDeviceOperationResult.failed_items" border max-height="300">
              <ElTableColumn prop="virtual_no" label="设备号" width="180" />
              <ElTableColumn prop="reason" label="失败原因" />
            </ElTable>
          </div>
          <div
            v-if="
              enterpriseDeviceOperationResult.authorized_devices &&
              enterpriseDeviceOperationResult.authorized_devices.length > 0
            "
            style="margin-top: 20px"
          >
            <ElDivider content-position="left">已授权设备</ElDivider>
            <ElTable
              :data="enterpriseDeviceOperationResult.authorized_devices"
              border
              max-height="220"
            >
              <ElTableColumn prop="virtual_no" label="设备号" width="180" />
              <ElTableColumn prop="card_count" label="绑定卡数" />
            </ElTable>
          </div>
          <template #footer>
            <div class="dialog-footer">
              <ElButton type="primary" @click="enterpriseDeviceResultDialogVisible = false"
                >确定</ElButton
              >
            </div>
          </template>
        </ElDialog>
        <ExportTaskCreateDialog
          v-model="exportDialogVisible"
          scene="device"
          :query="exportQuery"
          confirm-permission="devices:export"
          title="导出设备"
        />
      </ElCard>
    </div>
  </ArtTableFullScreen>
</template>

<script setup lang="ts">
  import { computed, h } from 'vue'
  import { useRouter } from 'vue-router'
  import { RoutesAlias } from '@/router/routesAlias'
  import {
    DeviceService,
    ShopService,
    CardService,
    PackageSeriesService,
    AssetService,
    EnterpriseService
  } from '@/api/modules'
  import { DeviceSelectionType } from '@/types/api'
  import { ElMessage, ElMessageBox, ElTag, ElIcon, ElRadioGroup, ElRadio } from 'element-plus'
  import { Loading } from '@element-plus/icons-vue'
  import type { FormInstance, FormRules } from 'element-plus'
  import SwitchCardDialog from '@/components/device/SwitchCardDialog.vue'
  import SwitchModeDialog from '@/views/asset-management/asset-information/components/dialogs/SwitchModeDialog.vue'
  import type {
    Device,
    DeviceStatus,
    AllocateDevicesResponse,
    RecallDevicesResponse,
    BatchSetDeviceSeriesBindingRequest,
    BatchSetDeviceSeriesBindingResponse
  } from '@/types/api'
  import type { SearchFormItem } from '@/types'
  import { useCheckedColumns } from '@/composables/useCheckedColumns'
  import { useAuth } from '@/composables/useAuth'
  import { formatDateTime } from '@/utils/business/format'
  import { getExpiryEstimateText, getExpiryEstimateTooltip } from '@/utils/business/expiryEstimate'
  import type { PackageSeriesResponse } from '@/types/api'
  import type { EnterpriseItem } from '@/types/api/enterprise'
  import type {
    EnterpriseAllocateDevicesResponse,
    EnterpriseRecallDevicesResponse
  } from '@/types/api/enterpriseDevice'
  import RealnamePolicyDialog from '@/components/device/RealnamePolicyDialog.vue'
  import BatchRealnamePolicyDialog from '@/components/business/BatchRealnamePolicyDialog.vue'
  import OperationLogsDialog from '@/components/business/OperationLogsDialog.vue'
  import ExportTaskCreateDialog from '@/components/business/ExportTaskCreateDialog.vue'
  import type { AssetRealnamePolicy } from '@/types/api'

  defineOptions({ name: 'DeviceList' })

  interface SwitchModeCardOption {
    iot_card_id: number
    iccid: string
    slot_position?: number
    carrier_name?: string
    msisdn?: string
    network_status?: number
    real_name_status?: number
    is_current?: boolean
  }

  const { hasAuth } = useAuth()
  const router = useRouter()

  const loading = ref(false)
  const allocateLoading = ref(false)
  const recallLoading = ref(false)
  const tableRef = ref()
  const allocateFormRef = ref<FormInstance>()
  const recallFormRef = ref<FormInstance>()
  const allocateDialogVisible = ref(false)
  const recallDialogVisible = ref(false)
  const selectedDevices = ref<Device[]>([])
  const batchRealnamePolicyDialogVisible = ref(false)
  const batchRealnamePolicyLoading = ref(false)
  const batchRealnamePolicyError = ref('')
  const operationLogsDialogVisible = ref(false)
  const operationLogsIdentifier = ref('')
  const exportDialogVisible = ref(false)
  const shopCascadeOptions = ref<any[]>([])
  const shopCascadeProps = {
    lazy: true,
    checkStrictly: true,
    lazyLoad: async (node: any, resolve: any) => {
      const { level, value } = node
      const parentId = level === 0 ? undefined : value

      try {
        const res = await ShopService.getShopsCascade({ parent_id: parentId })
        if (res.code === 0) {
          const nodes = (res.data || []).map((item: any) => ({
            value: item.id,
            label: item.shop_name,
            leaf: !item.has_children
          }))
          resolve(nodes)
        } else {
          resolve([])
        }
      } catch (error) {
        console.error('加载店铺级联数据失败:', error)
        resolve([])
      }
    },
    value: 'value',
    label: 'label',
    children: 'children'
  }
  const loadTopLevelShopCascadeOptions = async () => {
    try {
      const res = await ShopService.getShopsCascade({ parent_id: undefined })
      if (res.code === 0) {
        shopCascadeOptions.value = (res.data || []).map((item: any) => ({
          value: item.id,
          label: item.shop_name,
          leaf: !item.has_children
        }))
      }
    } catch (error) {
      console.error('加载顶级店铺失败:', error)
    }
  }
  const seriesBindingShopCascadeOptions = ref<any[]>([])
  const seriesBindingShopCascadeProps = {
    lazy: true,
    checkStrictly: true,
    lazyLoad: async (node: any, resolve: any) => {
      const { level, value } = node
      const parentId = level === 0 ? undefined : value

      try {
        const res = await ShopService.getShopsCascade({
          parent_id: parentId,
          exclude_self: true
        })
        if (res.code === 0) {
          const nodes = (res.data || []).map((item: any) => ({
            value: item.id,
            label: item.shop_name,
            leaf: !item.has_children
          }))
          resolve(nodes)
        } else {
          resolve([])
        }
      } catch (error) {
        console.error('加载批量设置套餐系列店铺级联数据失败:', error)
        resolve([])
      }
    },
    value: 'value',
    label: 'label',
    children: 'children'
  }
  const allocateResult = ref<AllocateDevicesResponse | null>(null)
  const recallResult = ref<RecallDevicesResponse | null>(null)
  const enterpriseDeviceAuthorizeDialogVisible = ref(false)
  const enterpriseDeviceRecallDialogVisible = ref(false)
  const enterpriseDeviceResultDialogVisible = ref(false)
  const enterpriseDeviceAuthorizeLoading = ref(false)
  const enterpriseDeviceRecallLoading = ref(false)
  const enterpriseDeviceResultTitle = ref('')
  const enterpriseDeviceAuthorizeFormRef = ref<FormInstance>()
  const enterpriseDeviceRecallFormRef = ref<FormInstance>()
  const enterpriseOptions = ref<EnterpriseItem[]>([])
  const enterpriseLoading = ref(false)
  const enterpriseDeviceOperationResult = ref<
    Partial<EnterpriseAllocateDevicesResponse & EnterpriseRecallDevicesResponse> & {
      success_count: number
      fail_count: number
    }
  >({
    success_count: 0,
    fail_count: 0,
    failed_items: null,
    authorized_devices: null
  })

  // 套餐系列绑定相关
  const seriesBindingDialogVisible = ref(false)
  const seriesBindingLoading = ref(false)
  const seriesBindingFormRef = ref<FormInstance>()
  const seriesLoading = ref(false)
  const packageSeriesList = ref<PackageSeriesResponse[]>([])
  const createInitialSeriesBindingState = () => ({
    selection_type: DeviceSelectionType.LIST,
    series_id: undefined as number | undefined,
    virtual_no_start: '',
    virtual_no_end: '',
    virtual_no: '',
    device_name: '',
    device_type: '',
    manufacturer: '',
    batch_no: '',
    status: undefined as DeviceStatus | undefined,
    shop_id_path: undefined as number[] | undefined,
    filter_series_id: undefined as number | undefined,
    created_at_range: [] as string[],
    created_at_start: '',
    created_at_end: ''
  })
  const seriesBindingForm = reactive(createInitialSeriesBindingState())
  const createInitialEnterpriseDeviceAuthorizeState = () => ({
    enterprise_id: undefined as number | undefined,
    selection_type: DeviceSelectionType.LIST,
    virtual_no: '',
    batch_no: '',
    shop_id_path: undefined as number[] | undefined,
    remark: ''
  })
  const createInitialEnterpriseDeviceRecallState = () => ({
    enterprise_id: undefined as number | undefined,
    selection_type: DeviceSelectionType.LIST,
    virtual_no: '',
    batch_no: ''
  })
  const enterpriseDeviceAuthorizeForm = reactive(createInitialEnterpriseDeviceAuthorizeState())
  const enterpriseDeviceRecallForm = reactive(createInitialEnterpriseDeviceRecallState())
  const parseNumericStringToBigInt = (value: string): bigint | null => {
    const normalizedValue = value.trim()
    if (!normalizedValue || !/^\d+$/.test(normalizedValue)) {
      return null
    }

    try {
      return BigInt(normalizedValue)
    } catch {
      return null
    }
  }
  const getPositiveRangeCountText = (start: bigint | null, end: bigint | null): string => {
    if (start === null || end === null || end < start) {
      return ''
    }

    return (end - start + 1n).toString()
  }
  const formatDigitGrouping = (value: string): string => value.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  const parseDeviceRangeEndpoint = (value: string): { prefix: string; number: bigint } | null => {
    const normalizedValue = value.trim()
    if (!normalizedValue) {
      return null
    }

    const numericValue = parseNumericStringToBigInt(normalizedValue)
    if (numericValue !== null) {
      return {
        prefix: '',
        number: numericValue
      }
    }

    const match = normalizedValue.match(/^(.*?)(\d+)$/)
    if (!match) {
      return null
    }

    try {
      return {
        prefix: match[1],
        number: BigInt(match[2])
      }
    } catch {
      return null
    }
  }
  const getDeviceRangeCountText = (startValue: string, endValue: string): string => {
    const start = parseDeviceRangeEndpoint(startValue)
    const end = parseDeviceRangeEndpoint(endValue)
    if (!start || !end || start.prefix !== end.prefix) {
      return ''
    }

    const countText = getPositiveRangeCountText(start.number, end.number)
    return countText ? formatDigitGrouping(countText) : ''
  }
  const seriesBindingRangeCountText = computed(() =>
    getDeviceRangeCountText(seriesBindingForm.virtual_no_start, seriesBindingForm.virtual_no_end)
  )
  const seriesBindingRules = reactive<FormRules>({
    selection_type: [{ required: true, message: '请选择选设备方式', trigger: 'change' }],
    series_id: [{ required: true, message: '请选择套餐系列', trigger: 'change' }],
    virtual_no_start: [
      {
        required: true,
        validator: (_rule, value, callback) => {
          if (seriesBindingForm.selection_type === DeviceSelectionType.RANGE && !value) {
            callback(new Error('请输入起始设备号'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ],
    virtual_no_end: [
      {
        required: true,
        validator: (_rule, value, callback) => {
          if (seriesBindingForm.selection_type === DeviceSelectionType.RANGE && !value) {
            callback(new Error('请输入结束设备号'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ]
  })
  const createEnterpriseDeviceRules = () =>
    reactive<FormRules>({
      enterprise_id: [{ required: true, message: '请选择企业', trigger: 'change' }],
      selection_type: [{ required: true, message: '请选择选设备方式', trigger: 'change' }]
    })
  const enterpriseDeviceAuthorizeRules = createEnterpriseDeviceRules()
  const enterpriseDeviceRecallRules = createEnterpriseDeviceRules()
  const seriesBindingResult = ref<BatchSetDeviceSeriesBindingResponse | null>(null)

  // 搜索表单店铺/系列选项
  const shopOptions = ref<any[]>([])
  const searchSeriesOptions = ref<any[]>([])
  const searchBatchNoOptions = ref<any[]>([])

  // 设备详情弹窗相关
  const deviceDetailDialogVisible = ref(false)
  const deviceDetailLoading = ref(false)
  const currentDeviceDetail = ref<any>(null)
  const deviceCards = ref<any[]>([])
  const deviceCardsLoading = ref(false)
  const deviceCardsDialogVisible = ref(false)

  // 绑定卡相关
  const bindCardLoading = ref(false)
  const bindCardFormRef = ref<FormInstance>()
  const iotCardList = ref<any[]>([])
  const iotCardSearchLoading = ref(false)
  const iotCardHasSearched = ref(false) // 标记是否已执行过搜索
  const bindCardForm = reactive({
    search_type: 'iccid' as 'iccid' | 'carrier_name',
    iot_card_id: undefined as number | undefined,
    slot_position: 1
  })
  const bindCardRules = reactive<FormRules>({
    search_type: [{ required: true, message: '请选择搜索类型', trigger: 'change' }],
    iot_card_id: [{ required: true, message: '请选择ICCID', trigger: 'change' }],
    slot_position: [{ required: true, message: '请选择插槽位置', trigger: 'change' }]
  })

  // 设备操作相关对话框

  const currentOperatingImei = ref<string>('') // 用于存储当前操作设备的IMEI
  const currentOperatingDevice = ref<Device | null>(null)

  const switchCardDialogVisible = ref(false)
  const switchCardLoading = ref(false)
  const deviceBindingCards = ref<any[]>([]) // 设备绑定的卡列表
  const loadingDeviceCards = ref(false) // 加载设备绑定卡列表的状态

  // 切换模式相关
  const switchModeDialogVisible = ref(false)
  const switchModeLoading = ref(false)
  const switchModeCards = ref<SwitchModeCardOption[]>([])
  const currentOperatingDeviceIdentifier = ref<string>('')
  const currentOperatingDeviceHasImei = ref(false)
  const currentDeviceSwitchMode = ref<number>(0)

  // 实名认证策略相关
  const realnamePolicyDialogVisible = ref(false)
  const currentRealnamePolicyAsset = ref<string>('')
  const currentRealnamePolicy = ref<string>('none')

  // 搜索表单初始值
  const initialSearchState = {
    virtual_no: '',
    imei: '',
    device_name: '',
    status: undefined as DeviceStatus | undefined,
    activation_status: undefined as number | undefined,
    real_name_status: undefined as 0 | 1 | undefined,
    batch_no: '',
    device_type: '',
    manufacturer: '',
    shop_id: undefined as number | undefined,
    series_id: undefined as number | undefined,
    has_active_package: undefined as boolean | undefined,
    authorized_enterprise_id: undefined as number | undefined,
    is_authorized_to_enterprise: undefined as boolean | undefined,
    dateRange: [] as string[],
    created_at_start: '',
    created_at_end: ''
  }

  // 搜索表单
  const searchForm = reactive<Record<string, any>>({ ...initialSearchState })

  // 搜索批次号（用于搜索表单）
  const loadSearchBatchNoOptions = async (batchNo?: string) => {
    try {
      const params: any = {
        page: 1,
        page_size: 20
      }
      if (batchNo) {
        params.batch_no = batchNo
      }
      const res = await CardService.getIotCardImportTasks(params)
      if (res.code === 0) {
        searchBatchNoOptions.value = res.data.items || []
      }
    } catch (error) {
      console.error('加载批次号选项失败:', error)
    }
  }

  // 搜索批次号
  const handleSearchBatchNo = (query: string) => {
    if (query) {
      loadSearchBatchNoOptions(query)
    } else {
      loadSearchBatchNoOptions()
    }
  }

  // 搜索表单配置
  const searchFormItems: SearchFormItem[] = [
    {
      label: '设备号',
      prop: 'virtual_no',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入设备号'
      }
    },
    {
      label: '设备名称',
      prop: 'device_name',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入设备名称'
      }
    },
    {
      label: 'IMEI',
      prop: 'imei',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入IMEI'
      }
    },
    {
      label: '虚拟号',
      prop: 'virtual_no',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入虚拟号'
      }
    },
    {
      label: '状态',
      prop: 'status',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '请选择状态'
      },
      options: () => [
        { label: '在库', value: 1 },
        { label: '已分销', value: 2 },
        { label: '已激活', value: 3 },
        { label: '已停用', value: 4 }
      ]
    },
    {
      label: '激活状态',
      prop: 'activation_status',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '请选择激活状态'
      },
      options: () => [
        { label: '未激活', value: 0 },
        { label: '已激活', value: 1 }
      ]
    },
    {
      label: '实名状态',
      prop: 'real_name_status',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '全部'
      },
      options: () => [
        { label: '已实名', value: 1 },
        { label: '未实名', value: 0 }
      ]
    },
    {
      label: '批次号',
      prop: 'batch_no',
      type: 'select',
      config: {
        clearable: true,
        filterable: true,
        remote: true,
        remoteMethod: handleSearchBatchNo,
        loading: false,
        placeholder: '请选择或搜索批次号'
      },
      options: () =>
        searchBatchNoOptions.value.map((b) => ({
          label: b.batch_no,
          value: b.batch_no
        }))
    },
    {
      label: '设备类型',
      prop: 'device_type',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入设备类型'
      }
    },
    {
      label: '制造商',
      prop: 'manufacturer',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入制造商'
      }
    },
    {
      label: '店铺名称',
      prop: 'shop_id',
      type: 'select',
      config: {
        clearable: true,
        filterable: true,
        remote: true,
        remoteMethod: (query: string) => searchShops(query),
        loading: false,
        placeholder: '请选择或搜索店铺名称'
      },
      options: () =>
        shopOptions.value.map((shop) => ({
          label: shop.shop_name,
          value: shop.id
        }))
    },
    {
      label: '套餐系列',
      prop: 'series_id',
      type: 'select',
      config: {
        clearable: true,
        filterable: true,
        remote: true,
        remoteMethod: (query: string) => searchSeries(query),
        loading: seriesLoading.value,
        placeholder: '请选择或搜索套餐系列'
      },
      options: () =>
        searchSeriesOptions.value.map((s) => ({
          label: s.series_name,
          value: s.id
        }))
    },
    {
      label: '起止时间',
      prop: 'dateRange',
      type: 'date',
      config: {
        type: 'daterange',
        rangeSeparator: '至',
        startPlaceholder: '开始时间',
        endPlaceholder: '结束时间',
        valueFormat: 'YYYY-MM-DD'
      }
    }
  ]

  // 分页
  searchFormItems.splice(searchFormItems.length - 1, 0, {
    label: '有效套餐',
    prop: 'has_active_package',
    type: 'select',
    config: {
      clearable: true,
      placeholder: '全部'
    },
    options: () => [
      { label: '是', value: true },
      { label: '否', value: false }
    ]
  })
  searchFormItems.splice(searchFormItems.length - 1, 0, {
    label: '授权企业',
    prop: 'authorized_enterprise_id',
    type: 'select',
    config: {
      clearable: true,
      filterable: true,
      remote: true,
      remoteMethod: (query: string) => handleSearchEnterprise(query),
      loading: enterpriseLoading.value,
      placeholder: '请选择或搜索企业'
    },
    options: () =>
      enterpriseOptions.value.map((enterprise) => ({
        label: enterprise.enterprise_name,
        value: enterprise.id
      }))
  })
  searchFormItems.splice(searchFormItems.length - 1, 0, {
    label: '授权状态',
    prop: 'is_authorized_to_enterprise',
    type: 'select',
    config: {
      clearable: true,
      placeholder: '全部'
    },
    options: () => [
      { label: '已授权', value: true },
      { label: '未授权', value: false }
    ]
  })

  const pagination = reactive({
    page: 1,
    pageSize: 20,
    total: 0
  })

  // 列配置
  const columnOptions = [
    { label: '设备号', prop: 'virtual_no' },
    { label: 'IMEI', prop: 'imei' },
    { label: '设备名称', prop: 'device_name' },
    { label: '店铺名称', prop: 'shop_name' },
    { label: '套餐系列', prop: 'series_name' },
    { label: '预计套餐到期时间', prop: 'estimated_final_expires_at' },
    { label: '设备型号', prop: 'device_model' },
    { label: '设备类型', prop: 'device_type' },
    { label: '状态', prop: 'status' },
    { label: '状态名称', prop: 'status_name' },
    { label: '资产世代', prop: 'generation' },
    { label: '业务状态', prop: 'asset_status' },
    { label: '激活状态', prop: 'activation_status_name' },
    { label: '实名状态', prop: 'real_name_status_name' },
    { label: '在线状态', prop: 'online_status' },
    { label: '实名策略', prop: 'realname_policy' },
    { label: '切卡模式', prop: 'switch_mode' },
    { label: '激活时间', prop: 'activated_at' },
    { label: '制造商', prop: 'manufacturer' },
    { label: '软件版本', prop: 'software_version' },
    { label: '最大插槽数', prop: 'max_sim_slots' },
    { label: '已绑定卡数', prop: 'bound_card_count' },
    { label: '序列号', prop: 'sn' },
    { label: '批次号', prop: 'batch_no' },
    { label: '最后在线时间', prop: 'last_online_time' },
    { label: '最后同步时间', prop: 'last_gateway_sync_at' },
    { label: '创建时间', prop: 'created_at' },
    { label: '操作', prop: 'operation' }
  ]

  const deviceList = ref<Device[]>([])

  // 分配表单
  const allocateForm = reactive({
    target_shop_id: undefined as number[] | undefined,
    remark: ''
  })

  // 分配表单验证规则
  const allocateRules = reactive<FormRules>({
    target_shop_id: [{ required: true, message: '请选择目标店铺', trigger: 'change' }]
  })

  // 回收表单
  const recallForm = reactive({
    remark: ''
  })

  // 跳转到资产信息页面(原设备详情)
  const goToDeviceSearchDetail = (deviceNo: string) => {
    if (hasAuth('device:view_detail')) {
      router.push({
        path: RoutesAlias.AssetInformation,
        query: {
          virtual_no: deviceNo
        }
      })
    } else {
      ElMessage.warning('您没有查看详情的权限')
    }
  }

  // 查看设备设备绑定的卡
  const handleViewCards = async (device: Device) => {
    currentDeviceDetail.value = device
    deviceCards.value = []
    deviceCardsDialogVisible.value = true
    // 重置绑定卡表单
    bindCardForm.search_type = 'iccid'
    bindCardForm.iot_card_id = undefined
    bindCardForm.slot_position = 1
    bindCardFormRef.value?.resetFields()
    // 加载未绑定设备的卡列表
    await Promise.all([loadDeviceCards(device.virtual_no), loadDefaultIotCards()])
  }

  // 加载设备绑定的卡列表
  const loadDeviceCards = async (virtualNo: string) => {
    deviceCardsLoading.value = true
    try {
      const res = await DeviceService.getDeviceCards(virtualNo)
      if (res.code === 0 && res.data) {
        deviceCards.value = (res.data.bindings || []).sort(
          (a, b) => a.slot_position - b.slot_position
        )
      }
    } catch (error) {
      console.error('获取设备绑定的卡列表失败:', error)
    } finally {
      deviceCardsLoading.value = false
    }
  }

  // 加载默认的IoT卡列表
  const loadDefaultIotCards = async () => {
    iotCardSearchLoading.value = true
    try {
      const res = await CardService.getStandaloneIotCards({
        page: 1,
        page_size: 20,
        is_standalone: true
      })
      if (res.code === 0 && res.data?.items) {
        iotCardList.value = res.data.items
      }
    } catch (error) {
      console.error('获取IoT卡列表失败:', error)
    } finally {
      iotCardSearchLoading.value = false
    }
  }

  // 搜索IoT卡（根据ICCID或运营商名称）
  const searchIotCards = async (query: string) => {
    if (!query) {
      await loadDefaultIotCards()
      return
    }
    iotCardSearchLoading.value = true
    iotCardHasSearched.value = true
    try {
      const params: any = {
        page: 1,
        page_size: 20,
        is_standalone: true
      }
      if (bindCardForm.search_type === 'iccid') {
        params.iccid = query
      } else if (bindCardForm.search_type === 'carrier_name') {
        params.carrier_name = query
      }
      const res = await CardService.getStandaloneIotCards(params)
      if (res.code === 0 && res.data?.items) {
        iotCardList.value = res.data.items
      }
    } catch (error) {
      console.error('搜索IoT卡失败:', error)
    } finally {
      iotCardSearchLoading.value = false
    }
  }

  // 确认绑定卡
  const handleConfirmBindCard = async () => {
    if (!bindCardFormRef.value || !currentDeviceDetail.value) return

    await bindCardFormRef.value.validate(async (valid) => {
      if (valid) {
        bindCardLoading.value = true
        try {
          const res = await DeviceService.bindCard(currentDeviceDetail.value.virtual_no, {
            iot_card_id: bindCardForm.iot_card_id!,
            slot_position: bindCardForm.slot_position
          })
          if (res.code === 0) {
            ElMessage.success('绑定成功')
            // 重置表单
            bindCardForm.iot_card_id = undefined
            bindCardForm.slot_position = 1
            bindCardFormRef.value?.resetFields()
            // 重新加载卡列表
            await loadDeviceCards(currentDeviceDetail.value.virtual_no)
            // 刷新设备详情以更新绑定卡数量
            const detailRes = await AssetService.resolveAsset(currentDeviceDetail.value.virtual_no)
            if (detailRes.code === 0 && detailRes.data) {
              currentDeviceDetail.value = detailRes.data
            }
          }
        } catch (error: any) {
          console.error('绑定卡失败:', error)
        } finally {
          bindCardLoading.value = false
        }
      }
    })
  }

  // 解绑卡
  const handleUnbindCard = (row: any) => {
    ElMessageBox.confirm(`确定要解绑 ICCID: ${row.iccid} 吗？`, '解绑确认', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(async () => {
        try {
          const res = await DeviceService.unbindCard(
            currentDeviceDetail.value.virtual_no,
            row.iccid
          )
          if (res.code === 0) {
            ElMessage.success('解绑成功')
            // 重新加载卡列表
            await loadDeviceCards(currentDeviceDetail.value.virtual_no)
            // 刷新设备详情以更新绑定卡数量
            const detailRes = await AssetService.resolveAsset(currentDeviceDetail.value.virtual_no)
            if (detailRes.code === 0 && detailRes.data) {
              currentDeviceDetail.value = detailRes.data
            }
          } else {
            ElMessage.error(res.msg || '解绑失败')
          }
        } catch (error: any) {
          console.error('解绑卡失败:', error)
        }
      })
      .catch(() => {
        // 用户取消
      })
  }

  // 获取网络状态标签类型
  const getNetworkStatusTagType = (networkStatus: number) => {
    // 0: 停机 (danger 红色)
    // 1: 开机 - 正常/异常 (success 绿色 / warning 黄色)
    if (networkStatus === 0) {
      return 'danger' // 停机 - 红色
    } else if (networkStatus === 1) {
      return 'success' // 开机正常 - 绿色
    }
    return 'info' // 未知状态
  }

  // 获取网络状态文本
  const getNetworkStatusText = (networkStatus: number) => {
    // 0: 停机
    // 1: 开机 - 显示为"正常"
    const textMap: Record<number, string> = {
      0: '停机',
      1: '正常' // 开机显示为"正常"
    }
    return textMap[networkStatus] || '未知'
  }

  // 获取设备状态标签类型
  const getDeviceStatusTagType = (status: number) => {
    const typeMap: Record<number, any> = {
      1: 'info', // 在库
      2: 'warning', // 已分销
      3: 'success', // 已激活
      4: 'danger' // 已停用
    }
    return typeMap[status] || 'info'
  }

  // 动态列配置
  const { columnChecks, columns } = useCheckedColumns(() => [
    {
      prop: 'virtual_no',
      label: '设备号',
      minWidth: 170,
      showOverflowTooltip: true,
      formatter: (row: Device) => {
        return h(
          'span',
          {
            style: 'color: var(--el-color-primary); cursor: pointer; text-decoration: underline;',
            onClick: (e: MouseEvent) => {
              e.stopPropagation()
              goToDeviceSearchDetail(row.virtual_no)
            }
          },
          row.virtual_no
        )
      }
    },
    {
      prop: 'imei',
      label: 'IMEI',
      minWidth: 150,
      showOverflowTooltip: true,
      formatter: (row: Device) => row.imei || '-'
    },
    {
      prop: 'device_name',
      label: '设备名称',
      showOverflowTooltip: true,
      minWidth: 150
    },
    {
      prop: 'shop_name',
      label: '店铺名称',
      minWidth: 120
    },
    {
      prop: 'series_name',
      label: '套餐系列',
      minWidth: 180,
      showOverflowTooltip: true
    },
    {
      prop: 'estimated_final_expires_at',
      label: '预计套餐到期时间',
      width: 180,
      formatter: (row: Device) =>
        h(
          'span',
          {
            class: { 'expiry-estimate--expiring': row.is_expiring },
            title: getExpiryEstimateTooltip(row)
          },
          getExpiryEstimateText(row)
        )
    },
    {
      prop: 'device_model',
      label: '设备型号',
      minWidth: 120
    },
    {
      prop: 'device_type',
      label: '设备类型',
      width: 120
    },
    {
      prop: 'status',
      label: '状态',
      width: 100,
      formatter: (row: Device) => {
        const statusMap: Record<number, { text: string; type: any }> = {
          1: { text: '在库', type: 'info' },
          2: { text: '已分销', type: 'primary' },
          3: { text: '已激活', type: 'success' },
          4: { text: '已停用', type: 'danger' }
        }
        const status = statusMap[row.status] || { text: '未知', type: 'info' }
        return h(ElTag, { type: status.type }, () => status.text)
      }
    },
    {
      prop: 'status_name',
      label: '状态名称',
      width: 100,
      formatter: (row: Device) => row.status_name || '-'
    },
    {
      prop: 'generation',
      label: '资产世代',
      width: 100,
      formatter: (row: Device) => row.generation ?? '-'
    },
    {
      prop: 'asset_status',
      label: '业务状态',
      width: 100,
      formatter: (row: Device) => {
        const assetStatusMap: Record<number, { text: string; type: any }> = {
          1: { text: '在库', type: 'info' },
          2: { text: '已销售', type: 'success' },
          3: { text: '已换货', type: 'warning' },
          4: { text: '已停用', type: 'danger' }
        }
        if (row.asset_status == null) return '-'
        const status = assetStatusMap[row.asset_status] || { text: '未知', type: 'info' }
        return h(ElTag, { type: status.type }, () => status.text)
      }
    },
    {
      prop: 'activation_status_name',
      label: '激活状态',
      width: 120,
      formatter: (row: Device) => row.activation_status_name || '-'
    },
    {
      prop: 'real_name_status_name',
      label: '实名状态',
      width: 100,
      formatter: (row: Device) => row.real_name_status_name || '-'
    },
    {
      prop: 'online_status',
      label: '在线状态',
      width: 100,
      formatter: (row: Device) => {
        const onlineStatusMap: Record<number, { text: string; type: any }> = {
          0: { text: '未知', type: 'info' },
          1: { text: '在线', type: 'success' },
          2: { text: '离线', type: 'danger' }
        }
        const status = onlineStatusMap[row.online_status ?? 0] || { text: '未知', type: 'info' }
        return h(ElTag, { type: status.type }, () => status.text)
      }
    },
    {
      prop: 'realname_policy',
      label: '实名策略',
      width: 150,
      formatter: (row: Device) => {
        const policy = row.realname_policy || ''
        const policyMap: Record<string, string> = {
          none: '无需实名',
          before_order: '先实名后充值/购买',
          after_order: '先充值/购买后实名'
        }
        return policyMap[policy] || (policy ? policy : '未知')
      }
    },
    {
      prop: 'switch_mode',
      label: '切卡模式',
      width: 100,
      formatter: (row: Device) => {
        const modeMap: Record<string, string> = {
          '0': '自动',
          '1': '手动'
        }
        return modeMap[row.switch_mode || ''] || '-'
      }
    },
    {
      prop: 'activated_at',
      label: '激活时间',
      width: 180,
      formatter: (row: Device) => (row.activated_at ? formatDateTime(row.activated_at) : '-')
    },
    {
      prop: 'manufacturer',
      label: '制造商',
      minWidth: 100
    },
    {
      prop: 'software_version',
      label: '软件版本',
      minWidth: 180,
      showOverflowTooltip: true,
      formatter: (row: Device) => row.software_version || '-'
    },
    {
      prop: 'max_sim_slots',
      label: '最大插槽数',
      width: 100
    },
    {
      prop: 'bound_card_count',
      label: '已绑定卡数',
      width: 110,
      formatter: (row: Device) => {
        const color = row.bound_card_count > 0 ? '#67c23a' : '#909399'
        return h('span', { style: { color, fontWeight: 'bold' } }, row.bound_card_count)
      }
    },
    {
      prop: 'sn',
      label: '序列号',
      minWidth: 120,
      showOverflowTooltip: true,
      formatter: (row: Device) => row.sn || '-'
    },
    {
      prop: 'batch_no',
      label: '批次号',
      minWidth: 180,
      showOverflowTooltip: true,
      formatter: (row: Device) => row.batch_no || '-'
    },
    {
      prop: 'last_online_time',
      label: '最后在线时间',
      width: 180,
      formatter: (row: Device) =>
        row.last_online_time ? formatDateTime(row.last_online_time) : '-'
    },
    {
      prop: 'last_gateway_sync_at',
      label: '最后同步时间',
      width: 180,
      formatter: (row: Device) =>
        row.last_gateway_sync_at ? formatDateTime(row.last_gateway_sync_at) : '-'
    },
    {
      prop: 'created_at',
      label: '创建时间',
      width: 180,
      formatter: (row: Device) => formatDateTime(row.created_at)
    }
  ])

  // 搜索店铺（用于搜索表单）
  const searchShops = async (query: string) => {
    try {
      const params: any = {
        page: 1,
        page_size: 20
      }
      if (query) {
        params.shop_name = query
      }
      const res = await ShopService.getShops(params)
      if (res.code === 0) {
        shopOptions.value = res.data.items || []
      }
    } catch (error) {
      console.error('搜索店铺失败:', error)
    }
  }

  // 搜索套餐系列（用于搜索表单）
  const searchSeries = async (query: string) => {
    try {
      const params: any = {
        page: 1,
        page_size: 20,
        status: 1
      }
      if (query) {
        params.series_name = query
      }
      const res = await PackageSeriesService.getPackageSeries(params)
      if (res.code === 0) {
        searchSeriesOptions.value = res.data.items || []
      }
    } catch (error) {
      console.error('搜索套餐系列失败:', error)
    }
  }

  const handleSearchEnterprise = async (query?: string) => {
    try {
      enterpriseLoading.value = true
      const params = {
        page: 1,
        page_size: 20,
        enterprise_name: query || undefined,
        status: 1
      }
      const res = await EnterpriseService.getEnterprises(params)
      if (res.code === 0) {
        enterpriseOptions.value = res.data.items || []
      }
    } catch (error) {
      console.error('搜索企业失败:', error)
    } finally {
      enterpriseLoading.value = false
    }
  }

  let isFirstActivation = true
  onMounted(() => {
    getTableData()
  })

  // 当页面被 keep-alive 激活时自动刷新数据
  onActivated(() => {
    if (!isFirstActivation) {
      getTableData()
    }
    isFirstActivation = false
  })

  // 获取设备列表
  const getTableData = async () => {
    loading.value = true
    try {
      const params = {
        page: pagination.page,
        page_size: pagination.pageSize,
        virtual_no: searchForm.virtual_no || undefined,
        imei: searchForm.imei || undefined,
        device_name: searchForm.device_name || undefined,
        status: searchForm.status,
        activation_status: searchForm.activation_status ?? undefined,
        real_name_status: searchForm.real_name_status ?? undefined,
        batch_no: searchForm.batch_no || undefined,
        device_type: searchForm.device_type || undefined,
        manufacturer: searchForm.manufacturer || undefined,
        shop_id: searchForm.shop_id || undefined,
        series_id: searchForm.series_id || undefined,
        has_active_package: searchForm.has_active_package ?? undefined,
        authorized_enterprise_id: searchForm.authorized_enterprise_id || undefined,
        is_authorized_to_enterprise: searchForm.is_authorized_to_enterprise ?? undefined,
        created_at_start: searchForm.created_at_start || undefined,
        created_at_end: searchForm.created_at_end || undefined
      }
      const res = await DeviceService.getDevices(params)
      if (res.code === 0 && res.data) {
        deviceList.value = res.data.items || []
        pagination.total = res.data.total || 0
      }
    } catch (error) {
      console.error(error)
    } finally {
      loading.value = false
    }
  }

  const exportQuery = computed(() => {
    const query: Record<string, unknown> = {
      virtual_no: searchForm.virtual_no || undefined,
      imei: searchForm.imei || undefined,
      device_name: searchForm.device_name || undefined,
      status: searchForm.status,
      activation_status: searchForm.activation_status ?? undefined,
      real_name_status: searchForm.real_name_status ?? undefined,
      batch_no: searchForm.batch_no || undefined,
      device_type: searchForm.device_type || undefined,
      manufacturer: searchForm.manufacturer || undefined,
      shop_id: searchForm.shop_id || undefined,
      series_id: searchForm.series_id || undefined,
      has_active_package: searchForm.has_active_package ?? undefined,
      authorized_enterprise_id: searchForm.authorized_enterprise_id || undefined,
      is_authorized_to_enterprise: searchForm.is_authorized_to_enterprise ?? undefined,
      created_at_start: searchForm.created_at_start || undefined,
      created_at_end: searchForm.created_at_end || undefined
    }

    Object.keys(query).forEach((key) => {
      if (query[key] === undefined || query[key] === null || query[key] === '') {
        delete query[key]
      }
    })

    return query
  })

  const showExportDialog = () => {
    exportDialogVisible.value = true
  }

  // 重置搜索
  const handleReset = () => {
    Object.assign(searchForm, { ...initialSearchState })
    pagination.page = 1
    getTableData()
  }

  // 搜索
  const handleSearch = () => {
    // 处理日期范围
    if (searchForm.dateRange && Array.isArray(searchForm.dateRange)) {
      searchForm.created_at_start = searchForm.dateRange[0] || ''
      searchForm.created_at_end = searchForm.dateRange[1] || ''
    } else {
      searchForm.created_at_start = ''
      searchForm.created_at_end = ''
    }
    pagination.page = 1
    getTableData()
  }

  // 刷新表格
  const handleRefresh = () => {
    getTableData()
  }

  // 处理表格分页变化
  const handleSizeChange = (newPageSize: number) => {
    pagination.pageSize = newPageSize
    getTableData()
  }

  const handleCurrentChange = (newCurrentPage: number) => {
    pagination.page = newCurrentPage
    getTableData()
  }

  // 处理选择变化
  const handleSelectionChange = (selection: Device[]) => {
    selectedDevices.value = selection
  }

  const showBatchRealnamePolicyDialog = () => {
    if (selectedDevices.value.length === 0) {
      ElMessage.warning('请先选择要修改的设备')
      return
    }

    batchRealnamePolicyError.value = ''
    batchRealnamePolicyDialogVisible.value = true
  }

  const handleConfirmBatchRealnamePolicy = async (realnamePolicy: AssetRealnamePolicy) => {
    const assetIds = selectedDevices.value.map((device) => device.id)
    if (assetIds.length === 0) {
      batchRealnamePolicyError.value = '请先选择要修改的设备'
      return
    }
    if (assetIds.length > 500) {
      batchRealnamePolicyError.value = '单次最多可修改500台设备'
      return
    }

    batchRealnamePolicyError.value = ''
    batchRealnamePolicyLoading.value = true
    try {
      const res = await DeviceService.batchUpdateRealnamePolicy(
        { asset_ids: assetIds, realname_policy: realnamePolicy },
        { requestOptions: { errorMessageMode: 'none' } }
      )
      if (res.code !== 0) {
        batchRealnamePolicyError.value = res.msg || '批量修改实名顺序失败'
        return
      }

      ElMessage.success('批量修改实名顺序成功')
      batchRealnamePolicyDialogVisible.value = false
      selectedDevices.value = []
      await getTableData()
    } catch (error: any) {
      batchRealnamePolicyError.value = error?.response?.data?.msg || '批量修改实名顺序失败'
    } finally {
      batchRealnamePolicyLoading.value = false
    }
  }

  // 删除设备
  const deleteDevice = (row: Device) => {
    ElMessageBox.confirm(
      `确定删除设备 ${row.virtual_no} 吗？删除后将自动解绑所有卡。`,
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'error'
      }
    )
      .then(async () => {
        try {
          await DeviceService.deleteDevice(row.virtual_no)
          ElMessage.success('删除成功')
          await getTableData()
        } catch (error) {
          console.error(error)
        }
      })
      .catch(() => {
        // 用户取消
      })
  }

  // 清除设备套餐系列绑定
  const handleClearDeviceSeries = async (deviceNo: string) => {
    const device = deviceList.value.find((d) => d.virtual_no === deviceNo)
    if (!device) {
      ElMessage.error('未找到该设备')
      return
    }

    ElMessageBox.confirm(`确定要清除设备 ${deviceNo} 的套餐系列关联吗？`, '确认清除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(async () => {
        try {
          const res = await DeviceService.batchSetDeviceSeriesBinding({
            selection_type: DeviceSelectionType.LIST,
            device_ids: [device.id],
            series_id: 0
          })
          if (res.code === 0) {
            if (res.data.fail_count === 0) {
              ElMessage.success('清除关联成功')
            } else {
              ElMessage.warning(`部分失败：${res.data.failed_items?.[0]?.reason || '未知原因'}`)
            }
            await getTableData()
          }
        } catch (error) {
          console.error('清除关联失败:', error)
        }
      })
      .catch(() => {
        // 用户取消
      })
  }

  // 批量分配
  const handleBatchAllocate = async () => {
    if (selectedDevices.value.length === 0) {
      ElMessage.warning('请先选择要分配的设备')
      return
    }
    allocateForm.target_shop_id = undefined
    allocateForm.remark = ''
    allocateResult.value = null
    shopCascadeOptions.value = []
    allocateDialogVisible.value = true
  }

  // 确认批量分配
  const handleConfirmAllocate = async () => {
    if (!allocateFormRef.value) return

    await allocateFormRef.value.validate(async (valid) => {
      if (valid) {
        allocateLoading.value = true
        try {
          const targetShopPath = allocateForm.target_shop_id
          if (!targetShopPath?.length) {
            ElMessage.warning('请选择目标店铺')
            return
          }

          const data = {
            device_ids: selectedDevices.value.map((d) => d.id),
            target_shop_id: targetShopPath[targetShopPath.length - 1],
            remark: allocateForm.remark
          }
          const res = await DeviceService.allocateDevices(data)
          if (res.code === 0) {
            allocateResult.value = res.data
            if (res.data.fail_count === 0) {
              ElMessage.success('全部分配成功')
              setTimeout(() => {
                handleCloseAllocateDialog()
                getTableData()
              }, 1500)
            } else {
              ElMessage.warning(`部分分配失败，请查看失败详情`)
            }
          }
        } catch (error) {
          console.error(error)
        } finally {
          allocateLoading.value = false
        }
      }
    })
  }

  // 关闭分配对话框
  const handleCloseAllocateDialog = () => {
    allocateDialogVisible.value = false
    allocateResult.value = null
    if (allocateFormRef.value) {
      allocateFormRef.value.resetFields()
    }
  }

  // 批量回收
  const handleBatchRecall = () => {
    if (selectedDevices.value.length === 0) {
      ElMessage.warning('请先选择要回收的设备')
      return
    }
    recallForm.remark = ''
    recallResult.value = null
    recallDialogVisible.value = true
  }

  // 确认批量回收
  const handleConfirmRecall = async () => {
    recallLoading.value = true
    try {
      const data = {
        device_ids: selectedDevices.value.map((d) => d.id),
        remark: recallForm.remark
      }
      const res = await DeviceService.recallDevices(data)
      if (res.code === 0) {
        recallResult.value = res.data
        if (res.data.fail_count === 0) {
          ElMessage.success('全部回收成功')
          setTimeout(() => {
            handleCloseRecallDialog()
            getTableData()
          }, 1500)
        } else {
          ElMessage.warning(`部分回收失败，请查看失败详情`)
        }
      }
    } catch (error) {
      console.error(error)
    } finally {
      recallLoading.value = false
    }
  }

  // 关闭回收对话框
  const handleCloseRecallDialog = () => {
    recallDialogVisible.value = false
    recallResult.value = null
    recallForm.remark = ''
  }

  const getInferredDeviceEnterpriseId = () => {
    const filterEnterpriseId = searchForm.authorized_enterprise_id
    if (filterEnterpriseId) return filterEnterpriseId

    const selectedEnterpriseIds = Array.from(
      new Set(
        selectedDevices.value
          .map((device) => device.authorized_enterprise_id)
          .filter((id): id is number => typeof id === 'number')
      )
    )

    return selectedEnterpriseIds.length === 1 ? selectedEnterpriseIds[0] : undefined
  }

  const resetEnterpriseDeviceAuthorizeForm = () => {
    Object.assign(enterpriseDeviceAuthorizeForm, createInitialEnterpriseDeviceAuthorizeState(), {
      selection_type:
        selectedDevices.value.length > 0 ? DeviceSelectionType.LIST : DeviceSelectionType.FILTER,
      virtual_no: searchForm.virtual_no || '',
      batch_no: searchForm.batch_no || '',
      shop_id_path: undefined
    })
  }

  const resetEnterpriseDeviceRecallForm = () => {
    Object.assign(enterpriseDeviceRecallForm, createInitialEnterpriseDeviceRecallState(), {
      enterprise_id: getInferredDeviceEnterpriseId(),
      selection_type:
        selectedDevices.value.length > 0 ? DeviceSelectionType.LIST : DeviceSelectionType.FILTER,
      virtual_no: searchForm.virtual_no || '',
      batch_no: searchForm.batch_no || ''
    })
  }

  const showEnterpriseDeviceAuthorizeDialog = async () => {
    resetEnterpriseDeviceAuthorizeForm()
    await Promise.all([
      handleSearchEnterprise(),
      loadSearchBatchNoOptions(),
      loadTopLevelShopCascadeOptions()
    ])
    enterpriseDeviceAuthorizeDialogVisible.value = true
    enterpriseDeviceAuthorizeFormRef.value?.clearValidate()
  }

  const showEnterpriseDeviceRecallDialog = async () => {
    resetEnterpriseDeviceRecallForm()
    await Promise.all([handleSearchEnterprise(), loadSearchBatchNoOptions()])
    enterpriseDeviceRecallDialogVisible.value = true
    enterpriseDeviceRecallFormRef.value?.clearValidate()
  }

  const handleEnterpriseDeviceAuthorizeDialogClose = () => {
    Object.assign(enterpriseDeviceAuthorizeForm, createInitialEnterpriseDeviceAuthorizeState())
    enterpriseDeviceAuthorizeFormRef.value?.resetFields()
  }

  const handleEnterpriseDeviceRecallDialogClose = () => {
    Object.assign(enterpriseDeviceRecallForm, createInitialEnterpriseDeviceRecallState())
    enterpriseDeviceRecallFormRef.value?.resetFields()
  }

  const buildEnterpriseDeviceParams = (form: any) => {
    const params: Record<string, unknown> = {
      selection_type: form.selection_type,
      remark: form.remark || undefined
    }

    if (form.selection_type === DeviceSelectionType.LIST) {
      const deviceNos = selectedDevices.value.map((device) => device.virtual_no).filter(Boolean)
      if (!deviceNos.length) {
        ElMessage.warning('列表模式下请先选择设备')
        return null
      }
      params.device_nos = deviceNos
    } else {
      if (form.batch_no) params.batch_no = form.batch_no
      if (Array.isArray(form.shop_id_path) && form.shop_id_path.length > 0) {
        params.shop_id = form.shop_id_path[form.shop_id_path.length - 1]
      }
      if (form.virtual_no) params.virtual_no = form.virtual_no
    }

    Object.keys(params).forEach((key) => {
      if (params[key] === undefined || params[key] === '') delete params[key]
    })

    return params
  }

  const applyEnterpriseDeviceOperationSuccess = async (
    title: string,
    result: EnterpriseAllocateDevicesResponse | EnterpriseRecallDevicesResponse
  ) => {
    enterpriseDeviceOperationResult.value = result
    enterpriseDeviceResultTitle.value = title
    enterpriseDeviceResultDialogVisible.value = true
    selectedDevices.value = []
    await getTableData()
  }

  const handleEnterpriseDeviceAuthorize = async () => {
    if (!enterpriseDeviceAuthorizeFormRef.value) return

    await enterpriseDeviceAuthorizeFormRef.value.validate(async (valid) => {
      if (!valid) return
      const params = buildEnterpriseDeviceParams(enterpriseDeviceAuthorizeForm)
      if (!params) return

      enterpriseDeviceAuthorizeLoading.value = true
      try {
        const res = await EnterpriseService.allocateDevices(
          enterpriseDeviceAuthorizeForm.enterprise_id!,
          params as any
        )
        if (res.code === 0) {
          enterpriseDeviceAuthorizeDialogVisible.value = false
          await applyEnterpriseDeviceOperationSuccess('授权设备给企业结果', res.data)
        }
      } catch (error) {
        console.error('授权设备给企业失败:', error)
      } finally {
        enterpriseDeviceAuthorizeLoading.value = false
      }
    })
  }

  const handleEnterpriseDeviceRecall = async () => {
    if (!enterpriseDeviceRecallFormRef.value) return

    await enterpriseDeviceRecallFormRef.value.validate(async (valid) => {
      if (!valid) return
      const params = buildEnterpriseDeviceParams(enterpriseDeviceRecallForm)
      if (!params) return

      enterpriseDeviceRecallLoading.value = true
      try {
        const res = await EnterpriseService.recallDevices(
          enterpriseDeviceRecallForm.enterprise_id!,
          params as any
        )
        if (res.code === 0) {
          enterpriseDeviceRecallDialogVisible.value = false
          await applyEnterpriseDeviceOperationSuccess('撤销设备授权结果', res.data)
        }
      } catch (error) {
        console.error('撤销设备授权失败:', error)
      } finally {
        enterpriseDeviceRecallLoading.value = false
      }
    })
  }

  // 批量设置套餐系列
  const handleBatchSetSeries = async () => {
    seriesBindingResult.value = null
    Object.assign(seriesBindingForm, createInitialSeriesBindingState(), {
      selection_type:
        selectedDevices.value.length > 0 ? DeviceSelectionType.LIST : DeviceSelectionType.FILTER
    })
    await Promise.all([
      loadPackageSeriesList(),
      loadSearchBatchNoOptions(),
      loadSeriesBindingShopCascadeOptions()
    ])
    seriesBindingDialogVisible.value = true
    seriesBindingFormRef.value?.clearValidate()
  }

  // 加载套餐系列列表（支持名称搜索，默认20条）
  const loadPackageSeriesList = async (seriesName?: string) => {
    seriesLoading.value = true
    try {
      const params: any = {
        page: 1,
        page_size: 20,
        status: 1 // 只获取启用的
      }
      if (seriesName) {
        params.series_name = seriesName
      }
      const res = await PackageSeriesService.getPackageSeries(params)
      if (res.code === 0 && res.data.items) {
        packageSeriesList.value = res.data.items
      }
    } catch (error) {
      console.error('获取套餐系列列表失败:', error)
    } finally {
      seriesLoading.value = false
    }
  }

  // 搜索套餐系列
  const searchPackageSeries = async (query: string) => {
    await loadPackageSeriesList(query || undefined)
  }

  const loadSeriesBindingShopCascadeOptions = async () => {
    try {
      const res = await ShopService.getShopsCascade({
        parent_id: undefined,
        exclude_self: true
      })
      if (res.code === 0) {
        seriesBindingShopCascadeOptions.value = (res.data || []).map((item: any) => ({
          value: item.id,
          label: item.shop_name,
          leaf: !item.has_children
        }))
      }
    } catch (error) {
      console.error('加载批量设置套餐系列根级店铺失败:', error)
    }
  }

  const buildSeriesBindingRequest = (): BatchSetDeviceSeriesBindingRequest | null => {
    const request: BatchSetDeviceSeriesBindingRequest = {
      selection_type: seriesBindingForm.selection_type,
      series_id: seriesBindingForm.series_id!
    }

    if (seriesBindingForm.selection_type === DeviceSelectionType.LIST) {
      const deviceIds = selectedDevices.value.map((device) => device.id)
      if (deviceIds.length === 0) {
        ElMessage.warning('列表模式下请先选择要设置的设备')
        return null
      }
      request.device_ids = deviceIds
      return request
    }

    if (seriesBindingForm.selection_type === DeviceSelectionType.RANGE) {
      request.virtual_no_start = seriesBindingForm.virtual_no_start
      request.virtual_no_end = seriesBindingForm.virtual_no_end
      return request
    }

    if (seriesBindingForm.virtual_no) request.virtual_no = seriesBindingForm.virtual_no
    if (seriesBindingForm.device_name) request.device_name = seriesBindingForm.device_name
    if (seriesBindingForm.device_type) request.device_type = seriesBindingForm.device_type
    if (seriesBindingForm.manufacturer) request.manufacturer = seriesBindingForm.manufacturer
    if (seriesBindingForm.batch_no) request.batch_no = seriesBindingForm.batch_no
    if (seriesBindingForm.status !== undefined) request.status = seriesBindingForm.status
    if (seriesBindingForm.shop_id_path?.length) {
      request.shop_id = seriesBindingForm.shop_id_path[seriesBindingForm.shop_id_path.length - 1]
    }
    if (seriesBindingForm.filter_series_id !== undefined) {
      request.filter_series_id = seriesBindingForm.filter_series_id
    }
    if (seriesBindingForm.created_at_range.length === 2) {
      request.created_at_start = seriesBindingForm.created_at_range[0]
      request.created_at_end = seriesBindingForm.created_at_range[1]
    }

    return request
  }

  // 确认设置套餐系列绑定
  const handleConfirmSeriesBinding = async () => {
    if (!seriesBindingFormRef.value) return

    await seriesBindingFormRef.value.validate(async (valid) => {
      if (valid) {
        seriesBindingLoading.value = true
        try {
          const data = buildSeriesBindingRequest()
          if (!data) {
            return
          }
          const res = await DeviceService.batchSetDeviceSeriesBinding(data)
          if (res.code === 0) {
            seriesBindingResult.value = res.data
            if (res.data.fail_count === 0) {
              ElMessage.success('全部设置成功')
              setTimeout(() => {
                handleCloseSeriesBindingDialog()
                getTableData()
              }, 1500)
            } else {
              ElMessage.warning(`部分设置失败，请查看失败详情`)
            }
          }
        } catch (error) {
          console.error(error)
        } finally {
          seriesBindingLoading.value = false
        }
      }
    })
  }

  // 关闭套餐系列绑定对话框
  const handleCloseSeriesBindingDialog = () => {
    seriesBindingDialogVisible.value = false
    seriesBindingResult.value = null
    Object.assign(seriesBindingForm, createInitialSeriesBindingState())
    if (seriesBindingFormRef.value) {
      seriesBindingFormRef.value.resetFields()
    }
  }

  // ========== 设备操作相关 ==========

  // 获取设备IMEI(通过virtual_no)
  const getDeviceImei = async (virtualNo: string): Promise<string | null> => {
    try {
      const res = await AssetService.resolveAsset(virtualNo)
      if (res.code === 0 && res.data && res.data.asset_type === 'device') {
        return res.data.imei || null
      }
      return null
    } catch (error) {
      console.error('获取设备IMEI失败:', error)
      return null
    }
  }

  // 设备操作路由
  const handleDeviceOperation = async (command: string, deviceNo: string, device?: Device) => {
    // 设置当前操作的设备
    currentOperatingDevice.value = device || null

    switch (command) {
      case 'view-cards':
        handleViewCardsByDeviceNo(deviceNo)
        break
      case 'reboot': {
        const imei = device?.imei || (await getDeviceImei(deviceNo))
        if (!imei) {
          ElMessage.error('无法获取设备IMEI,无法执行重启操作')
          return
        }
        handleRebootDevice(imei)
        break
      }
      case 'reset': {
        const imei = device?.imei || (await getDeviceImei(deviceNo))
        if (!imei) {
          ElMessage.error('无法获取设备IMEI,无法执行重置操作')
          return
        }
        handleResetDevice(imei)
        break
      }
      case 'switch-card': {
        const imei = device?.imei || (await getDeviceImei(deviceNo))
        if (!imei) {
          ElMessage.error('无法获取设备IMEI,无法执行切卡操作')
          return
        }
        await showSwitchCardDialog(imei)
        break
      }
      case 'manual-deactivate':
        handleManualDeactivateDevice()
        break
      case 'delete':
        await handleDeleteDeviceByNo(deviceNo)
        break
      case 'clear-series':
        await handleClearDeviceSeries(deviceNo)
        break
      case 'switch-mode':
        await showSwitchModeDialog(deviceNo)
        break
      case 'realname-policy':
        showRealnamePolicyDialog(deviceNo, device?.realname_policy)
        break
    }
  }

  // 显示实名认证策略对话框
  const showRealnamePolicyDialog = (deviceNo: string, currentPolicy?: string) => {
    currentRealnamePolicyAsset.value = deviceNo
    currentRealnamePolicy.value = currentPolicy ?? 'none'
    realnamePolicyDialogVisible.value = true
  }

  // 确认设置实名认证策略
  const handleConfirmRealnamePolicy = async (data: { realname_policy: string }) => {
    try {
      const res = await AssetService.updateRealnamePolicy(
        currentRealnamePolicyAsset.value,
        data.realname_policy
      )
      if (res.code === 0) {
        ElMessage.success('设置实名认证策略成功')
        realnamePolicyDialogVisible.value = false
        await getTableData()
      } else {
        ElMessage.error(res.msg || '设置失败')
      }
    } catch (error) {
      console.error('设置实名认证策略失败:', error)
    }
  }

  // 通过设备号设备绑定的卡
  const handleViewCardsByDeviceNo = (deviceNo: string) => {
    const device = deviceList.value.find((d) => d.virtual_no === deviceNo)
    if (device) {
      handleViewCards(device)
    } else {
      ElMessage.error('未找到该设备')
    }
  }

  // 手动停用设备（资产层面的停用）
  const handleManualDeactivateDevice = () => {
    const device = currentOperatingDevice.value
    if (!device) {
      ElMessage.error('未找到设备信息')
      return
    }

    ElMessageBox.confirm(
      `确定要手动停用设备 ${device.virtual_no} 吗？此操作将在资产管理层面停用该设备。`,
      '确认手动停用',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
      .then(async () => {
        try {
          const res = await AssetService.deactivateAsset(device.virtual_no)
          if (res.code === 0) {
            ElMessage.success('手动停用成功')
            await getTableData()
          }
        } catch (error: any) {
          console.error('手动停用失败:', error)
        }
      })
      .catch(() => {
        // 用户取消
      })
  }

  // 通过设备号删除设备
  const handleDeleteDeviceByNo = async (deviceNo: string) => {
    // 先根据设备号找到设备对象
    const device = deviceList.value.find((d) => d.virtual_no === deviceNo)
    if (device) {
      deleteDevice(device)
    } else {
      ElMessage.error('未找到该设备')
    }
  }

  // 重启设备
  const handleRebootDevice = (imei: string) => {
    ElMessageBox.confirm(`确定要重启设备 ${imei} 吗？`, '重启确认', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(async () => {
        try {
          const res = await DeviceService.rebootDevice(imei)
          if (res.code === 0) {
            ElMessage.success('重启指令已发送')
          } else {
            ElMessage.error(res.msg || '重启失败')
          }
        } catch (error: any) {
          console.error('重启设备失败:', error)
        }
      })
      .catch(() => {
        // 用户取消
      })
  }

  // 恢复出厂设置
  const handleResetDevice = (imei: string) => {
    ElMessageBox.confirm(
      `确定要恢复设备 ${imei} 的出厂设置吗？此操作将清除所有配置和数据！`,
      '恢复出厂设置确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'error'
      }
    )
      .then(async () => {
        try {
          const res = await DeviceService.resetDevice(imei)
          if (res.code === 0) {
            ElMessage.success('恢复出厂设置指令已发送')
          } else {
            ElMessage.error(res.msg || '操作失败')
          }
        } catch (error: any) {
          console.error('恢复出厂设置失败:', error)
        }
      })
      .catch(() => {
        // 用户取消
      })
  }

  // 显示切换SIM卡对话框
  const showSwitchCardDialog = async (imei: string) => {
    currentOperatingImei.value = imei
    deviceBindingCards.value = []
    switchCardDialogVisible.value = true

    // 使用当前操作的设备
    const device = currentOperatingDevice.value
    if (!device) {
      ElMessage.error('未找到设备信息')
      return
    }

    // 加载设备绑定的卡列表
    loadingDeviceCards.value = true
    try {
      const res = await DeviceService.getDeviceCards(device.virtual_no)
      if (res.code === 0 && res.data) {
        deviceBindingCards.value = res.data.bindings || []
        if (deviceBindingCards.value.length === 0) {
          ElMessage.warning('该设备暂无绑定的SIM卡')
        }
      }
    } catch (error) {
      console.error('加载设备绑定卡列表失败:', error)
    } finally {
      loadingDeviceCards.value = false
    }
  }

  // 确认切换SIM卡
  const handleConfirmSwitchCard = async (data: { target_iccid: string }) => {
    try {
      const res = await DeviceService.switchCard(currentOperatingImei.value, {
        target_iccid: data.target_iccid
      })
      if (res.code === 0) {
        ElMessage.success('切换SIM卡指令已发送')
        switchCardDialogVisible.value = false
      } else {
        ElMessage.error(res.msg || '切换失败')
      }
    } catch (error: any) {
      console.error('切换SIM卡失败:', error)
    }
  }

  // 显示切换模式对话框
  const normalizeSwitchModeCards = (cards: Array<Record<string, any>>): SwitchModeCardOption[] => {
    return cards
      .map((card) => ({
        iot_card_id: Number(card.iot_card_id),
        iccid: card.iccid,
        slot_position: card.slot_position,
        carrier_name: card.carrier_name,
        msisdn: card.msisdn,
        network_status: card.network_status === undefined ? undefined : Number(card.network_status),
        real_name_status:
          card.real_name_status === undefined ? undefined : Number(card.real_name_status),
        is_current: card.is_current
      }))
      .filter((card) => Number.isFinite(card.iot_card_id) && Boolean(card.iccid))
  }

  // 显示切换模式对话框
  const showSwitchModeDialog = async (deviceIdentifier: string) => {
    const device = currentOperatingDevice.value
    if (!device) {
      ElMessage.error('未找到设备信息')
      return
    }

    currentOperatingDeviceIdentifier.value = deviceIdentifier
    currentDeviceSwitchMode.value = Number(device.switch_mode ?? 0)
    currentOperatingDeviceHasImei.value = Boolean(device.imei)
    switchModeCards.value = []

    if (currentOperatingDeviceHasImei.value) {
      try {
        const res = await DeviceService.getDeviceCards(device.virtual_no)
        if (res.code !== 0 || !res.data) {
          ElMessage.error(res.msg || '加载设备绑定卡失败')
          return
        }

        switchModeCards.value = normalizeSwitchModeCards(
          (res.data.bindings || []) as Array<Record<string, any>>
        )
      } catch (error) {
        console.error('加载切卡模式绑定卡失败:', error)
        ElMessage.error('加载设备绑定卡失败')
        return
      }
    }

    switchModeDialogVisible.value = true
  }

  // 确认切换模式
  const handleConfirmSwitchMode = async (data: { iot_card_id: number; switch_mode: 0 | 1 }) => {
    switchModeLoading.value = true
    try {
      const res = await DeviceService.setSwitchMode(currentOperatingDeviceIdentifier.value, data)
      if (res.code === 0) {
        ElMessage.success('设置切卡模式成功')
        switchModeDialogVisible.value = false
        await getTableData()
      } else {
        ElMessage.error(res.msg || '设置切卡模式失败')
      }
    } catch (error: any) {
      console.error('设置切卡模式失败:', error)
    } finally {
      switchModeLoading.value = false
    }
  }

  // 设备操作菜单项配置
  // 表格操作列配置
  const getActions = (row: Device) => {
    const actions: any[] = []

    // 第一个按钮：切换SIM卡
    if (hasAuth('device:switch_sim')) {
      actions.push({
        label: '切换SIM卡',
        handler: () => handleDeviceOperation('switch-card', row.virtual_no, row),
        type: 'primary'
      })
    }

    // 其他操作放到"更多"下拉菜单中
    const moreActions: any[] = []

    if (hasAuth('device:view_cards')) {
      moreActions.push({
        label: '设备绑定的卡',
        handler: () => handleDeviceOperation('view-cards', row.virtual_no, row),
        type: 'primary'
      })
    }

    if (hasAuth('device:switch_mode')) {
      moreActions.push({
        label: '设置切卡模式',
        handler: () => handleDeviceOperation('switch-mode', row.virtual_no, row),
        type: 'primary'
      })
    }

    if (hasAuth('device:reboot')) {
      moreActions.push({
        label: '重启设备',
        handler: () => handleDeviceOperation('reboot', row.virtual_no, row),
        type: 'primary'
      })
    }

    if (hasAuth('device:factory_reset')) {
      moreActions.push({
        label: '恢复出厂',
        handler: () => handleDeviceOperation('reset', row.virtual_no, row),
        type: 'primary'
      })
    }

    if (hasAuth('device:clear_series')) {
      moreActions.push({
        label: '清除关联',
        handler: () => handleDeviceOperation('clear-series', row.virtual_no, row),
        type: 'primary'
      })
    }

    if (hasAuth('device:realname_policy')) {
      moreActions.push({
        label: '实名认证策略',
        handler: () => handleDeviceOperation('realname-policy', row.virtual_no, row),
        type: 'primary'
      })
    }

    // if (hasAuth('device:manual_deactivate')) {
    //   moreActions.push({
    //     label: '手动停用',
    //     handler: () => handleDeviceOperation('manual-deactivate', row.virtual_no, row),
    //     type: 'primary'
    //   })
    // }

    if (hasAuth('device:delete')) {
      moreActions.push({
        label: '删除设备',
        handler: () => handleDeviceOperation('delete', row.virtual_no, row),
        type: 'primary'
      })
    }

    if (hasAuth('device:operation_logs')) {
      moreActions.push({
        label: '操作审计日志',
        handler: () => {
          operationLogsIdentifier.value = row.virtual_no
          operationLogsDialogVisible.value = true
        },
        type: 'primary'
      })
    }

    // 如果有更多操作，添加到 actions 中
    if (moreActions.length > 0) {
      actions.push(...moreActions)
    }

    return actions
  }
</script>

<style scoped lang="scss">
  .device-list-page {
    height: 100%;
  }

  .range-allocation-hint {
    font-size: 13px;
    line-height: 20px;
    color: var(--el-text-color-secondary);
  }

  .range-allocation-hint--device {
    margin: -6px 0 18px 120px;
  }

  :deep(.el-table__row.table-row-with-context-menu) {
    cursor: pointer;
  }

  .expiry-estimate--expiring {
    font-weight: 500;
    color: var(--el-color-danger);
  }
</style>
