<template>
  <ArtTableFullScreen>
    <div class="standalone-card-list-page" id="table-full-screen">
      <!-- 搜索栏 -->
      <ArtSearchBar
        v-model:filter="formFilters"
        :items="formItems"
        label-width="90px"
        @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="success"
              :disabled="selectedCards.length === 0"
              @click="showAllocateDialog"
              v-permission="'iot_card:batch_allocation'"
            >
              批量分配
            </ElButton>
            <ElButton
              type="warning"
              :disabled="selectedCards.length === 0"
              @click="showRecallDialog"
              v-permission="'iot_card:batch_recycle'"
            >
              批量回收
            </ElButton>
            <ElButton
              type="primary"
              :disabled="selectedCards.length === 0"
              @click="showSeriesBindingDialog"
              v-permission="'iot_card:batch_setting'"
            >
              批量设置套餐系列
            </ElButton>
            <ElButton
              type="primary"
              :disabled="selectedCards.length === 0"
              @click="showBatchRealnamePolicyDialog"
              v-permission="'iot_card:realname_policy'"
            >
              批量修改实名顺序
            </ElButton>
            <ElButton
              type="primary"
              :disabled="selectedCards.length === 0"
              @click="showEnterpriseCardAuthorizeDialog"
              v-permission="'iot_card:authorize_enterprise'"
            >
              授权卡给企业
            </ElButton>
            <ElButton
              type="warning"
              :disabled="selectedCards.length === 0"
              @click="showEnterpriseCardRecallDialog"
              v-permission="'iot_card:recall_enterprise_authorization'"
            >
              回收卡授权
            </ElButton>
            <ElButton type="primary" @click="showExportDialog" v-permission="'iot_card:export'">
              导出
            </ElButton>
          </template>
        </ArtTableHeader>

        <!-- 表格 -->
        <ArtTable
          ref="tableRef"
          row-key="id"
          :loading="loading"
          :data="cardList"
          :currentPage="pagination.page"
          :pageSize="pagination.pageSize"
          :total="pagination.total"
          :marginTop="10"
          :actions="getActions"
          :actionsWidth="160"
          @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"
          @close="handleAllocateDialogClose"
        >
          <ElForm
            ref="allocateFormRef"
            :model="allocateForm"
            :rules="allocateRules"
            label-width="120px"
          >
            <ElFormItem label="店铺" prop="to_shop_id">
              <ElCascader
                v-model="allocateForm.to_shop_id"
                :options="shopCascadeOptions"
                :props="shopCascadeProps"
                placeholder="请选择目标店铺"
                clearable
                filterable
                style="width: 100%"
              />
            </ElFormItem>
            <ElFormItem label="选卡方式" prop="selection_type">
              <ElRadioGroup v-model="allocateForm.selection_type">
                <ElRadio label="list">ICCID列表</ElRadio>
                <ElRadio label="range">号段范围</ElRadio>
                <ElRadio label="filter">筛选条件</ElRadio>
              </ElRadioGroup>
            </ElFormItem>

            <ElFormItem
              v-if="allocateForm.selection_type === CardSelectionType.LIST"
              label="ICCID列表"
            >
              <div>已选择 {{ selectedCards.length }} 张卡</div>
            </ElFormItem>

            <ElFormItem
              v-if="allocateForm.selection_type === CardSelectionType.RANGE"
              label="起始ICCID"
              prop="iccid_start"
            >
              <ElInput v-model="allocateForm.iccid_start" placeholder="请输入起始ICCID" />
            </ElFormItem>
            <ElFormItem
              v-if="allocateForm.selection_type === CardSelectionType.RANGE"
              label="结束ICCID"
              prop="iccid_end"
            >
              <ElInput v-model="allocateForm.iccid_end" placeholder="请输入结束ICCID" />
            </ElFormItem>
            <div
              v-if="
                allocateForm.selection_type === CardSelectionType.RANGE && allocateRangeCountText
              "
              class="range-allocation-hint range-allocation-hint--card-form"
            >
              共分配{{ allocateRangeCountText }}张卡
            </div>

            <ElFormItem
              v-if="allocateForm.selection_type === CardSelectionType.FILTER"
              label="运营商"
            >
              <ElSelect
                v-model="allocateForm.carrier_id"
                placeholder="请选择或搜索运营商"
                clearable
                filterable
                remote
                :remote-method="handleSearchAllocateCarrier"
                :loading="allocateCarrierLoading"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in allocateCarrierOptions"
                  :key="item.id"
                  :label="item.carrier_name"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem
              v-if="allocateForm.selection_type === CardSelectionType.FILTER"
              label="卡状态"
            >
              <ElSelect
                v-model="allocateForm.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="
                allocateForm.selection_type === CardSelectionType.FILTER && userInfo.user_type !== 3
              "
              label="批次号"
            >
              <ElSelect
                v-model="allocateForm.batch_no"
                placeholder="请选择或搜索批次号"
                clearable
                filterable
                remote
                :remote-method="handleSearchAllocateBatchNo"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in allocateBatchNoOptions"
                  :key="item.id"
                  :label="item.batch_no"
                  :value="item.batch_no"
                />
              </ElSelect>
            </ElFormItem>

            <ElFormItem label="备注">
              <ElInput
                v-model="allocateForm.remark"
                type="textarea"
                :rows="3"
                placeholder="请输入备注信息"
              />
            </ElFormItem>
          </ElForm>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="allocateDialogVisible = false">取消</ElButton>
              <ElButton type="primary" @click="handleAllocate" :loading="allocateLoading">
                确认分配
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 批量回收对话框 -->
        <ElDialog
          v-model="recallDialogVisible"
          title="批量回收"
          width="600px"
          @close="handleRecallDialogClose"
        >
          <ElForm ref="recallFormRef" :model="recallForm" :rules="recallRules" label-width="120px">
            <ElFormItem label="选卡方式" prop="selection_type">
              <ElRadioGroup v-model="recallForm.selection_type">
                <ElRadio label="list">ICCID列表</ElRadio>
                <ElRadio label="range">号段范围</ElRadio>
                <ElRadio label="filter">筛选条件</ElRadio>
              </ElRadioGroup>
            </ElFormItem>

            <ElFormItem
              v-if="recallForm.selection_type === CardSelectionType.LIST"
              label="ICCID列表"
            >
              <div>已选择 {{ selectedCards.length }} 张卡</div>
            </ElFormItem>

            <ElFormItem
              v-if="recallForm.selection_type === CardSelectionType.RANGE"
              label="起始ICCID"
              prop="iccid_start"
            >
              <ElInput v-model="recallForm.iccid_start" placeholder="请输入起始ICCID" />
            </ElFormItem>
            <ElFormItem
              v-if="recallForm.selection_type === CardSelectionType.RANGE"
              label="结束ICCID"
              prop="iccid_end"
            >
              <ElInput v-model="recallForm.iccid_end" placeholder="请输入结束ICCID" />
            </ElFormItem>
            <div
              v-if="recallForm.selection_type === CardSelectionType.RANGE && recallRangeCountText"
              class="range-allocation-hint range-allocation-hint--card-form"
            >
              共分配{{ recallRangeCountText }}张卡
            </div>

            <ElFormItem
              v-if="recallForm.selection_type === CardSelectionType.FILTER"
              label="运营商"
            >
              <ElSelect
                v-model="recallForm.carrier_id"
                placeholder="请选择或搜索运营商"
                clearable
                filterable
                remote
                :remote-method="handleSearchAllocateCarrier"
                :loading="allocateCarrierLoading"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in allocateCarrierOptions"
                  :key="item.id"
                  :label="item.carrier_name"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem
              v-if="
                recallForm.selection_type === CardSelectionType.FILTER && userInfo.user_type !== 3
              "
              label="批次号"
            >
              <ElSelect
                v-model="recallForm.batch_no"
                placeholder="请选择或搜索批次号"
                clearable
                filterable
                remote
                :remote-method="handleSearchAllocateBatchNo"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in allocateBatchNoOptions"
                  :key="item.id"
                  :label="item.batch_no"
                  :value="item.batch_no"
                />
              </ElSelect>
            </ElFormItem>

            <ElFormItem label="备注">
              <ElInput
                v-model="recallForm.remark"
                type="textarea"
                :rows="3"
                placeholder="请输入备注信息"
              />
            </ElFormItem>
          </ElForm>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="recallDialogVisible = false">取消</ElButton>
              <ElButton type="primary" @click="handleRecall" :loading="recallLoading">
                确认回收
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 分配结果对话框 -->
        <ElDialog v-model="resultDialogVisible" :title="resultTitle" width="700px">
          <ElDescriptions :column="2" border>
            <ElDescriptionsItem label="操作单号">{{
              allocationResult.allocation_no
            }}</ElDescriptionsItem>
            <ElDescriptionsItem label="待处理总数">{{
              allocationResult.total_count
            }}</ElDescriptionsItem>
            <ElDescriptionsItem label="成功数">
              <ElTag type="success">{{ allocationResult.success_count }}</ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem label="失败数">
              <ElTag type="danger">{{ allocationResult.fail_count }}</ElTag>
            </ElDescriptionsItem>
          </ElDescriptions>

          <div
            v-if="allocationResult.failed_items && allocationResult.failed_items.length > 0"
            style="margin-top: 20px"
          >
            <ElDivider content-position="left">失败项详情</ElDivider>
            <ElTable :data="allocationResult.failed_items" border max-height="300">
              <ElTableColumn prop="iccid" label="ICCID" width="200" />
              <ElTableColumn prop="reason" label="失败原因" />
            </ElTable>
          </div>

          <template #footer>
            <div class="dialog-footer">
              <ElButton type="primary" @click="resultDialogVisible = false">确定</ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 企业卡授权对话框 -->
        <ElDialog
          v-model="enterpriseCardAuthorizeDialogVisible"
          title="授权卡给企业"
          width="640px"
          @close="handleEnterpriseCardAuthorizeDialogClose"
        >
          <ElForm
            ref="enterpriseCardAuthorizeFormRef"
            :model="enterpriseCardAuthorizeForm"
            :rules="enterpriseCardAuthorizeRules"
            label-width="120px"
          >
            <ElFormItem label="授权企业" prop="enterprise_id">
              <ElSelect
                v-model="enterpriseCardAuthorizeForm.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="enterpriseCardAuthorizeForm.selection_type">
                <ElRadio label="list">ICCID列表</ElRadio>
                <ElRadio label="range">号段范围</ElRadio>
                <ElRadio label="filter">筛选条件</ElRadio>
              </ElRadioGroup>
            </ElFormItem>
            <ElFormItem
              v-if="enterpriseCardAuthorizeForm.selection_type === CardSelectionType.LIST"
              label="ICCID列表"
            >
              <div>已选择 {{ selectedCards.length }} 张卡</div>
            </ElFormItem>
            <ElFormItem
              v-if="enterpriseCardAuthorizeForm.selection_type === CardSelectionType.RANGE"
              label="起始ICCID"
              prop="iccid_start"
            >
              <ElInput
                v-model="enterpriseCardAuthorizeForm.iccid_start"
                placeholder="请输入起始ICCID"
              />
            </ElFormItem>
            <ElFormItem
              v-if="enterpriseCardAuthorizeForm.selection_type === CardSelectionType.RANGE"
              label="结束ICCID"
              prop="iccid_end"
            >
              <ElInput
                v-model="enterpriseCardAuthorizeForm.iccid_end"
                placeholder="请输入结束ICCID"
              />
            </ElFormItem>
            <div
              v-if="
                enterpriseCardAuthorizeForm.selection_type === CardSelectionType.RANGE &&
                enterpriseCardAuthorizeRangeCountText
              "
              class="range-allocation-hint range-allocation-hint--card-form"
            >
              共授权{{ enterpriseCardAuthorizeRangeCountText }}张卡
            </div>
            <template
              v-if="enterpriseCardAuthorizeForm.selection_type === CardSelectionType.FILTER"
            >
              <ElFormItem label="运营商">
                <ElSelect
                  v-model="enterpriseCardAuthorizeForm.carrier_id"
                  placeholder="请选择或搜索运营商"
                  clearable
                  filterable
                  remote
                  :remote-method="handleSearchAllocateCarrier"
                  :loading="allocateCarrierLoading"
                  style="width: 100%"
                >
                  <ElOption
                    v-for="item in allocateCarrierOptions"
                    :key="item.id"
                    :label="item.carrier_name"
                    :value="item.id"
                  />
                </ElSelect>
              </ElFormItem>
              <ElFormItem label="店铺">
                <ElCascader
                  v-model="enterpriseCardAuthorizeForm.shop_id_path"
                  :options="shopCascadeOptions"
                  :props="shopCascadeProps"
                  placeholder="请选择店铺"
                  style="width: 100%"
                  clearable
                  filterable
                />
              </ElFormItem>
              <ElFormItem label="批次号">
                <ElSelect
                  v-model="enterpriseCardAuthorizeForm.batch_no"
                  placeholder="请选择或搜索批次号"
                  clearable
                  filterable
                  remote
                  :remote-method="handleSearchAllocateBatchNo"
                  style="width: 100%"
                >
                  <ElOption
                    v-for="item in allocateBatchNoOptions"
                    :key="item.id"
                    :label="item.batch_no"
                    :value="item.batch_no"
                  />
                </ElSelect>
              </ElFormItem>
              <ElFormItem label="ICCID">
                <ElInput v-model="enterpriseCardAuthorizeForm.iccid" placeholder="请输入ICCID" />
              </ElFormItem>
            </template>
            <ElFormItem label="备注">
              <ElInput
                v-model="enterpriseCardAuthorizeForm.remark"
                type="textarea"
                :rows="3"
                placeholder="请输入备注信息"
              />
            </ElFormItem>
          </ElForm>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="enterpriseCardAuthorizeDialogVisible = false">取消</ElButton>
              <ElButton
                type="primary"
                @click="handleEnterpriseCardAuthorize"
                :loading="enterpriseCardAuthorizeLoading"
              >
                确认授权
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 企业卡授权回收对话框 -->
        <ElDialog
          v-model="enterpriseCardRecallDialogVisible"
          title="回收卡授权"
          width="640px"
          @close="handleEnterpriseCardRecallDialogClose"
        >
          <ElForm
            ref="enterpriseCardRecallFormRef"
            :model="enterpriseCardRecallForm"
            :rules="enterpriseCardRecallRules"
            label-width="120px"
          >
            <ElFormItem label="授权企业" prop="enterprise_id">
              <ElSelect
                v-model="enterpriseCardRecallForm.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="enterpriseCardRecallForm.selection_type">
                <ElRadio label="list">ICCID列表</ElRadio>
                <ElRadio label="range">号段范围</ElRadio>
                <ElRadio label="filter">筛选条件</ElRadio>
              </ElRadioGroup>
            </ElFormItem>
            <ElFormItem
              v-if="enterpriseCardRecallForm.selection_type === CardSelectionType.LIST"
              label="ICCID列表"
            >
              <div>已选择 {{ selectedCards.length }} 张卡</div>
            </ElFormItem>
            <ElFormItem
              v-if="enterpriseCardRecallForm.selection_type === CardSelectionType.RANGE"
              label="起始ICCID"
              prop="iccid_start"
            >
              <ElInput
                v-model="enterpriseCardRecallForm.iccid_start"
                placeholder="请输入起始ICCID"
              />
            </ElFormItem>
            <ElFormItem
              v-if="enterpriseCardRecallForm.selection_type === CardSelectionType.RANGE"
              label="结束ICCID"
              prop="iccid_end"
            >
              <ElInput v-model="enterpriseCardRecallForm.iccid_end" placeholder="请输入结束ICCID" />
            </ElFormItem>
            <div
              v-if="
                enterpriseCardRecallForm.selection_type === CardSelectionType.RANGE &&
                enterpriseCardRecallRangeCountText
              "
              class="range-allocation-hint range-allocation-hint--card-form"
            >
              共回收{{ enterpriseCardRecallRangeCountText }}张卡
            </div>
            <template v-if="enterpriseCardRecallForm.selection_type === CardSelectionType.FILTER">
              <ElFormItem label="运营商">
                <ElSelect
                  v-model="enterpriseCardRecallForm.carrier_id"
                  placeholder="请选择或搜索运营商"
                  clearable
                  filterable
                  remote
                  :remote-method="handleSearchAllocateCarrier"
                  :loading="allocateCarrierLoading"
                  style="width: 100%"
                >
                  <ElOption
                    v-for="item in allocateCarrierOptions"
                    :key="item.id"
                    :label="item.carrier_name"
                    :value="item.id"
                  />
                </ElSelect>
              </ElFormItem>
              <ElFormItem label="批次号">
                <ElSelect
                  v-model="enterpriseCardRecallForm.batch_no"
                  placeholder="请选择或搜索批次号"
                  clearable
                  filterable
                  remote
                  :remote-method="handleSearchAllocateBatchNo"
                  style="width: 100%"
                >
                  <ElOption
                    v-for="item in allocateBatchNoOptions"
                    :key="item.id"
                    :label="item.batch_no"
                    :value="item.batch_no"
                  />
                </ElSelect>
              </ElFormItem>
              <ElFormItem label="ICCID">
                <ElInput v-model="enterpriseCardRecallForm.iccid" placeholder="请输入ICCID" />
              </ElFormItem>
            </template>
            <ElFormItem label="备注">
              <ElInput
                v-model="enterpriseCardRecallForm.remark"
                type="textarea"
                :rows="3"
                placeholder="请输入备注信息"
              />
            </ElFormItem>
          </ElForm>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="enterpriseCardRecallDialogVisible = false">取消</ElButton>
              <ElButton
                type="primary"
                @click="handleEnterpriseCardRecall"
                :loading="enterpriseCardRecallLoading"
              >
                确认回收
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 企业卡授权操作结果 -->
        <ElDialog
          v-model="enterpriseCardResultDialogVisible"
          :title="enterpriseCardResultTitle"
          width="700px"
        >
          <ElDescriptions :column="2" border>
            <ElDescriptionsItem label="成功数">
              <ElTag type="success">{{ enterpriseCardOperationResult.success_count }}</ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem label="失败数">
              <ElTag type="danger">{{ enterpriseCardOperationResult.fail_count }}</ElTag>
            </ElDescriptionsItem>
          </ElDescriptions>
          <div
            v-if="
              enterpriseCardOperationResult.failed_items &&
              enterpriseCardOperationResult.failed_items.length > 0
            "
            style="margin-top: 20px"
          >
            <ElDivider content-position="left">失败项详情</ElDivider>
            <ElTable :data="enterpriseCardOperationResult.failed_items" border max-height="300">
              <ElTableColumn prop="iccid" label="ICCID" width="200" />
              <ElTableColumn prop="reason" label="失败原因" />
            </ElTable>
          </div>
          <div
            v-if="
              enterpriseCardOperationResult.recalled_devices &&
              enterpriseCardOperationResult.recalled_devices.length > 0
            "
            style="margin-top: 20px"
          >
            <ElDivider content-position="left">连带回收设备</ElDivider>
            <ElTable :data="enterpriseCardOperationResult.recalled_devices" border max-height="220">
              <ElTableColumn prop="virtual_no" label="设备虚拟号" width="180" />
              <ElTableColumn prop="card_count" label="关联卡数" width="100" />
              <ElTableColumn label="ICCID列表">
                <template #default="{ row }">
                  {{ row.iccids?.join(', ') || '-' }}
                </template>
              </ElTableColumn>
            </ElTable>
          </div>
          <template #footer>
            <div class="dialog-footer">
              <ElButton type="primary" @click="enterpriseCardResultDialogVisible = false"
                >确定</ElButton
              >
            </div>
          </template>
        </ElDialog>

        <!-- 批量设置套餐系列绑定对话框 -->
        <ElDialog
          v-model="seriesBindingDialogVisible"
          title="批量设置套餐系列绑定"
          width="600px"
          @close="handleSeriesBindingDialogClose"
        >
          <ElForm
            ref="seriesBindingFormRef"
            :model="seriesBindingForm"
            :rules="seriesBindingRules"
            label-width="100"
          >
            <ElFormItem label="选卡方式" prop="selection_type">
              <ElRadioGroup v-model="seriesBindingForm.selection_type">
                <ElRadio label="list">ICCID列表</ElRadio>
                <ElRadio label="range">号段范围</ElRadio>
                <ElRadio label="filter">筛选条件</ElRadio>
              </ElRadioGroup>
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === CardSelectionType.LIST"
              label="ICCID列表"
            >
              <div>已选择 {{ selectedCards.length }} 张卡</div>
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === CardSelectionType.RANGE"
              label="起始ICCID"
              prop="iccid_start"
            >
              <ElInput v-model="seriesBindingForm.iccid_start" placeholder="请输入起始ICCID" />
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === CardSelectionType.RANGE"
              label="结束ICCID"
              prop="iccid_end"
            >
              <ElInput v-model="seriesBindingForm.iccid_end" placeholder="请输入结束ICCID" />
            </ElFormItem>
            <div
              v-if="
                seriesBindingForm.selection_type === CardSelectionType.RANGE &&
                seriesBindingRangeCountText
              "
              class="range-allocation-hint range-allocation-hint--card"
            >
              共分配{{ seriesBindingRangeCountText }}张卡
            </div>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === CardSelectionType.FILTER"
              label="运营商"
            >
              <ElSelect
                v-model="seriesBindingForm.carrier_id"
                placeholder="请选择或搜索运营商"
                clearable
                filterable
                remote
                :remote-method="handleSearchAllocateCarrier"
                :loading="allocateCarrierLoading"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in allocateCarrierOptions"
                  :key="item.id"
                  :label="item.carrier_name"
                  :value="item.id"
                />
              </ElSelect>
            </ElFormItem>
            <ElFormItem
              v-if="seriesBindingForm.selection_type === CardSelectionType.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 === CardSelectionType.FILTER &&
                userInfo.user_type !== 3
              "
              label="批次号"
            >
              <ElSelect
                v-model="seriesBindingForm.batch_no"
                placeholder="请选择或搜索批次号"
                clearable
                filterable
                remote
                :remote-method="handleSearchAllocateBatchNo"
                style="width: 100%"
              >
                <ElOption
                  v-for="item in allocateBatchNoOptions"
                  :key="item.id"
                  :label="item.batch_no"
                  :value="item.batch_no"
                />
              </ElSelect>
            </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>
          <template #footer>
            <div class="dialog-footer">
              <ElButton @click="seriesBindingDialogVisible = false">取消</ElButton>
              <ElButton type="primary" @click="handleSeriesBinding" :loading="seriesBindingLoading">
                确认设置
              </ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 套餐系列绑定结果对话框 -->
        <ElDialog
          v-model="seriesBindingResultDialogVisible"
          title="设置结果"
          width="700px"
          @close="handleSeriesBindingResultDialogClose"
        >
          <ElDescriptions :column="2" border>
            <ElDescriptionsItem label="成功数">
              <ElTag type="success">{{ seriesBindingResult.success_count }}</ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem label="失败数">
              <ElTag type="danger">{{ seriesBindingResult.fail_count }}</ElTag>
            </ElDescriptionsItem>
          </ElDescriptions>

          <div
            v-if="seriesBindingResult.failed_items && seriesBindingResult.failed_items.length > 0"
            style="margin-top: 20px"
          >
            <ElDivider content-position="left">失败项详情</ElDivider>
            <ElTable :data="seriesBindingResult.failed_items" border max-height="300">
              <ElTableColumn prop="iccid" label="ICCID" width="200" />
              <ElTableColumn prop="reason" label="失败原因" />
            </ElTable>
          </div>

          <template #footer>
            <div class="dialog-footer">
              <ElButton type="primary" @click="seriesBindingResultDialogVisible = false"
                >确定</ElButton
              >
            </div>
          </template>
        </ElDialog>

        <!-- 卡详情对话框 -->
        <ElDialog v-model="cardDetailDialogVisible" title="卡片详情" width="900px">
          <div v-if="cardDetailLoading" style="padding: 40px; text-align: center">
            <ElIcon class="is-loading" :size="40">
              <Loading />
            </ElIcon>
            <div style="margin-top: 16px">加载中...</div>
          </div>

          <ElDescriptions v-else-if="currentCardDetail" :column="3" border>
            <ElDescriptionsItem label="卡ID">{{ currentCardDetail.id }}</ElDescriptionsItem>
            <ElDescriptionsItem label="ICCID" :span="2">{{
              currentCardDetail.iccid
            }}</ElDescriptionsItem>

            <ElDescriptionsItem label="MSISDN">{{
              currentCardDetail.msisdn || '--'
            }}</ElDescriptionsItem>
            <ElDescriptionsItem label="运营商">{{
              currentCardDetail.carrier_name || '--'
            }}</ElDescriptionsItem>
            <ElDescriptionsItem label="运营商类型">{{
              getCarrierTypeText(currentCardDetail.carrier_type)
            }}</ElDescriptionsItem>

            <ElDescriptionsItem label="卡业务类型">{{
              getCardCategoryText(currentCardDetail.card_category)
            }}</ElDescriptionsItem>
            <ElDescriptionsItem label="状态">
              <ElTag :type="getCardDetailStatusTagType(currentCardDetail.status)">
                {{ getCardDetailStatusText(currentCardDetail.status) }}
              </ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem label="套餐系列">{{
              currentCardDetail.series_name || '--'
            }}</ElDescriptionsItem>
            <ElDescriptionsItem label="激活状态">
              <ElTag :type="currentCardDetail.activation_status === 1 ? 'success' : 'info'">
                {{ currentCardDetail.activation_status === 1 ? '已激活' : '未激活' }}
              </ElTag>
            </ElDescriptionsItem>

            <ElDescriptionsItem label="实名状态">
              <ElTag :type="currentCardDetail.real_name_status === 1 ? 'success' : 'warning'">
                {{ currentCardDetail.real_name_status === 1 ? '已实名' : '未实名' }}
              </ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem label="网络状态">
              <ElTag :type="currentCardDetail.network_status === 1 ? 'success' : 'danger'">
                {{ currentCardDetail.network_status === 1 ? '正常' : '停机' }}
              </ElTag>
            </ElDescriptionsItem>
            <ElDescriptionsItem label="累计流量使用"
              >{{ currentCardDetail.data_usage_mb }} MB</ElDescriptionsItem
            >
            <ElDescriptionsItem label="创建时间">{{
              formatDateTime(currentCardDetail.created_at)
            }}</ElDescriptionsItem>

            <ElDescriptionsItem label="更新时间" :span="2">{{
              formatDateTime(currentCardDetail.updated_at)
            }}</ElDescriptionsItem>
          </ElDescriptions>

          <ElEmpty v-else description="未找到卡片信息" />

          <template #footer>
            <div class="dialog-footer">
              <ElButton type="primary" @click="cardDetailDialogVisible = false">关闭</ElButton>
            </div>
          </template>
        </ElDialog>

        <!-- 实名认证策略对话框 -->
        <RealnamePolicyDialog
          v-model="realnamePolicyDialogVisible"
          :asset-identifier="currentRealnamePolicyIccid"
          :current-policy="currentRealnamePolicy"
          @confirm="handleConfirmRealnamePolicy"
        />
        <BatchRealnamePolicyDialog
          v-model="batchRealnamePolicyDialogVisible"
          :selected-count="selectedCards.length"
          asset-unit="张卡"
          :loading="batchRealnamePolicyLoading"
          :error-message="batchRealnamePolicyError"
          @confirm="handleConfirmBatchRealnamePolicy"
        />

        <!-- 更新实名状态对话框 -->
        <UpdateRealnameStatusDialog
          v-model="updateRealnameStatusDialogVisible"
          :asset-identifier="currentUpdateRealnameStatusIccid"
          :current-realname-status="currentUpdateRealnameStatus"
          @success="handleUpdateRealnameStatusSuccess"
        />

        <!-- 操作审计日志弹窗 -->
        <OperationLogsDialog
          v-model="operationLogsDialogVisible"
          :identifier="operationLogsIdentifier"
          download-permission="iot_card:download_log_file"
        />

        <ExportTaskCreateDialog
          v-model="exportDialogVisible"
          scene="iot_card"
          :query="exportQuery"
          confirm-permission="iot_card:export"
          title="导出IOT卡"
        />
      </ElCard>
    </div>
  </ArtTableFullScreen>
