<template>
  <div class="tenant-package-page art-full-height">
    <PackageSearch
      v-show="showSearchBar"
      v-model="searchForm"
      @search="handleSearch"
      @reset="handleReset"
    />

    <ElCard
      class="art-table-card"
      shadow="never"
      :style="{ 'margin-top': showSearchBar ? '12px' : '0' }"
    >
      <ArtTableHeader
        v-model:columns="columnChecks"
        v-model:showSearchBar="showSearchBar"
        :loading="loading"
        @refresh="refreshData"
        @search="handleSearch"
      >
        <template #left>
          <ElSpace wrap>
            <ElButton
              v-if="hasAuth('tenant-package:create')"
              type="primary"
              @click="openDialog('create')"
              v-ripple
            >
              <template #icon><ArtSvgIcon icon="ri:add-line" /></template>
              {{ t('tenantPackage.actions.create') }}
            </ElButton>
          </ElSpace>
        </template>
      </ArtTableHeader>

      <ArtTable
        :loading="loading"
        :data="data"
        :columns="columns"
        :pagination="pagination"
        @pagination:size-change="handleSizeChange"
        @pagination:current-change="handleCurrentChange"
      >
        <template #name="{ row }">
          <div class="name-cell">
            <div class="name-title">
              <ArtSvgIcon v-if="row.isRecommended" icon="ri:star-fill" class="name-recommend" />
              <span class="name-text">{{ row.name }}</span>
            </div>
            <div v-if="row.tags?.length" class="name-tags">
              <ElTag
                v-for="tag in row.tags"
                :key="tag"
                class="name-tag"
                size="small"
                :type="getPackageTagType(tag)"
              >
                {{ getPackageTagLabel(tag) }}
              </ElTag>
            </div>
          </div>
        </template>

        <template #packageType="{ row }">
          <ElTag :type="getPackageTypeTag(row.packageType)">
            {{ getPackageTypeLabel(row.packageType) }}
          </ElTag>
        </template>

        <template #monthlyPrice="{ row }">
          <span>{{ renderPrice(row.monthlyPrice) }}</span>
        </template>

        <template #yearlyPrice="{ row }">
          <span>{{ renderPrice(row.yearlyPrice) }}</span>
        </template>

        <template #quota="{ row }">
          <div class="quota-cell">
            <span>{{ renderQuota(row) }}</span>
          </div>
        </template>

        <template #status="{ row }">
          <ElTag :type="row.isActive ? 'success' : 'danger'">
            {{
              row.isActive ? t('tenantPackage.status.enabled') : t('tenantPackage.status.disabled')
            }}
          </ElTag>
        </template>

        <template #publishStatus="{ row }">
          <ElTag :type="row.publishStatus === 1 ? 'success' : 'info'">
            {{
              row.publishStatus === 1
                ? t('tenantPackage.publishStatus.published')
                : t('tenantPackage.publishStatus.draft')
            }}
          </ElTag>
        </template>

        <template #publicVisible="{ row }">
          <ElTag :type="row.isPublicVisible ? 'success' : 'info'">
            {{ row.isPublicVisible ? t('common.yes') : t('common.no') }}
          </ElTag>
        </template>

        <template #allowNewPurchase="{ row }">
          <ElTag :type="row.isAllowNewTenantPurchase ? 'success' : 'info'">
            {{ row.isAllowNewTenantPurchase ? t('common.yes') : t('common.no') }}
          </ElTag>
        </template>

        <template #usage="{ row }">
          <div class="usage-cell">
            <template v-if="usageMap[row.id]">
              <div class="usage-line">
                <span class="usage-label">{{ t('tenantPackage.usage.activeSubscription') }}：</span>
                <span class="usage-value">
                  {{ usageMap[row.id].activeSubscriptionCount }}/{{
                    usageMap[row.id].totalSubscriptionCount
                  }}
                </span>
              </div>
              <div class="usage-line">
                <span class="usage-label">{{ t('tenantPackage.usage.activeTenant') }}：</span>
                <span class="usage-value">{{ usageMap[row.id].activeTenantCount }}</span>
              </div>
              <div class="usage-line">
                <span class="usage-label">{{ t('tenantPackage.usage.mrr') }}：</span>
                <span class="usage-value">{{ renderPrice(usageMap[row.id].mrr) }}</span>
              </div>
              <div class="usage-line">
                <span class="usage-label">{{ t('tenantPackage.usage.arr') }}：</span>
                <span class="usage-value">{{ renderPrice(usageMap[row.id].arr) }}</span>
              </div>
              <div class="usage-line">
                <span class="usage-label">{{ t('tenantPackage.usage.expiringIn') }}：</span>
                <div class="expiring-chips">
                  <button
                    class="expiring-chip danger"
                    type="button"
                    :disabled="tenantsLoading"
                    @click="openExpiringTenantsDrawer(row, 7)"
                  >
                    <span class="chip-label">7D</span>
                    <span class="chip-count">{{
                      usageMap[row.id].expiringTenantCount7Days ?? 0
                    }}</span>
                  </button>
                  <button
                    class="expiring-chip warning"
                    type="button"
                    :disabled="tenantsLoading"
                    @click="openExpiringTenantsDrawer(row, 15)"
                  >
                    <span class="chip-label">15D</span>
                    <span class="chip-count">{{
                      usageMap[row.id].expiringTenantCount15Days ?? 0
                    }}</span>
                  </button>
                  <button
                    class="expiring-chip primary"
                    type="button"
                    :disabled="tenantsLoading"
                    @click="openExpiringTenantsDrawer(row, 30)"
                  >
                    <span class="chip-label">30D</span>
                    <span class="chip-count">{{
                      usageMap[row.id].expiringTenantCount30Days ?? 0
                    }}</span>
                  </button>
                </div>
              </div>
            </template>
            <span v-else class="usage-empty">--</span>
          </div>
        </template>

        <template #actions="{ row }">
          <div class="action-wrap">
            <button
              v-if="hasAuth('tenant-package:read')"
              class="art-action-btn"
              @click="openDialog('view', row)"
            >
              <ArtSvgIcon icon="ri:information-line" class="art-action-icon" />
              <span>{{ t('dictionary.common.detail') }}</span>
            </button>
            <button
              v-if="hasAuth('tenant-package:update')"
              class="art-action-btn primary"
              @click="openDialog('edit', row)"
            >
              <ArtSvgIcon icon="ri:edit-2-line" class="art-action-icon" />
              <span>{{ t('tenantPackage.actions.edit') }}</span>
            </button>
            <ElDropdown trigger="click" @command="(cmd) => handleMoreActionClick(cmd, row)">
              <button class="art-action-btn info">
                <ArtSvgIcon icon="ri:more-2-line" class="art-action-icon" />
                <span>{{ t('tenantPackage.actions.more') }}</span>
              </button>
              <template #dropdown>
                <ElDropdownMenu>
                  <ElDropdownItem v-if="hasAuth('tenant-package:create')" command="copy">
                    <span class="dropdown-item">
                      <ArtSvgIcon icon="ri:file-copy-line" class="dropdown-icon" />
                      <span>{{ t('tenantPackage.actions.copy') }}</span>
                    </span>
                  </ElDropdownItem>

                  <ElDropdownItem v-if="hasAuth('tenant-package:update')" command="toggleActive">
                    <span class="dropdown-item">
                      <ArtSvgIcon icon="ri:toggle-line" class="dropdown-icon" />
                      <span>{{ t('tenantPackage.actions.toggleActive') }}</span>
                    </span>
                  </ElDropdownItem>

                  <ElDropdownItem v-if="hasAuth('tenant-package:update')" command="toggleVisible">
                    <span class="dropdown-item">
                      <ArtSvgIcon icon="ri:eye-line" class="dropdown-icon" />
                      <span>
                        {{ t('tenantPackage.actions.toggleVisible') }}:
                        <span class="more-actions-yn" :class="row.isPublicVisible ? 'yes' : 'no'">
                          {{ row.isPublicVisible ? t('common.yes') : t('common.no') }}
                        </span>
                      </span>
                    </span>
                  </ElDropdownItem>

                  <ElDropdownItem
                    v-if="hasAuth('tenant-package:update')"
                    command="togglePurchasable"
                  >
                    <span class="dropdown-item">
                      <ArtSvgIcon icon="ri:shopping-cart-2-line" class="dropdown-icon" />
                      <span>
                        {{ t('tenantPackage.actions.togglePurchasable') }}:
                        <span
                          class="more-actions-yn"
                          :class="row.isAllowNewTenantPurchase ? 'yes' : 'no'"
                        >
                          {{ row.isAllowNewTenantPurchase ? t('common.yes') : t('common.no') }}
                        </span>
                      </span>
                    </span>
                  </ElDropdownItem>

                  <ElDropdownItem
                    v-if="row.publishStatus === 0 && hasAuth('tenant-package:update')"
                    command="publish"
                  >
                    <span class="dropdown-item">
                      <ArtSvgIcon icon="ri:send-plane-line" class="dropdown-icon" />
                      <span>{{ t('tenantPackage.actions.publish') }}</span>
                    </span>
                  </ElDropdownItem>

                  <ElDropdownItem
                    v-if="row.publishStatus === 1 && hasAuth('tenant-package:update')"
                    command="rollbackDraft"
                  >
                    <span class="dropdown-item">
                      <ArtSvgIcon icon="ri:arrow-go-back-line" class="dropdown-icon" />
                      <span>{{ t('tenantPackage.actions.rollbackDraft') }}</span>
                    </span>
                  </ElDropdownItem>

                  <ElDropdownItem v-if="hasAuth('tenant-package:update')" command="quotaEdit">
                    <span class="dropdown-item">
                      <ArtSvgIcon icon="ri:stack-line" class="dropdown-icon" />
                      <span>{{ t('tenantPackage.actions.quotaEdit') }}</span>
                    </span>
                  </ElDropdownItem>

                  <ElDropdownItem v-if="hasAuth('tenant-package:read')" command="viewTenants">
                    <span class="dropdown-item">
                      <ArtSvgIcon icon="ri:group-line" class="dropdown-icon" />
                      <span>{{ t('tenantPackage.actions.viewTenants') }}</span>
                    </span>
                  </ElDropdownItem>

                  <ElDropdownItem v-if="hasAuth('tenant-package:delete')" command="delete" divided>
                    <span class="dropdown-item danger">
                      <ArtSvgIcon icon="ri:delete-bin-line" class="dropdown-icon" />
                      <span>{{ t('tenantPackage.actions.delete') }}</span>
                    </span>
                  </ElDropdownItem>
                </ElDropdownMenu>
              </template>
            </ElDropdown>
          </div>
        </template>
      </ArtTable>
    </ElCard>

    <PackageFormDialog
      v-model="dialogVisible"
      :mode="dialogMode"
      :package-id="currentPackageId"
      @success="handleDialogSuccess"
    />

    <PackageDetailDrawer
      v-model="detailDrawerVisible"
      :package-id="currentPackageId"
      :package-name="currentPackageName"
    />

    <PackageQuotaDialog
      v-model="quotaDialogVisible"
      :package-id="currentPackageId"
      :package-name="currentPackageName"
      @success="handleDialogSuccess"
    />

    <ElDrawer v-model="tenantsDrawerVisible" :title="tenantsDrawerTitle" size="min(960px, 92vw)">
      <div class="drawer-body">
        <ElSpace wrap class="drawer-toolbar">
          <ElInput
            v-model="tenantsKeyword"
            clearable
            class="drawer-search-input"
            :placeholder="t('tenantPackage.drawer.searchPlaceholder')"
            @keyup.enter="handleTenantsSearch"
          />
          <ElButton type="primary" :loading="tenantsLoading" @click="handleTenantsSearch">
            {{ t('table.searchBar.search') }}
          </ElButton>
          <ElButton :disabled="tenantsLoading" @click="handleTenantsReset">
            {{ t('table.searchBar.reset') }}
          </ElButton>
        </ElSpace>

        <ElTable :data="tenantsData" v-loading="tenantsLoading" height="520" class="w-full">
          <ElTableColumn
            prop="name"
            :label="t('tenantPackage.drawer.tenantName')"
            min-width="180"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="code"
            :label="t('tenantPackage.drawer.tenantCode')"
            min-width="140"
            show-overflow-tooltip
          />
          <ElTableColumn :label="t('tenantPackage.drawer.tenantStatus')" min-width="110">
            <template #default="{ row }">
              <ElTag :type="getTenantStatusTag(row.status)">{{
                getTenantStatusText(row.status)
              }}</ElTag>
            </template>
          </ElTableColumn>
          <ElTableColumn
            prop="contactName"
            :label="t('tenantPackage.drawer.contact')"
            min-width="140"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="contactPhone"
            :label="t('tenantPackage.drawer.phone')"
            min-width="150"
            show-overflow-tooltip
          />
          <ElTableColumn
            prop="subscriptionEffectiveTo"
            :label="t('tenantPackage.drawer.effectiveTo')"
            min-width="180"
            :formatter="(row) => formatDateTime(row.subscriptionEffectiveTo)"
            show-overflow-tooltip
          />
        </ElTable>

        <div class="drawer-pagination">
          <ElPagination
            background
            layout="total, sizes, prev, pager, next, jumper"
            :total="tenantsTotal"
            :current-page="tenantsPage"
            :page-size="tenantsPageSize"
            :page-sizes="[10, 20, 50, 100]"
            @current-change="handleTenantsPageChange"
            @size-change="handleTenantsPageSizeChange"
          />
        </div>
      </div>
    </ElDrawer>
  </div>