</template>

<script setup lang="ts">
  import { computed, h } from 'vue'
  import { useRouter } from 'vue-router'
  import { RoutesAlias } from '@/router/routesAlias'
  import {
    CardService,
    ShopService,
    PackageSeriesService,
    AssetService,
    CarrierService,
    EnterpriseService
  } from '@/api/modules'
  import { ElMessage, ElTag, ElIcon, ElMessageBox } from 'element-plus'
  import { Loading } from '@element-plus/icons-vue'
  import RealnamePolicyDialog from '@/components/device/RealnamePolicyDialog.vue'
  import BatchRealnamePolicyDialog from '@/components/business/BatchRealnamePolicyDialog.vue'
  import UpdateRealnameStatusDialog from '@/components/business/UpdateRealnameStatusDialog.vue'
  import ExportTaskCreateDialog from '@/components/business/ExportTaskCreateDialog.vue'
  import type { FormInstance, FormRules } from 'element-plus'
  import type { SearchFormItem } from '@/types'
  import { useCheckedColumns } from '@/composables/useCheckedColumns'
  import { useAuth } from '@/composables/useAuth'
  import { useUserStore } from '@/store/modules/user'
  import { storeToRefs } from 'pinia'
  import { formatDateTime } from '@/utils/business/format'
  import { getExpiryEstimateText, getExpiryEstimateTooltip } from '@/utils/business/expiryEstimate'
  import { formatRemainingTime, FrontendRateLimitError } from '@/utils/business/apiRateLimit'
  import type {
    StandaloneIotCard,
    StandaloneCardStatus,
    AllocateStandaloneCardsRequest,
    RecallStandaloneCardsRequest,
    AllocateStandaloneCardsResponse,
    BatchSetCardSeriesBindingRequest,
    BatchSetCardSeriesBindingResponse
  } from '@/types/api/card'
  import { CardSelectionType } from '@/types/api/card'
  import type { AssetRealnamePolicy, PackageSeriesResponse } from '@/types/api'
  import type { EnterpriseItem } from '@/types/api/enterprise'
  import type { AllocateCardsResponse, RecallCardsResponse } from '@/types/api/enterpriseCard'
  import OperationLogsDialog from '@/components/business/OperationLogsDialog.vue'

  defineOptions({ name: 'StandaloneCardList' })

  const { hasAuth } = useAuth()
  const userStore = useUserStore()
  const { info: userInfo } = storeToRefs(userStore)
  const router = useRouter()

  const loading = ref(false)
  const allocateDialogVisible = ref(false)
  const allocateLoading = ref(false)
  const recallDialogVisible = ref(false)
  const recallLoading = ref(false)
  const resultDialogVisible = ref(false)
  const resultTitle = ref('')
  const tableRef = ref()
  const allocateFormRef = ref<FormInstance>()
  const recallFormRef = ref<FormInstance>()
  const selectedCards = ref<StandaloneIotCard[]>([])
  const batchRealnamePolicyDialogVisible = ref(false)
  const batchRealnamePolicyLoading = ref(false)
  const batchRealnamePolicyError = ref('')
  const allocationResult = ref<AllocateStandaloneCardsResponse>({
    allocation_no: '',
    total_count: 0,
    success_count: 0,
    fail_count: 0,
    failed_items: null
  })
  const enterpriseCardAuthorizeDialogVisible = ref(false)
  const enterpriseCardRecallDialogVisible = ref(false)
  const enterpriseCardResultDialogVisible = ref(false)
  const enterpriseCardAuthorizeLoading = ref(false)
  const enterpriseCardRecallLoading = ref(false)
  const enterpriseCardResultTitle = ref('')
  const enterpriseCardAuthorizeFormRef = ref<FormInstance>()
  const enterpriseCardRecallFormRef = ref<FormInstance>()
  const enterpriseOptions = ref<EnterpriseItem[]>([])
  const enterpriseLoading = ref(false)
  const enterpriseCardOperationResult = ref<
    Partial<AllocateCardsResponse & RecallCardsResponse> & {
      success_count: number
      fail_count: number
    }
  >({
    success_count: 0,
    fail_count: 0,
    failed_items: null,
    recalled_devices: null
  })

  // 操作审计日志弹窗
  const operationLogsDialogVisible = ref(false)
  const operationLogsIdentifier = ref('')
  const exportDialogVisible = ref(false)

  // 套餐系列绑定相关
  const seriesBindingDialogVisible = ref(false)
  const seriesBindingLoading = ref(false)
  const seriesBindingResultDialogVisible = ref(false)
  const seriesBindingFormRef = ref<FormInstance>()
  const seriesLoading = ref(false)
  const packageSeriesList = ref<PackageSeriesResponse[]>([])
  const createInitialSeriesBindingState = () => ({
    selection_type: CardSelectionType.LIST,
    series_id: undefined as number | undefined,
    iccid_start: '',
    iccid_end: '',
    carrier_id: undefined as number | undefined,
    status: undefined as StandaloneCardStatus | undefined,
    batch_no: ''
  })
  const seriesBindingForm = reactive(createInitialSeriesBindingState())
  const createInitialEnterpriseCardAuthorizeState = () => ({
    enterprise_id: undefined as number | undefined,
    selection_type: CardSelectionType.LIST,
    iccid_start: '',
    iccid_end: '',
    carrier_id: undefined as number | undefined,
    shop_id_path: undefined as number[] | undefined,
    batch_no: '',
    iccid: '',
    remark: ''
  })
  const createInitialEnterpriseCardRecallState = () => ({
    enterprise_id: undefined as number | undefined,
    selection_type: CardSelectionType.LIST,
    iccid_start: '',
    iccid_end: '',
    carrier_id: undefined as number | undefined,
    batch_no: '',
    iccid: '',
    remark: ''
  })
  const enterpriseCardAuthorizeForm = reactive(createInitialEnterpriseCardAuthorizeState())
  const enterpriseCardRecallForm = reactive(createInitialEnterpriseCardRecallState())
  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 getFormattedRangeCountText = (startValue?: string, endValue?: string): string => {
    const countText = getPositiveRangeCountText(
      parseNumericStringToBigInt(startValue ?? ''),
      parseNumericStringToBigInt(endValue ?? '')
    )

    return countText ? formatDigitGrouping(countText) : ''
  }
  const allocateRangeCountText = computed(() =>
    getFormattedRangeCountText(allocateForm.iccid_start, allocateForm.iccid_end)
  )
  const recallRangeCountText = computed(() =>
    getFormattedRangeCountText(recallForm.iccid_start, recallForm.iccid_end)
  )
  const enterpriseCardAuthorizeRangeCountText = computed(() =>
    getFormattedRangeCountText(
      enterpriseCardAuthorizeForm.iccid_start,
      enterpriseCardAuthorizeForm.iccid_end
    )
  )
  const enterpriseCardRecallRangeCountText = computed(() =>
    getFormattedRangeCountText(
      enterpriseCardRecallForm.iccid_start,
      enterpriseCardRecallForm.iccid_end
    )
  )
  const seriesBindingRangeCountText = computed(() =>
    getFormattedRangeCountText(seriesBindingForm.iccid_start, seriesBindingForm.iccid_end)
  )
  const createEnterpriseCardRules = (form: { selection_type: CardSelectionType }) =>
    reactive<FormRules>({
      enterprise_id: [{ required: true, message: '请选择企业', trigger: 'change' }],
      selection_type: [{ required: true, message: '请选择选卡方式', trigger: 'change' }],
      iccid_start: [
        {
          required: true,
          validator: (_rule, value, callback) => {
            if (form.selection_type === CardSelectionType.RANGE && !value) {
              callback(new Error('请输入起始ICCID'))
            } else {
              callback()
            }
          },
          trigger: 'blur'
        }
      ],
      iccid_end: [
        {
          required: true,
          validator: (_rule, value, callback) => {
            if (form.selection_type === CardSelectionType.RANGE && !value) {
              callback(new Error('请输入结束ICCID'))
            } else {
              callback()
            }
          },
          trigger: 'blur'
        }
      ]
    })
  const enterpriseCardAuthorizeRules = createEnterpriseCardRules(enterpriseCardAuthorizeForm)
  const enterpriseCardRecallRules = createEnterpriseCardRules(enterpriseCardRecallForm)
  const seriesBindingRules = reactive<FormRules>({
    selection_type: [{ required: true, message: '请选择选卡方式', trigger: 'change' }],
    series_id: [{ required: true, message: '请选择套餐系列', trigger: 'change' }],
    iccid_start: [
      {
        required: true,
        validator: (_rule, value, callback) => {
          if (seriesBindingForm.selection_type === CardSelectionType.RANGE && !value) {
            callback(new Error('请输入起始ICCID'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ],
    iccid_end: [
      {
        required: true,
        validator: (_rule, value, callback) => {
          if (seriesBindingForm.selection_type === CardSelectionType.RANGE && !value) {
            callback(new Error('请输入结束ICCID'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ]
  })
  const seriesBindingResult = ref<BatchSetCardSeriesBindingResponse>({
    success_count: 0,
    fail_count: 0,
    failed_items: null
  })

  // 运营商搜索相关
  const carrierLoading = ref(false)
  const searchCarrierOptions = ref<any[]>([])

  // 批量分配对话框运营商选项
  const allocateCarrierOptions = ref<any[]>([])
  const allocateCarrierLoading = ref(false)

  // 加载搜索栏运营商选项（默认加载10条）
  const loadSearchCarrierOptions = async (carrierName?: string) => {
    try {
      const params: any = {
        page: 1,
        page_size: 10
      }
      if (carrierName) {
        params.carrier_name = carrierName
      }
      const res = await CarrierService.getCarriers(params)
      if (res.code === 0) {
        searchCarrierOptions.value = res.data.items
      }
    } catch (error) {
      console.error('加载运营商选项失败:', error)
    }
  }

  // 加载批量分配对话框运营商选项
  const loadAllocateCarrierOptions = async (carrierName?: string) => {
    try {
      allocateCarrierLoading.value = true
      const params: any = {
        page: 1,
        page_size: 20
      }
      if (carrierName) {
        params.carrier_name = carrierName
      }
      const res = await CarrierService.getCarriers(params)
      if (res.code === 0) {
        allocateCarrierOptions.value = res.data.items || []
      }
    } catch (error) {
      console.error('加载运营商选项失败:', error)
    } finally {
      allocateCarrierLoading.value = false
    }
  }

  // 搜索批量分配对话框运营商
  const handleSearchAllocateCarrier = (query: string) => {
    if (query) {
      loadAllocateCarrierOptions(query)
    } else {
      loadAllocateCarrierOptions()
    }
  }

  // 搜索运营商（用于搜索栏）
  const handleSearchCarrier = (query: string) => {
    if (query) {
      loadSearchCarrierOptions(query)
    } else {
      loadSearchCarrierOptions()
    }
  }

  // 批量分配对话框批次号选项
  const allocateBatchNoOptions = ref<any[]>([])

  // 加载批量分配对话框批次号选项
  const loadAllocateBatchNoOptions = 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) {
        allocateBatchNoOptions.value = res.data.items || []
      }
    } catch (error) {
      console.error('加载批次号选项失败:', error)
    }
  }

  // 搜索批量分配对话框批次号
  const handleSearchAllocateBatchNo = (query: string) => {
    if (query) {
      loadAllocateBatchNoOptions(query)
    } else {
      loadAllocateBatchNoOptions()
    }
  }

  // 搜索栏远程选项
  const shopOptions = ref<any[]>([])
  const searchSeriesOptions = ref<any[]>([])

  // 搜索店铺（用于搜索栏）
  const handleSearchShops = 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 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
    }
  }

  // 搜索套餐系列（用于搜索栏）
  const handleSearchSeries = 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 cardDetailDialogVisible = ref(false)
  const cardDetailLoading = ref(false)
  const currentCardDetail = ref<any>(null)

  // IoT卡操作相关对话框

  // 实名认证策略对话框
  const realnamePolicyDialogVisible = ref(false)
  const currentRealnamePolicyIccid = ref('')
  const currentRealnamePolicy = ref('none')

  // 更新实名状态对话框
  const updateRealnameStatusDialogVisible = ref(false)
  const currentUpdateRealnameStatusIccid = ref('')
  const currentUpdateRealnameStatus = ref<number>(0)

  // 显示实名认证策略对话框
  const handleShowRealnamePolicy = async (iccid: string, currentPolicy?: string) => {
    currentRealnamePolicyIccid.value = iccid
    if (currentPolicy !== undefined && currentPolicy !== null) {
      currentRealnamePolicy.value = String(currentPolicy)
    } else {
      try {
        const res = await AssetService.resolveAsset(iccid)
        if (res.code === 0 && res.data) {
          currentRealnamePolicy.value = res.data.realname_policy ?? 'none'
        } else {
          currentRealnamePolicy.value = 'none'
        }
      } catch {
        currentRealnamePolicy.value = 'none'
      }
    }
    realnamePolicyDialogVisible.value = true
  }

  // 确认设置实名认证策略
  const handleConfirmRealnamePolicy = async (data: { realname_policy: string }) => {
    if (!currentRealnamePolicyIccid.value) {
      ElMessage.warning('未指定卡片')
      return
    }
    try {
      const res = await AssetService.updateRealnamePolicy(
        currentRealnamePolicyIccid.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 handleShowUpdateRealnameStatus = (iccid: string, realnameStatus: number) => {
    currentUpdateRealnameStatusIccid.value = iccid
    currentUpdateRealnameStatus.value = realnameStatus
    updateRealnameStatusDialogVisible.value = true
  }

  // 更新实名状态成功
  const handleUpdateRealnameStatusSuccess = async () => {
    await getTableData()
  }

  // 店铺相关
  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 initialSearchState: {
    status: undefined | number
    network_status: undefined | number
    real_name_status: undefined | 0 | 1
    iccid: string
    carrier_name: string
    msisdn: string
    virtual_no: string
    device_virtual_no: string
    shop_id: undefined | number
    series_id: undefined | number
    has_active_package: undefined | boolean
    is_distributed: undefined | number
    is_standalone: undefined | boolean
    authorized_enterprise_id: undefined | number
    is_authorized_to_enterprise: undefined | boolean
    [key: string]: any
  } = {
    status: undefined,
    network_status: undefined,
    real_name_status: undefined,
    iccid: '',
    carrier_name: '',
    msisdn: '',
    virtual_no: '',
    device_virtual_no: '',
    shop_id: undefined,
    series_id: undefined,
    has_active_package: undefined,
    is_distributed: undefined,
    is_standalone: undefined,
    authorized_enterprise_id: undefined,
    is_authorized_to_enterprise: undefined,
    is_replaced: undefined,
    iccid_start: '',
    iccid_end: ''
  }

  // 搜索表单
  const formFilters = reactive({ ...initialSearchState })

  // 批量分配表单
  const allocateForm = reactive<Partial<AllocateStandaloneCardsRequest>>({
    selection_type: CardSelectionType.LIST,
    to_shop_id: undefined,
    iccids: [],
    iccid_start: '',
    iccid_end: '',
    carrier_id: undefined,
    status: undefined,
    batch_no: '',
    remark: ''
  })

  // 批量分配表单验证规则
  const allocateRules = reactive<FormRules>({
    to_shop_id: [{ required: true, message: '请选择目标店铺', trigger: 'change' }],
    selection_type: [{ required: true, message: '请选择选卡方式', trigger: 'change' }],
    iccid_start: [
      {
        required: true,
        validator: (_rule, value, callback) => {
          if (allocateForm.selection_type === CardSelectionType.RANGE && !value) {
            callback(new Error('请输入起始ICCID'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ],
    iccid_end: [
      {
        required: true,
        validator: (_rule, value, callback) => {
          if (allocateForm.selection_type === CardSelectionType.RANGE && !value) {
            callback(new Error('请输入结束ICCID'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ]
  })

  // 批量回收表单
  const recallForm = reactive<Partial<RecallStandaloneCardsRequest>>({
    selection_type: CardSelectionType.LIST,
    iccids: [],
    iccid_start: '',
    iccid_end: '',
    carrier_id: undefined,
    batch_no: '',
    remark: ''
  })

  // 批量回收表单验证规则
  const recallRules = reactive<FormRules>({
    selection_type: [{ required: true, message: '请选择选卡方式', trigger: 'change' }],
    iccid_start: [
      {
        required: true,
        validator: (_rule, value, callback) => {
          if (recallForm.selection_type === CardSelectionType.RANGE && !value) {
            callback(new Error('请输入起始ICCID'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ],
    iccid_end: [
      {
        required: true,
        validator: (_rule, value, callback) => {
          if (recallForm.selection_type === CardSelectionType.RANGE && !value) {
            callback(new Error('请输入结束ICCID'))
          } else {
            callback()
          }
        },
        trigger: 'blur'
      }
    ]
  })

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

  // 搜索表单配置
  const baseFormItems: SearchFormItem[] = [
    {
      label: 'ICCID',
      prop: 'iccid',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入ICCID'
      }
    },
    {
      label: '运营商',
      prop: 'carrier_name',
      type: 'select',
      config: {
        clearable: true,
        filterable: true,
        remote: true,
        remoteMethod: handleSearchCarrier,
        loading: carrierLoading.value,
        placeholder: '请选择或搜索运营商名称'
      },
      options: () =>
        searchCarrierOptions.value.map((c) => ({
          label: c.carrier_name,
          value: c.carrier_name
        }))
    },
    {
      label: '状态',
      prop: 'status',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '全部'
      },
      options: () => [
        { label: '在库', value: 1 },
        { label: '已分销', value: 2 },
        { label: '已激活', value: 3 },
        { label: '已停用', value: 4 }
      ]
    },
    {
      label: '网络状态',
      prop: 'network_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: 'virtual_no',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入卡虚拟号'
      }
    },
    {
      label: 'MSISDN',
      prop: 'msisdn',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入MSISDN'
      }
    },
    {
      label: '设备虚拟号',
      prop: 'device_virtual_no',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入绑定设备虚拟号'
      }
    },
    {
      label: '店铺名称',
      prop: 'shop_id',
      type: 'select',
      config: {
        clearable: true,
        filterable: true,
        remote: true,
        remoteMethod: handleSearchShops,
        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: handleSearchSeries,
        placeholder: '请选择或搜索套餐系列'
      },
      options: () =>
        searchSeriesOptions.value.map((s) => ({
          label: s.series_name,
          value: s.id
        }))
    },
    {
      label: '分销状态',
      prop: 'is_distributed',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '全部'
      },
      options: () => [
        { label: '是', value: true },
        { label: '否', value: false }
      ]
    },
    {
      label: '有无换卡',
      prop: 'is_replaced',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '全部'
      },
      options: () => [
        { label: '有换卡记录', value: true },
        { label: '无换卡记录', value: false }
      ]
    },
    {
      label: '起始号',
      prop: 'iccid_start',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入ICCID起始号'
      }
    },
    {
      label: '结束号',
      prop: 'iccid_end',
      type: 'input',
      config: {
        clearable: true,
        placeholder: '请输入ICCID结束号'
      }
    },
    {
      label: '是否绑设备',
      prop: 'is_standalone',
      type: 'select',
      config: {
        clearable: true,
        placeholder: '全部'
      },
      options: () => [
        { label: '未绑定设备', value: true },
        { label: '已绑定设备', value: false }
      ]
    }
  ]

  // 搜索表单配置
  baseFormItems.splice(8, 0, {
    label: '有效套餐',
    prop: 'has_active_package',
    type: 'select',
    config: {
      clearable: true,
      placeholder: '全部'
    },
    options: () => [
      { label: '是', value: true },
      { label: '否', value: false }
    ]
  })
  baseFormItems.splice(9, 0, {
    label: '授权企业',
    prop: 'authorized_enterprise_id',
    type: 'select',
    config: {
      clearable: true,
      filterable: true,
      remote: true,
      remoteMethod: handleSearchEnterprise,
      loading: enterpriseLoading.value,
      placeholder: '请选择或搜索企业'
    },
    options: () =>
      enterpriseOptions.value.map((enterprise) => ({
        label: enterprise.enterprise_name,
        value: enterprise.id
      }))
  })
  baseFormItems.splice(10, 0, {
    label: '授权状态',
    prop: 'is_authorized_to_enterprise',
    type: 'select',
    config: {
      clearable: true,
      placeholder: '全部'
    },
    options: () => [
      { label: '已授权', value: true },
      { label: '未授权', value: false }
    ]
  })

  const formItems: SearchFormItem[] = baseFormItems

  // 列配置
  const columnOptions = [
    { label: 'ICCID', prop: 'iccid' },
    { label: 'IMEI', prop: 'gateway_card_imei' },
    { label: 'MSISDN', prop: 'msisdn' },
    { label: '卡虚拟号', prop: 'virtual_no' },
    { label: '运营商', prop: 'carrier_name' },
    { label: '卡业务类型', prop: 'card_category' },
    { label: '状态', prop: 'status' },
    { label: '资产世代', prop: 'generation' },
    { label: '业务状态', prop: 'asset_status' },
    { label: '激活状态', prop: 'activation_status' },
    { label: '激活时间', prop: 'activated_at' },
    { label: '网络状态', prop: 'network_status' },
    { label: '实名状态', prop: 'real_name_status' },
    { label: '实名认证策略', prop: 'realname_policy' },
    { label: '绑定设备虚拟号', prop: 'device_virtual_no' },
    { label: '店铺名称', prop: 'shop_name' },
    { label: '套餐系列', prop: 'series_name' },
    { label: '预计套餐到期时间', prop: 'estimated_final_expires_at' },
    { label: '自然月累计流量(MB)', prop: 'current_month_usage_mb' },
    { label: '本月开始日期', prop: 'current_month_start_date' },
    { label: '上月流量总量(MB)', prop: 'last_month_total_mb' },
    { label: '累计流量(MB)', prop: 'data_usage_mb' },
    { label: '最后流量检查时间', prop: 'last_data_check_at' },
    { label: '最后实名检查时间', prop: 'last_real_name_check_at' },
    { label: '启用轮询', prop: 'enable_polling' },
    { label: '批次号', prop: 'batch_no' },
    { label: '创建时间', prop: 'created_at' },
    { label: '更新时间', prop: 'updated_at' }
  ]

  const cardList = ref<StandaloneIotCard[]>([])

  // 获取状态标签类型
  const getStatusType = (status: StandaloneCardStatus) => {
    switch (status) {
      case 1:
        return 'info'
      case 2:
        return 'warning'
      case 3:
        return 'success'
      case 4:
        return 'danger'
      default:
        return 'info'
    }
  }

  // 获取状态文本
  const getStatusText = (status: StandaloneCardStatus) => {
    switch (status) {
      case 1:
        return '在库'
      case 2:
        return '已分销'
      case 3:
        return '已激活'
      case 4:
        return '已停用'
      default:
        return '未知'
    }
  }

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

  // 卡详情辅助函数
  const getCarrierTypeText = (type: string) => {
    const typeMap: Record<string, string> = {
      CMCC: '中国移动',
      CUCC: '中国联通',
      CTCC: '中国电信',
      CBN: '中国广电'
    }
    return typeMap[type] || type
  }

  const getCardCategoryText = (category: string) => {
    const categoryMap: Record<string, string> = {
      normal: '普通卡',
      industry: '行业卡'
    }
    return categoryMap[category] || category
  }

  const getCardDetailStatusText = (status: number) => {
    const statusMap: Record<number, string> = {
      1: '在库',
      2: '已分销',
      3: '已激活',
      4: '已停用'
    }
    return statusMap[status] || '未知'
  }

  const getCardDetailStatusTagType = (status: number) => {
    const typeMap: Record<number, any> = {
      1: 'info',
      2: 'warning',
      3: 'success',
      4: 'danger'
    }
    return typeMap[status] || 'info'
  }

  // 动态列配置
  const { columnChecks, columns } = useCheckedColumns(() => [
    {
      prop: 'iccid',
      label: 'ICCID',
      minWidth: 200,
      formatter: (row: StandaloneIotCard) => {
        return h(
          'span',
          {
            style: 'color: var(--el-color-primary); cursor: pointer; text-decoration: underline;',
            onClick: (e: MouseEvent) => {
              e.stopPropagation()
              goToCardDetail(row.iccid)
            }
          },
          row.iccid
        )
      }
    },
    {
      prop: 'gateway_card_imei',
      label: 'IMEI',
      width: 180,
      showOverflowTooltip: true,
      formatter: (row: StandaloneIotCard) => row.gateway_card_imei || '-'
    },
    {
      prop: 'msisdn',
      label: 'MSISDN',
      width: 160
    },
    {
      prop: 'virtual_no',
      label: '卡虚拟号',
      width: 180,
      showOverflowTooltip: true,
      formatter: (row: StandaloneIotCard) => row.virtual_no || '-'
    },
    {
      prop: 'device_virtual_no',
      label: '绑定设备虚拟号',
      width: 180,
      showOverflowTooltip: true,
      formatter: (row: StandaloneIotCard) => row.device_virtual_no || '-'
    },
    {
      prop: 'card_category',
      label: '卡业务类型',
      width: 100,
      formatter: (row: StandaloneIotCard) => getCardCategoryText(row.card_category)
    },
    {
      prop: 'carrier_name',
      label: '运营商',
      width: 150,
      showOverflowTooltip: true
    },
    {
      prop: 'shop_name',
      label: '店铺名称',
      minWidth: 150,
      showOverflowTooltip: true,
      formatter: (row: StandaloneIotCard) => row.shop_name || '-'
    },
    {
      prop: 'series_name',
      label: '套餐系列',
      width: 180,
      showOverflowTooltip: true,
      formatter: (row: StandaloneIotCard) => row.series_name || '-'
    },
    {
      prop: 'estimated_final_expires_at',
      label: '预计套餐到期时间',
      width: 180,
      formatter: (row: StandaloneIotCard) =>
        h(
          'span',
          {
            class: { 'expiry-estimate--expiring': row.is_expiring },
            title: getExpiryEstimateTooltip(row)
          },
          getExpiryEstimateText(row)
        )
    },
    {
      prop: 'status',
      label: '状态',
      width: 100,
      formatter: (row: StandaloneIotCard) => {
        return h(ElTag, { type: getStatusType(row.status) }, () => getStatusText(row.status))
      }
    },
    {
      prop: 'generation',
      label: '资产世代',
      width: 100,
      formatter: (row: StandaloneIotCard) => row.generation ?? '-'
    },
    {
      prop: 'asset_status',
      label: '业务状态',
      width: 100,
      formatter: (row: StandaloneIotCard) => {
        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',
      label: '激活状态',
      width: 100,
      formatter: (row: StandaloneIotCard) => {
        const type = row.activation_status === 1 ? 'success' : 'info'
        const text = row.activation_status === 1 ? '已激活' : '未激活'
        return h(ElTag, { type }, () => text)
      }
    },
    {
      prop: 'network_status',
      label: '网络状态',
      width: 100,
      formatter: (row: StandaloneIotCard) => {
        const type = row.network_status === 1 ? 'success' : 'danger'
        const text = row.network_status === 1 ? '正常' : '停机'
        return h(ElTag, { type }, () => text)
      }
    },
    {
      prop: 'real_name_status',
      label: '实名状态',
      width: 100,
      formatter: (row: StandaloneIotCard) => row.real_name_status_name || '-'
    },
    {
      prop: 'realname_policy',
      label: '实名认证策略',
      width: 150,
      formatter: (row: StandaloneIotCard) => {
        const policy = row.realname_policy || ''
        const policyMap: Record<string, string> = {
          none: '无需实名',
          before_order: '先实名后充值/购买',
          after_order: '先充值/购买后实名'
        }
        const text = policyMap[policy] || (policy ? policy : '未知')
        return text
      }
    },
    {
      prop: 'activated_at',
      label: '激活时间',
      width: 180,
      formatter: (row: StandaloneIotCard) =>
        row.activated_at ? formatDateTime(row.activated_at) : '-'
    },
    {
      prop: 'current_month_usage_mb',
      label: '自然月累计流量(MB)',
      width: 180,
      formatter: (row: StandaloneIotCard) => row.current_month_usage_mb?.toLocaleString() || '0'
    },
    {
      prop: 'current_month_start_date',
      label: '本月开始日期',
      width: 200,
      formatter: (row: StandaloneIotCard) =>
        row.current_month_start_date ? formatDateTime(row.current_month_start_date) : '-'
    },
    {
      prop: 'last_month_total_mb',
      label: '上月流量总量(MB)',
      width: 150,
      formatter: (row: StandaloneIotCard) => row.last_month_total_mb?.toLocaleString() || '0'
    },
    {
      prop: 'data_usage_mb',
      label: '累计流量(MB)',
      width: 120,
      formatter: (row: StandaloneIotCard) => row.data_usage_mb?.toLocaleString() || '0'
    },
    {
      prop: 'last_data_check_at',
      label: '最后流量检查时间',
      width: 180,
      formatter: (row: StandaloneIotCard) =>
        row.last_data_check_at ? formatDateTime(row.last_data_check_at) : '-'
    },
    {
      prop: 'last_real_name_check_at',
      label: '最后实名检查时间',
      width: 180,
      formatter: (row: StandaloneIotCard) =>
        row.last_real_name_check_at ? formatDateTime(row.last_real_name_check_at) : '-'
    },
    {
      prop: 'enable_polling',
      label: '启用轮询',
      width: 100,
      formatter: (row: StandaloneIotCard) => (row.enable_polling ? '是' : '否')
    },
    {
      prop: 'batch_no',
      label: '批次号',
      width: 200,
      showOverflowTooltip: true
    },
    {
      prop: 'created_at',
      label: '创建时间',
      width: 180,
      formatter: (row: StandaloneIotCard) => formatDateTime(row.created_at)
    }
  ])

  // 操作列配置
  const getActions = (row: StandaloneIotCard) => {
    const actions: any[] = []

    if (row.network_status === 1) {
      if (hasAuth('iot_card:stop_card')) {
        actions.push({
          label: '停用此卡',
          handler: () => handleCardOperation('stop-card', row.iccid),
          type: 'primary'
        })
      }
    } else {
      if (hasAuth('iot_card:start_card')) {
        actions.push({
          label: '启用此卡',
          handler: () => handleCardOperation('start-card', row.iccid),
          type: 'primary'
        })
      }
    }

    if (hasAuth('iot_card:realname_policy')) {
      actions.push({
        label: '实名认证策略',
        handler: () => handleCardOperation('realname-policy', row.iccid, row),
        type: 'primary'
      })
    }

    if (hasAuth('iot_card:update_realname_status')) {
      actions.push({
        label: '更新实名状态',
        handler: () => handleCardOperation('update-realname-status', row.iccid, row),
        type: 'primary'
      })
    }

    if (hasAuth('iot_card:clear_series')) {
      actions.push({
        label: '清除关联',
        handler: () => handleCardOperation('clear-series', row.iccid),
        type: 'primary'
      })
    }

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

    return actions
  }

  const exportQuery = computed(() => {
    const query: Record<string, unknown> = {}

    Object.entries(formFilters).forEach(([key, value]) => {
      if (value === undefined || value === null || value === '') return
      if (Array.isArray(value) && value.length === 0) return
      query[key] = value
    })

    return query
  })

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

  onMounted(() => {
    getTableData()
  })

  // 获取单卡列表
  const getTableData = async () => {
    loading.value = true
    try {
      const params: Record<string, any> = {
        page: pagination.page,
        page_size: pagination.pageSize,
        ...formFilters
      }
      Object.keys(params).forEach((key) => {
        if (params[key] === '' || params[key] === undefined) {
          delete params[key]
        }
      })

      const res = await CardService.getStandaloneIotCards(params)
      if (res.code === 0) {
        cardList.value = res.data.items || []
        pagination.total = res.data.total || 0
      }
    } catch (error) {
      console.error(error)
    } finally {
      loading.value = false
    }
  }

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

  // 搜索
  const handleSearch = () => {
    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: StandaloneIotCard[]) => {
    selectedCards.value = selection
  }

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

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

  const handleConfirmBatchRealnamePolicy = async (realnamePolicy: AssetRealnamePolicy) => {
    const assetIds = selectedCards.value.map((card) => card.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 CardService.batchUpdateRealnamePolicy(
        { asset_ids: assetIds, realname_policy: realnamePolicy },
        { requestOptions: { errorMessageMode: 'none' } }
      )
      if (res.code !== 0) {
        batchRealnamePolicyError.value = res.msg || '批量修改实名顺序失败'
        return
      }

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

  // 显示批量分配对话框
  const showAllocateDialog = () => {
    if (selectedCards.value.length === 0) {
      ElMessage.warning('请先选择要分配的卡')
      return
    }
    allocateDialogVisible.value = true
    Object.assign(allocateForm, {
      selection_type: CardSelectionType.LIST,
      to_shop_id: undefined,
      iccids: selectedCards.value.map((card) => card.iccid),
      iccid_start: '',
      iccid_end: '',
      carrier_id: undefined,
      status: undefined,
      batch_no: '',
      remark: ''
    })
    loadAllocateCarrierOptions()
    loadAllocateBatchNoOptions()
    if (allocateFormRef.value) {
      allocateFormRef.value.resetFields()
    }
  }

  // 显示批量回收对话框
  const showRecallDialog = () => {
    if (selectedCards.value.length === 0) {
      ElMessage.warning('请先选择要回收的卡')
      return
    }
    recallDialogVisible.value = true
    Object.assign(recallForm, {
      selection_type: CardSelectionType.LIST,
      iccids: selectedCards.value.map((card) => card.iccid),
      iccid_start: '',
      iccid_end: '',
      carrier_id: undefined,
      batch_no: '',
      remark: ''
    })
    if (recallFormRef.value) {
      recallFormRef.value.resetFields()
    }
    loadAllocateCarrierOptions()
    loadAllocateBatchNoOptions()
  }

  // 关闭批量分配对话框
  const handleAllocateDialogClose = () => {
    if (allocateFormRef.value) {
      allocateFormRef.value.resetFields()
    }
  }

  // 关闭批量回收对话框
  const handleRecallDialogClose = () => {
    if (recallFormRef.value) {
      recallFormRef.value.resetFields()
    }
  }

  // 执行批量分配
  const handleAllocate = async () => {
    if (!allocateFormRef.value) return

    await allocateFormRef.value.validate(async (valid) => {
      if (valid) {
        // 根据选卡方式构建请求参数
        const params: Partial<AllocateStandaloneCardsRequest> = {
          selection_type: allocateForm.selection_type!,
          to_shop_id: Array.isArray(allocateForm.to_shop_id)
            ? allocateForm.to_shop_id[allocateForm.to_shop_id.length - 1]
            : allocateForm.to_shop_id,
          remark: allocateForm.remark
        }

        if (allocateForm.selection_type === CardSelectionType.LIST) {
          params.iccids = selectedCards.value.map((card) => card.iccid)
          if (params.iccids.length === 0) {
            ElMessage.warning('请先选择要分配的卡')
            return
          }
        } else if (allocateForm.selection_type === CardSelectionType.RANGE) {
          params.iccid_start = allocateForm.iccid_start
          params.iccid_end = allocateForm.iccid_end
        } else if (allocateForm.selection_type === CardSelectionType.FILTER) {
          if (allocateForm.carrier_id) params.carrier_id = allocateForm.carrier_id
          if (allocateForm.status) params.status = allocateForm.status
          if (allocateForm.batch_no) params.batch_no = allocateForm.batch_no
        }

        allocateLoading.value = true
        try {
          const res = await CardService.allocateStandaloneCards(params)

          // code === 0 表示操作成功(接口调用成功),显示结果对话框
          if (res.code === 0) {
            allocationResult.value = res.data
            resultTitle.value = '批量分配结果'
            allocateDialogVisible.value = false
            resultDialogVisible.value = true

            // 清空选择
            selectedCards.value = []

            // 刷新列表
            await getTableData()
          }
        } catch (error) {
          console.error(error)
        } finally {
          allocateLoading.value = false
        }
      }
    })
  }

  // 执行批量回收
  const handleRecall = async () => {
    if (!recallFormRef.value) return

    await recallFormRef.value.validate(async (valid) => {
      if (valid) {
        // 根据选卡方式构建请求参数
        const params: Partial<RecallStandaloneCardsRequest> = {
          selection_type: recallForm.selection_type!,
          remark: recallForm.remark
        }

        if (recallForm.selection_type === CardSelectionType.LIST) {
          params.iccids = selectedCards.value.map((card) => card.iccid)
          if (params.iccids.length === 0) {
            ElMessage.warning('请先选择要回收的卡')
            return
          }
        } else if (recallForm.selection_type === CardSelectionType.RANGE) {
          params.iccid_start = recallForm.iccid_start
          params.iccid_end = recallForm.iccid_end
        } else if (recallForm.selection_type === CardSelectionType.FILTER) {
          if (recallForm.carrier_id) params.carrier_id = recallForm.carrier_id
          if (recallForm.batch_no) params.batch_no = recallForm.batch_no
        }

        recallLoading.value = true
        try {
          const res = await CardService.recallStandaloneCards(params)

          // code === 0 表示操作成功(接口调用成功),显示结果对话框
          if (res.code === 0) {
            allocationResult.value = res.data
            resultTitle.value = '批量回收结果'
            recallDialogVisible.value = false
            resultDialogVisible.value = true

            // 清空选择
            selectedCards.value = []

            // 刷新列表
            await getTableData()
          } else {
            // code !== 0 才是真正失败(接口调用失败)
            ElMessage.error(res.msg || '批量回收失败，请重试')
          }
        } catch (error) {
          console.error(error)
        } finally {
          recallLoading.value = false
        }
      }
    })
  }

  const getInferredCardEnterpriseId = () => {
    const filterEnterpriseId = formFilters.authorized_enterprise_id
    if (filterEnterpriseId) return filterEnterpriseId

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

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

  const resetEnterpriseCardAuthorizeForm = () => {
    Object.assign(enterpriseCardAuthorizeForm, createInitialEnterpriseCardAuthorizeState(), {
      selection_type:
        selectedCards.value.length > 0 ? CardSelectionType.LIST : CardSelectionType.FILTER,
      carrier_id: undefined,
      shop_id_path: undefined,
      batch_no: formFilters.batch_no || '',
      iccid: formFilters.iccid || ''
    })
  }

  const resetEnterpriseCardRecallForm = () => {
    Object.assign(enterpriseCardRecallForm, createInitialEnterpriseCardRecallState(), {
      enterprise_id: getInferredCardEnterpriseId(),
      selection_type:
        selectedCards.value.length > 0 ? CardSelectionType.LIST : CardSelectionType.FILTER,
      carrier_id: undefined,
      batch_no: formFilters.batch_no || '',
      iccid: formFilters.iccid || ''
    })
  }

  const showEnterpriseCardAuthorizeDialog = async () => {
    resetEnterpriseCardAuthorizeForm()
    await Promise.all([
      handleSearchEnterprise(),
      loadAllocateCarrierOptions(),
      loadAllocateBatchNoOptions(),
      loadTopLevelShopCascadeOptions()
    ])
    enterpriseCardAuthorizeDialogVisible.value = true
    enterpriseCardAuthorizeFormRef.value?.clearValidate()
  }

  const showEnterpriseCardRecallDialog = async () => {
    resetEnterpriseCardRecallForm()
    await Promise.all([
      handleSearchEnterprise(),
      loadAllocateCarrierOptions(),
      loadAllocateBatchNoOptions()
    ])
    enterpriseCardRecallDialogVisible.value = true
    enterpriseCardRecallFormRef.value?.clearValidate()
  }

  const handleEnterpriseCardAuthorizeDialogClose = () => {
    Object.assign(enterpriseCardAuthorizeForm, createInitialEnterpriseCardAuthorizeState())
    enterpriseCardAuthorizeFormRef.value?.resetFields()
  }

  const handleEnterpriseCardRecallDialogClose = () => {
    Object.assign(enterpriseCardRecallForm, createInitialEnterpriseCardRecallState())
    enterpriseCardRecallFormRef.value?.resetFields()
  }

  const appendEnterpriseCardFilterParams = (params: Record<string, unknown>, form: any) => {
    if (form.carrier_id) params.carrier_id = form.carrier_id
    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.batch_no) params.batch_no = form.batch_no
    if (form.iccid) params.iccid = form.iccid
  }

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

    if (form.selection_type === CardSelectionType.LIST) {
      const iccids = selectedCards.value.map((card) => card.iccid)
      if (!iccids.length) {
        ElMessage.warning('列表模式下请先选择卡')
        return null
      }
      params.iccids = iccids
    } else if (form.selection_type === CardSelectionType.RANGE) {
      params.iccid_start = form.iccid_start
      params.iccid_end = form.iccid_end
    } else {
      appendEnterpriseCardFilterParams(params, form)
    }

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

    return params
  }

  const applyEnterpriseCardOperationSuccess = async (
    title: string,
    result: AllocateCardsResponse | RecallCardsResponse
  ) => {
    enterpriseCardOperationResult.value = result
    enterpriseCardResultTitle.value = title
    enterpriseCardResultDialogVisible.value = true
    selectedCards.value = []
    await getTableData()
  }

  const handleEnterpriseCardAuthorize = async () => {
    if (!enterpriseCardAuthorizeFormRef.value) return

    await enterpriseCardAuthorizeFormRef.value.validate(async (valid) => {
      if (!valid) return
      const params = buildEnterpriseCardParams(enterpriseCardAuthorizeForm)
      if (!params) return

      enterpriseCardAuthorizeLoading.value = true
      try {
        const res = await EnterpriseService.allocateCards(
          enterpriseCardAuthorizeForm.enterprise_id!,
          params as any
        )
        if (res.code === 0) {
          enterpriseCardAuthorizeDialogVisible.value = false
          await applyEnterpriseCardOperationSuccess('授权卡给企业结果', res.data)
        }
      } catch (error) {
        console.error('授权卡给企业失败:', error)
      } finally {
        enterpriseCardAuthorizeLoading.value = false
      }
    })
  }

  const handleEnterpriseCardRecall = async () => {
    if (!enterpriseCardRecallFormRef.value) return

    await enterpriseCardRecallFormRef.value.validate(async (valid) => {
      if (!valid) return
      const params = buildEnterpriseCardParams(enterpriseCardRecallForm)
      if (!params) return

      enterpriseCardRecallLoading.value = true
      try {
        const res = await EnterpriseService.recallCards(
          enterpriseCardRecallForm.enterprise_id!,
          params as any
        )
        if (res.code === 0) {
          enterpriseCardRecallDialogVisible.value = false
          await applyEnterpriseCardOperationSuccess('回收卡授权结果', res.data)
        }
      } catch (error) {
        console.error('回收卡授权失败:', error)
      } finally {
        enterpriseCardRecallLoading.value = false
      }
    })
  }

  // 显示套餐系列绑定对话框
  const showSeriesBindingDialog = async () => {
    Object.assign(seriesBindingForm, createInitialSeriesBindingState(), {
      selection_type:
        selectedCards.value.length > 0 ? CardSelectionType.LIST : CardSelectionType.FILTER
    })
    await Promise.all([
      loadPackageSeriesList(),
      loadAllocateCarrierOptions(),
      loadAllocateBatchNoOptions()
    ])
    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 handleSeriesBindingDialogClose = () => {
    Object.assign(seriesBindingForm, createInitialSeriesBindingState())
    if (seriesBindingFormRef.value) {
      seriesBindingFormRef.value.resetFields()
    }
  }

  // 关闭套餐系列绑定结果对话框
  const handleSeriesBindingResultDialogClose = () => {
    // 刷新列表
    getTableData()
  }

  // 执行套餐系列绑定
  const handleSeriesBinding = async () => {
    if (!seriesBindingFormRef.value) return

    await seriesBindingFormRef.value.validate(async (valid) => {
      if (valid) {
        seriesBindingLoading.value = true
        try {
          const request: BatchSetCardSeriesBindingRequest = {
            selection_type: seriesBindingForm.selection_type,
            series_id: seriesBindingForm.series_id!
          }

          if (seriesBindingForm.selection_type === CardSelectionType.LIST) {
            const iccids = selectedCards.value.map((card) => card.iccid)
            if (iccids.length === 0) {
              ElMessage.warning('列表模式下请先选择要设置的卡')
              return
            }
            request.iccids = iccids
          } else if (seriesBindingForm.selection_type === CardSelectionType.RANGE) {
            request.iccid_start = seriesBindingForm.iccid_start
            request.iccid_end = seriesBindingForm.iccid_end
          } else {
            if (seriesBindingForm.carrier_id) request.carrier_id = seriesBindingForm.carrier_id
            if (seriesBindingForm.status) request.status = seriesBindingForm.status
            if (seriesBindingForm.batch_no) request.batch_no = seriesBindingForm.batch_no
          }

          const res = await CardService.batchSetCardSeriesBinding(request)

          if (res.code === 0) {
            seriesBindingResult.value = res.data
            seriesBindingDialogVisible.value = false
            seriesBindingResultDialogVisible.value = true

            // 清空选择
            selectedCards.value = []

            // 立即刷新列表
            await getTableData()

            // 显示消息提示
            if (res.data.fail_count === 0) {
              ElMessage.success('套餐系列绑定设置成功')
            } else if (res.data.success_count === 0) {
              ElMessage.error('套餐系列绑定设置失败')
            } else {
              ElMessage.warning(
                `部分设置成功：成功 ${res.data.success_count} 项，失败 ${res.data.fail_count} 项`
              )
            }
          }
        } catch (error) {
          console.error(error)
        } finally {
          seriesBindingLoading.value = false
        }
      }
    })
  }

  // IoT卡操作处理函数
  const handleCardOperation = (command: string, iccid: string, row?: any) => {
    switch (command) {
      case 'start-card':
        handleStartCard(iccid)
        break
      case 'stop-card':
        handleStopCard(iccid)
        break
      case 'realname-policy':
        handleShowRealnamePolicy(iccid, row?.realname_policy)
        break
      case 'update-realname-status':
        handleShowUpdateRealnameStatus(iccid, row?.real_name_status)
        break
      case 'clear-series':
        handleClearSingleCardSeries(iccid)
        break
    }
  }

  // 清除单卡套餐系列绑定
  const handleClearSingleCardSeries = (iccid: string) => {
    ElMessageBox.confirm(`确定要清除该卡（${iccid}）的套餐系列关联吗？`, '确认清除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(async () => {
        try {
          const res = await CardService.batchSetCardSeriesBinding({
            selection_type: CardSelectionType.LIST,
            iccids: [iccid],
            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 handleStartCard = (iccid: string) => {
    ElMessageBox.confirm('确定要启用该卡片吗？', '确认启用', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(async () => {
        try {
          // 使用统一接口：通过 identifier (ICCID) 启用资产
          const res = await AssetService.startAsset(iccid)
          if (res.code === 0) {
            ElMessage.success('启用成功')
            await getTableData()
          }
        } catch (error: any) {
          if (error instanceof FrontendRateLimitError) {
            ElMessage.warning(`操作过于频繁，请${formatRemainingTime(error.remainingMs)}后再试`)
            return
          }
          console.error('启用此卡失败:', error)
        }
      })
      .catch(() => {
        // 用户取消
      })
  }

  // 停用此卡（停机）
  const handleStopCard = (iccid: string) => {
    ElMessageBox.confirm('确定要停用该卡片吗？', '确认停用', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(async () => {
        try {
          // 使用统一接口：通过 identifier (ICCID) 停用资产
          const res = await AssetService.stopAsset(iccid)
          if (res.code === 0) {
            ElMessage.success('停用成功')
            await getTableData()
          }
        } catch (error: any) {
          if (error instanceof FrontendRateLimitError) {
            ElMessage.warning(`操作过于频繁，请${formatRemainingTime(error.remainingMs)}后再试`)
            return
          }
          console.error('停用此卡失败:', error)
        }
      })
      .catch(() => {
        // 用户取消
      })
  }
</script>

<style lang="scss" scoped>
  .range-allocation-hint {
    font-size: 13px;
    line-height: 20px;
    color: var(--el-text-color-secondary);
  }

  .range-allocation-hint--card {
    margin: -6px 0 18px 100px;
  }

  .range-allocation-hint--card-form {
    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>