</template>

<script setup lang="ts">
  import { computed, reactive, ref } from 'vue'
  import { useI18n } from 'vue-i18n'
  import ArtTable from '@/components/core/tables/art-table/index.vue'
  import ArtTableHeader from '@/components/core/tables/art-table-header/index.vue'
  import ArtSvgIcon from '@/components/core/base/art-svg-icon/index.vue'
  import PackageSearch from './modules/package-search.vue'
  import PackageFormDialog from './modules/package-form-dialog.vue'
  import PackageDetailDrawer from './modules/package-detail-drawer.vue'
  import PackageQuotaDialog from './modules/package-quota-dialog.vue'
  import { useTable } from '@/hooks/core/useTable'
  import type { ColumnOption } from '@/types/component'
  import {
    fetchDeleteTenantPackage,
    fetchTenantPackageDetail,
    fetchTenantPackageList,
    fetchTenantPackageTenants,
    fetchTenantPackageUsages,
    fetchUpdateTenantPackage
  } from '@/api/tenant-package'
  import {
    ElCard,
    ElButton,
    ElTag,
    ElMessageBox,
    ElMessage,
    ElSpace,
    ElDrawer,
    ElInput,
    ElPagination,
    ElTable,
    ElTableColumn,
    ElDropdown,
    ElDropdownMenu,
    ElDropdownItem
  } from 'element-plus'
  import { TenantPackageTypeEnum } from '@/enums/TenantPackageType'
  import { TenantStatus } from '@/enums/TenantStatus'
  import { useAuth } from '@/hooks/core/useAuth'

  defineOptions({ name: 'TenantPackage' })

  type TenantPackageRecord = Api.Tenant.TenantPackageDto
  type PackageSearchModel = { keyword: string; isActive?: boolean | '' }

  const { t } = useI18n()
  const { hasAuth } = useAuth()

  // 1. 组件状态
  const showSearchBar = ref(true)
  const searchForm = ref<PackageSearchModel>({
    keyword: '',
    isActive: ''
  })
  const dialogVisible = ref(false)
  const detailDrawerVisible = ref(false)
  const dialogMode = ref<'create' | 'edit' | 'view' | 'copy'>('create')
  const currentPackageId = ref<string>('')
  const currentPackageName = ref<string>('')
  const quotaDialogVisible = ref(false)
  const moreVisibleMap = reactive<Record<string, boolean>>({})

  const usageMap = ref<Record<string, Api.Tenant.TenantPackageUsageDto>>({})

  const tenantsDrawerVisible = ref(false)
  const tenantsKeyword = ref('')
  const tenantsLoading = ref(false)
  const tenantsData = ref<Api.Tenant.TenantPackageTenantDto[]>([])
  const tenantsPage = ref(1)
  const tenantsPageSize = ref(20)
  const tenantsTotal = ref(0)
  const tenantsExpiringWithinDays = ref<number | undefined>(undefined)

  // 2. 枚举与格式化
  type ElTagType = 'primary' | 'success' | 'warning' | 'info' | 'danger'
  type PackageTypeOption = { value: number; label: string; tag: ElTagType }

  const packageTypeOptions = computed<PackageTypeOption[]>(() => [
    { value: TenantPackageTypeEnum.Free, label: t('tenantPackage.type.free'), tag: 'info' },
    {
      value: TenantPackageTypeEnum.Standard,
      label: t('tenantPackage.type.standard'),
      tag: 'primary'
    },
    {
      value: TenantPackageTypeEnum.Professional,
      label: t('tenantPackage.type.professional'),
      tag: 'warning'
    },
    {
      value: TenantPackageTypeEnum.Enterprise,
      label: t('tenantPackage.type.enterprise'),
      tag: 'success'
    }
  ])

  const getPackageTypeLabel = (value: number) =>
    packageTypeOptions.value.find((item) => item.value === value)?.label ||
    t('tenantPackage.type.standard')

  const getPackageTypeTag = (value: number): ElTagType =>
    packageTypeOptions.value.find((item) => item.value === value)?.tag || 'info'

  const renderPrice = (value?: number) => {
    if (value === null || value === undefined) return '--'
    return `￥${Number(value).toFixed(2)}`
  }

  const renderQuota = (row: TenantPackageRecord) => {
    const fields = [
      { label: t('tenantPackage.form.maxStoreCount'), value: row.maxStoreCount },
      { label: t('tenantPackage.form.maxAccountCount'), value: row.maxAccountCount },
      { label: t('tenantPackage.form.maxStorageGb'), value: row.maxStorageGb },
      { label: t('tenantPackage.form.maxSmsCredits'), value: row.maxSmsCredits },
      { label: t('tenantPackage.form.maxDeliveryOrders'), value: row.maxDeliveryOrders }
    ].filter((item) => item.value !== null && item.value !== undefined)

    if (!fields.length) return t('tenantPackage.table.quotaEmpty')
    return fields.map((item) => `${item.label}：${item.value}`).join(' / ')
  }

  const tenantsDrawerTitle = computed(() => {
    const name = currentPackageName.value || '--'
    if (tenantsExpiringWithinDays.value) {
      return t('tenantPackage.drawer.expiringTitle', {
        name,
        days: tenantsExpiringWithinDays.value
      })
    }
    return t('tenantPackage.drawer.title', { name })
  })

  const getTenantStatusText = (status: number) => {
    switch (status) {
      case TenantStatus.PendingReview:
        return t('tenant.status.pendingReview')
      case TenantStatus.Active:
        return t('tenant.status.active')
      case TenantStatus.Suspended:
        return t('tenant.status.suspended')
      case TenantStatus.Expired:
        return t('tenant.status.expired')
      case TenantStatus.Closed:
        return t('tenant.status.closed')
      default:
        return t('tenant.status.unknown')
    }
  }

  const getTenantStatusTag = (status: number): ElTagType => {
    switch (status) {
      case TenantStatus.Active:
        return 'success'
      case TenantStatus.PendingReview:
        return 'warning'
      case TenantStatus.Suspended:
        return 'danger'
      case TenantStatus.Expired:
        return 'info'
      case TenantStatus.Closed:
        return 'info'
      default:
        return 'info'
    }
  }

  const getPackageTagLabel = (tag: string) => {
    switch (tag) {
      case 'recommended':
        return t('tenantPackage.tags.recommended')
      case 'bestValue':
        return t('tenantPackage.tags.bestValue')
      case 'flagship':
        return t('tenantPackage.tags.flagship')
      default:
        return tag
    }
  }

  const getPackageTagType = (tag: string): ElTagType => {
    switch (tag) {
      case 'recommended':
        return 'success'
      case 'bestValue':
        return 'warning'
      case 'flagship':
        return 'danger'
      default:
        return 'info'
    }
  }

  const formatDateTime = (value?: string) => {
    if (!value) return '-'
    const date = new Date(value)
    if (Number.isNaN(date.getTime())) return value
    return date.toLocaleString()
  }

  const buildUpdatePayload = (
    detail: Api.Tenant.TenantPackageDto,
    override: Partial<Api.Tenant.CreateTenantPackageCommand>
  ): Api.Tenant.UpdateTenantPackageCommand => ({
    tenantPackageId: detail.id,
    name: detail.name,
    description: detail.description,
    packageType: detail.packageType,
    monthlyPrice: detail.monthlyPrice,
    yearlyPrice: detail.yearlyPrice,
    maxStoreCount: detail.maxStoreCount,
    maxAccountCount: detail.maxAccountCount,
    maxStorageGb: detail.maxStorageGb,
    maxSmsCredits: detail.maxSmsCredits,
    maxDeliveryOrders: detail.maxDeliveryOrders,
    featurePoliciesJson: detail.featurePoliciesJson,
    isActive: detail.isActive,
    isPublicVisible: detail.isPublicVisible,
    isAllowNewTenantPurchase: detail.isAllowNewTenantPurchase,
    publishStatus: detail.publishStatus,
    isRecommended: detail.isRecommended,
    tags: Array.isArray(detail.tags) ? detail.tags : [],
    sortOrder: detail.sortOrder,
    ...override
  })

  // 3. 表格配置
  const {
    data,
    loading,
    pagination,
    columns,
    columnChecks,
    refreshData,
    handleSizeChange,
    handleCurrentChange
  } = useTable<(params: { current: number; size: number }) => Promise<any>, TenantPackageRecord>({
    core: {
      apiFn: async (params: { current: number; size: number }) => {
        // 1. 构造查询参数
        const query: Api.Tenant.TenantPackageQueryParams = {
          Keyword: searchForm.value.keyword?.trim() || undefined,
          IsActive:
            typeof searchForm.value.isActive === 'boolean' ? searchForm.value.isActive : undefined,
          Page: params.current,
          PageSize: params.size
        }

        // 2. 请求接口
        const res = await fetchTenantPackageList(query)
        const items = (res as any).items || []
        const total = (res as any).totalCount ?? items.length

        // 3. 拉取使用统计
        try {
          const ids = items.map((it: TenantPackageRecord) => it.id).filter(Boolean)
          const usages = await fetchTenantPackageUsages(ids)
          usageMap.value = (usages || []).reduce<Record<string, Api.Tenant.TenantPackageUsageDto>>(
            (acc, item) => {
              acc[item.tenantPackageId] = item
              return acc
            },
            {}
          )
        } catch {
          usageMap.value = {}
        }

        return {
          data: {
            list: items,
            total
          }
        }
      },
      columnsFactory: (): ColumnOption<TenantPackageRecord>[] => [
        { type: 'globalIndex', label: t('table.column.index'), width: 60, fixed: 'left' },
        {
          prop: 'name',
          label: t('tenantPackage.table.name'),
          minWidth: 180,
          slotName: 'name',
          useSlot: true,
          showOverflowTooltip: true
        },
        {
          prop: 'packageType',
          label: t('tenantPackage.table.packageType'),
          width: 110,
          slotName: 'packageType',
          useSlot: true
        },
        {
          prop: 'publishStatus',
          label: t('tenantPackage.table.publishStatus'),
          width: 100,
          slotName: 'publishStatus',
          useSlot: true
        },
        {
          prop: 'isPublicVisible',
          label: t('tenantPackage.table.publicVisible'),
          width: 90,
          slotName: 'publicVisible',
          useSlot: true
        },
        {
          prop: 'isAllowNewTenantPurchase',
          label: t('tenantPackage.table.allowNewPurchase'),
          width: 90,
          slotName: 'allowNewPurchase',
          useSlot: true
        },
        {
          prop: 'monthlyPrice',
          label: t('tenantPackage.table.monthlyPrice'),
          width: 100,
          slotName: 'monthlyPrice',
          useSlot: true
        },
        {
          prop: 'yearlyPrice',
          label: t('tenantPackage.table.yearlyPrice'),
          width: 100,
          slotName: 'yearlyPrice',
          useSlot: true
        },
        {
          prop: 'quota',
          label: t('tenantPackage.table.quota'),
          minWidth: 220,
          slotName: 'quota',
          useSlot: true,
          showOverflowTooltip: true
        },
        {
          prop: 'usage',
          label: t('tenantPackage.table.usage'),
          minWidth: 220,
          slotName: 'usage',
          useSlot: true
        },
        {
          prop: 'isActive',
          label: t('tenantPackage.table.status'),
          width: 90,
          slotName: 'status',
          useSlot: true
        },
        {
          prop: 'actions',
          label: t('tenantPackage.table.actions'),
          width: 260,
          fixed: 'right',
          slotName: 'actions',
          useSlot: true
        }
      ]
    }
  })

  // 4. 事件处理
  const handleSearch = () => {
    handleCurrentChange(1)
  }

  const handleReset = () => {
    searchForm.value.keyword = ''
    searchForm.value.isActive = ''
    handleSearch()
  }

  const openDialog = (mode: 'create' | 'edit' | 'view', row?: TenantPackageRecord) => {
    currentPackageId.value = row?.id || ''
    currentPackageName.value = row?.name || ''

    if (mode === 'view') {
      detailDrawerVisible.value = true
      return
    }

    dialogMode.value = mode
    dialogVisible.value = true
  }

  const openCopyDialog = (row: TenantPackageRecord) => {
    dialogMode.value = 'copy'
    currentPackageId.value = row.id
    currentPackageName.value = row.name
    dialogVisible.value = true
  }

  const openQuotaDialog = (row: TenantPackageRecord) => {
    currentPackageId.value = row.id
    currentPackageName.value = row.name
    quotaDialogVisible.value = true
  }

  const openTenantsDrawer = async (row: TenantPackageRecord) => {
    currentPackageId.value = row.id
    currentPackageName.value = row.name
    tenantsExpiringWithinDays.value = undefined
    tenantsKeyword.value = ''
    tenantsPage.value = 1
    tenantsPageSize.value = 20
    tenantsDrawerVisible.value = true
    await loadTenants()
  }

  const openExpiringTenantsDrawer = async (row: TenantPackageRecord, days: number) => {
    currentPackageId.value = row.id
    currentPackageName.value = row.name
    tenantsExpiringWithinDays.value = days
    tenantsKeyword.value = ''
    tenantsPage.value = 1
    tenantsPageSize.value = 20
    tenantsDrawerVisible.value = true
    await loadTenants()
  }

  const loadTenants = async () => {
    if (!currentPackageId.value) return
    tenantsLoading.value = true
    try {
      const res = await fetchTenantPackageTenants(currentPackageId.value, {
        keyword: tenantsKeyword.value?.trim() || undefined,
        expiringWithinDays: tenantsExpiringWithinDays.value,
        page: tenantsPage.value,
        pageSize: tenantsPageSize.value
      })

      tenantsData.value = (res as any).items || []
      tenantsTotal.value = (res as any).totalCount ?? 0
    } catch {
      // 1. 查询失败时兜底为空态（错误提示由全局拦截器负责）
      tenantsData.value = []
      tenantsTotal.value = 0
    } finally {
      tenantsLoading.value = false
    }
  }

  const handleTenantsSearch = async () => {
    tenantsPage.value = 1
    await loadTenants()
  }

  const handleTenantsReset = async () => {
    tenantsKeyword.value = ''
    tenantsPage.value = 1
    await loadTenants()
  }

  const handleTenantsPageChange = async (page: number) => {
    tenantsPage.value = page
    await loadTenants()
  }

  const handleTenantsPageSizeChange = async (size: number) => {
    tenantsPageSize.value = size
    tenantsPage.value = 1
    await loadTenants()
  }

  const handleToggleActive = async (row: TenantPackageRecord) => {
    const isEnable = !row.isActive
    try {
      await ElMessageBox.confirm(
        isEnable
          ? t('tenantPackage.message.toggleConfirmEnable')
          : t('tenantPackage.message.toggleConfirmDisable'),
        isEnable
          ? t('tenantPackage.message.toggleTitleEnable')
          : t('tenantPackage.message.toggleTitleDisable'),
        {
          type: 'warning',
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel')
        }
      )

      // 1. 获取详情（避免 PUT 覆盖字段）
      const detail = await fetchTenantPackageDetail(row.id)

      // 2. 执行更新
      await fetchUpdateTenantPackage(row.id, buildUpdatePayload(detail, { isActive: isEnable }))
      ElMessage.success(
        isEnable
          ? t('tenantPackage.message.toggleSuccessEnable')
          : t('tenantPackage.message.toggleSuccessDisable')
      )

      // 3. 刷新列表
      refreshData()
    } catch {
      // 用户取消
    }
  }

  const handleToggleVisible = async (row: TenantPackageRecord) => {
    const isEnable = !row.isPublicVisible
    try {
      await ElMessageBox.confirm(
        isEnable
          ? t('tenantPackage.message.toggleVisibleConfirmEnable')
          : t('tenantPackage.message.toggleVisibleConfirmDisable'),
        isEnable
          ? t('tenantPackage.message.toggleVisibleTitleEnable')
          : t('tenantPackage.message.toggleVisibleTitleDisable'),
        {
          type: 'warning',
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel')
        }
      )

      // 1. 获取详情（避免 PUT 覆盖字段）
      const detail = await fetchTenantPackageDetail(row.id)

      // 2. 执行更新
      await fetchUpdateTenantPackage(
        row.id,
        buildUpdatePayload(detail, { isPublicVisible: isEnable })
      )
      ElMessage.success(
        isEnable
          ? t('tenantPackage.message.toggleVisibleSuccessEnable')
          : t('tenantPackage.message.toggleVisibleSuccessDisable')
      )

      // 3. 刷新列表
      refreshData()
    } catch {
      // 用户取消
    }
  }

  const handleTogglePurchasable = async (row: TenantPackageRecord) => {
    const isEnable = !row.isAllowNewTenantPurchase
    try {
      await ElMessageBox.confirm(
        isEnable
          ? t('tenantPackage.message.togglePurchasableConfirmEnable')
          : t('tenantPackage.message.togglePurchasableConfirmDisable'),
        isEnable
          ? t('tenantPackage.message.togglePurchasableTitleEnable')
          : t('tenantPackage.message.togglePurchasableTitleDisable'),
        {
          type: 'warning',
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel')
        }
      )

      // 1. 获取详情（避免 PUT 覆盖字段）
      const detail = await fetchTenantPackageDetail(row.id)

      // 2. 执行更新
      await fetchUpdateTenantPackage(
        row.id,
        buildUpdatePayload(detail, { isAllowNewTenantPurchase: isEnable })
      )
      ElMessage.success(
        isEnable
          ? t('tenantPackage.message.togglePurchasableSuccessEnable')
          : t('tenantPackage.message.togglePurchasableSuccessDisable')
      )

      // 3. 刷新列表
      refreshData()
    } catch {
      // 用户取消
    }
  }

  const handlePublish = async (row: TenantPackageRecord) => {
    try {
      await ElMessageBox.confirm(
        t('tenantPackage.message.publishConfirm'),
        t('tenantPackage.message.publishTitle'),
        {
          type: 'warning',
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel')
        }
      )

      // 1. 获取详情（避免 PUT 覆盖字段）
      const detail = await fetchTenantPackageDetail(row.id)

      // 2. 执行发布
      await fetchUpdateTenantPackage(
        row.id,
        buildUpdatePayload(detail, {
          publishStatus: 1
        })
      )
      ElMessage.success(t('tenantPackage.message.publishSuccess'))
      refreshData()
    } catch {
      // 用户取消
    }
  }

  const handleRollbackDraft = async (row: TenantPackageRecord) => {
    try {
      await ElMessageBox.confirm(
        t('tenantPackage.message.rollbackDraftConfirm'),
        t('tenantPackage.message.rollbackDraftTitle'),
        {
          type: 'warning',
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel')
        }
      )

      // 1. 获取详情（避免 PUT 覆盖字段）
      const detail = await fetchTenantPackageDetail(row.id)

      // 2. 回滚草稿
      await fetchUpdateTenantPackage(row.id, buildUpdatePayload(detail, { publishStatus: 0 }))
      ElMessage.success(t('tenantPackage.message.rollbackDraftSuccess'))
      refreshData()
    } catch {
      // 用户取消
    }
  }

  const handleMoreCommand = async (
    cmd:
      | 'copy'
      | 'toggleActive'
      | 'toggleVisible'
      | 'togglePurchasable'
      | 'publish'
      | 'rollbackDraft'
      | 'quotaEdit'
      | 'viewTenants'
      | 'delete',
    row: TenantPackageRecord
  ) => {
    if (cmd === 'copy') openCopyDialog(row)
    if (cmd === 'toggleActive') await handleToggleActive(row)
    if (cmd === 'toggleVisible') await handleToggleVisible(row)
    if (cmd === 'togglePurchasable') await handleTogglePurchasable(row)
    if (cmd === 'publish') await handlePublish(row)
    if (cmd === 'rollbackDraft') await handleRollbackDraft(row)
    if (cmd === 'quotaEdit') openQuotaDialog(row)
    if (cmd === 'viewTenants') await openTenantsDrawer(row)
    if (cmd === 'delete') await handleDelete(row)
  }

  const handleMoreActionClick = async (
    cmd:
      | 'copy'
      | 'toggleActive'
      | 'toggleVisible'
      | 'togglePurchasable'
      | 'publish'
      | 'rollbackDraft'
      | 'quotaEdit'
      | 'viewTenants'
      | 'delete',
    row: TenantPackageRecord
  ) => {
    moreVisibleMap[row.id] = false
    await handleMoreCommand(cmd, row)
  }

  const handleDelete = async (row: TenantPackageRecord) => {
    try {
      await ElMessageBox.confirm(
        t('tenantPackage.message.deleteConfirm'),
        t('tenantPackage.message.deleteTitle'),
        {
          type: 'warning',
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel')
        }
      )
      await fetchDeleteTenantPackage(row.id)
      ElMessage.success(t('tenantPackage.message.deleteSuccess'))
      refreshData()
    } catch {
      // 用户取消
    }
  }

  const handleDialogSuccess = async () => {
    await refreshData()
  }
</script>

<style scoped>
  .tenant-package-page :deep(.el-card__body) {
    padding-top: 12px;
  }

  :deep(.el-input__inner),
  :deep(.el-textarea__inner) {
    text-align: left;
  }

  :deep(.el-input-number .el-input__inner) {
    text-align: left;
  }

  .quota-cell {
    display: inline-flex;
    align-items: center;
    line-height: 1.4;
    color: var(--el-text-color-regular);
  }

  .name-cell {
    display: flex;
    flex-direction: column;
    gap: 6px;
    line-height: 1.2;
  }

  .name-title {
    display: inline-flex;
    gap: 6px;
    align-items: center;
  }

  .name-text {
    font-weight: 600;
    color: var(--el-text-color-primary);
  }

  .name-recommend {
    font-size: 14px;
    color: var(--el-color-warning);
  }

  .name-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
  }

  :deep(.name-tag) {
    border-radius: 999px;
  }

  .art-action-icon {
    display: flex;
    font-size: 16px;
  }

  .action-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
  }

  .dropdown-item {
    display: inline-flex;
    gap: 8px;
    align-items: center;
  }

  .dropdown-item.danger {
    color: var(--el-color-danger);
  }

  .dropdown-icon {
    font-size: 16px;
  }

  .more-actions-yn {
    font-weight: 700;
    color: var(--el-color-danger);
  }

  .more-actions-yn.yes {
    color: var(--el-color-success);
  }

  .usage-cell {
    display: flex;
    flex-direction: column;
    gap: 2px;
    line-height: 1.2;
  }

  .usage-line {
    display: inline-flex;
    gap: 4px;
    align-items: center;
    color: var(--el-text-color-regular);
  }

  .usage-label {
    font-size: 12px;
    color: var(--el-text-color-secondary);
  }

  .usage-value {
    font-size: 12px;
    font-weight: 500;
    color: var(--el-text-color-regular);
  }

  .expiring-chips {
    display: inline-flex;
    gap: 6px;
    align-items: center;
  }

  .expiring-chip {
    display: inline-flex;
    gap: 6px;
    align-items: center;
    padding: 4px 8px;
    font-size: 12px;
    line-height: 1;
    cursor: pointer;
    user-select: none;
    background: var(--el-fill-color-light);
    border: 1px solid var(--el-border-color-lighter);
    border-radius: 999px;
    transition:
      transform 0.12s ease,
      box-shadow 0.12s ease,
      filter 0.12s ease;
  }

  .expiring-chip .chip-label {
    font-weight: 600;
    opacity: 0.9;
  }

  .expiring-chip .chip-count {
    min-width: 18px;
    padding: 2px 6px;
    font-weight: 800;
    color: var(--el-text-color-primary);
    background: var(--el-bg-color);
    border-radius: 999px;
  }

  .expiring-chip:hover {
    filter: brightness(0.99);
    box-shadow: 0 6px 18px rgb(0 0 0 / 8%);
    transform: translateY(-1px);
  }

  .expiring-chip:active {
    transform: translateY(0);
  }

  .expiring-chip:disabled {
    cursor: not-allowed;
    box-shadow: none;
    opacity: 0.6;
    transform: none;
  }

  .expiring-chip.primary {
    color: var(--el-color-primary);
    background: var(--el-color-primary-light-9);
    border-color: var(--el-color-primary-light-8);
  }

  .expiring-chip.warning {
    color: var(--el-color-warning);
    background: var(--el-color-warning-light-9);
    border-color: var(--el-color-warning-light-8);
  }

  .expiring-chip.danger {
    color: var(--el-color-danger);
    background: var(--el-color-danger-light-9);
    border-color: var(--el-color-danger-light-8);
  }

  .usage-empty {
    font-size: 12px;
    color: var(--el-text-color-secondary);
  }

  .drawer-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }

  .drawer-toolbar {
    width: 100%;
  }

  .drawer-search-input {
    width: 240px;
  }

  .drawer-pagination {
    display: flex;
    justify-content: flex-end;
  }

  .drawer-body :deep(.el-table .cell) {
    white-space: nowrap;
  }
</style>
