<template>
  <div class="space-y-4">
    <a-page-header title="已购产品" sub-title="订阅与授权信息">
      <template #extra>
        <a-space>
          <a-input
            v-model:value="keywords"
            allow-clear
            placeholder="搜索产品名称"
            class="w-56"
            @press-enter="doSearch"
          />
          <a-button :loading="loading" @click="refresh">刷新</a-button>
        </a-space>
      </template>
    </a-page-header>

    <!-- 统计卡片 -->
    <a-row :gutter="[16, 16]">
      <a-col :xs="8" :md="4" v-for="stat in stats" :key="stat.label">
        <div class="mini-stat" :class="stat.color">
          <div class="mini-stat-value">{{ stat.value }}</div>
          <div class="mini-stat-label">{{ stat.label }}</div>
        </div>
      </a-col>
    </a-row>

    <a-card :bordered="false" class="card">
      <!-- 筛选 -->
      <a-space class="mb-4" wrap>
        <a-segmented
          v-model:value="statusFilter"
          :options="statusOptions"
          @change="doSearch"
        />
        <a-select
          v-model:value="productType"
          allow-clear
          placeholder="产品类型"
          style="min-width: 140px"
          @change="doSearch"
        >
          <a-select-option value="website">企业官网</a-select-option>
          <a-select-option value="shop">电商系统</a-select-option>
          <a-select-option value="mp">小程序/公众号</a-select-option>
        </a-select>
      </a-space>

      <a-alert v-if="error" class="mb-4" show-icon type="error" :message="error" />

      <!-- 产品卡片列表 -->
      <div v-if="loading" class="product-loading">
        <a-spin tip="加载中..." />
      </div>

      <div v-else-if="productList.length === 0" class="product-empty">
        <a-empty description="暂无已购产品">
          <a-button type="primary" @click="navigateTo('/market')">
            前往应用商店
          </a-button>
        </a-empty>
      </div>

      <div v-else class="product-grid">
        <div
          v-for="product in productList"
          :key="product.id"
          class="product-card"
        >
          <div class="product-card-header">
            <div class="product-icon" :class="product.typeClass">{{ product.icon }}</div>
            <a-tag
              :color="product.isActive ? 'green' : 'default'"
              class="product-status"
            >
              {{ product.isActive ? '生效中' : '已过期' }}
            </a-tag>
          </div>
          <div class="product-card-body">
            <div class="product-name">{{ product.name }}</div>
            <div class="product-desc">{{ product.desc }}</div>
            <div class="product-meta">
              <span v-if="product.tenantName" class="meta-item">
                <span class="meta-dot" /> {{ product.tenantName }}
              </span>
              <span v-if="product.domain" class="meta-item">
                <span class="meta-dot" /> {{ product.domain }}
              </span>
            </div>
          </div>
          <a-divider style="margin: 0" />
          <div class="product-card-footer">
            <div class="product-price">
              <span class="price-amount">¥{{ product.price }}</span>
              <span class="price-period">/ {{ product.period }}</span>
            </div>
            <a-space>
              <a-button
                v-if="product.adminUrl"
                size="small"
                type="primary"
                @click="goAdmin(product)"
              >
                进入后台
              </a-button>
              <a-button size="small" @click="openDetail(product)">详情</a-button>
            </a-space>
          </div>
        </div>
      </div>

      <!-- 分页 -->
      <div v-if="total > pageSize" class="mt-4 flex justify-end">
        <a-pagination
          :current="page"
          :page-size="pageSize"
          :total="total"
          size="small"
          @change="onPageChange"
        />
      </div>
    </a-card>

    <!-- 详情弹窗 -->
    <a-modal
      v-model:open="detailOpen"
      :title="selectedProduct?.name || '产品详情'"
      :width="640"
      :footer="null"
    >
      <template v-if="selectedProduct">
        <a-descriptions :column="1" size="small" bordered>
          <a-descriptions-item label="产品名称">{{ selectedProduct.name }}</a-descriptions-item>
          <a-descriptions-item label="产品类型">{{ selectedProduct.typeName }}</a-descriptions-item>
          <a-descriptions-item label="授权状态">
            <a-tag :color="selectedProduct.isActive ? 'green' : 'default'">
              {{ selectedProduct.isActive ? '生效中' : '已过期' }}
            </a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="购买金额">¥{{ selectedProduct.price }}</a-descriptions-item>
          <a-descriptions-item label="订阅周期">{{ selectedProduct.period }}</a-descriptions-item>
          <a-descriptions-item label="关联租户">{{ selectedProduct.tenantName || '-' }}</a-descriptions-item>
          <a-descriptions-item label="绑定域名">
            <a-typography-text v-if="selectedProduct.domain" :copyable="{ text: selectedProduct.domain }">
              {{ selectedProduct.domain }}
            </a-typography-text>
            <span v-else>-</span>
          </a-descriptions-item>
          <a-descriptions-item label="订单号">
            <a-typography-text v-if="selectedProduct.orderNo" :copyable="{ text: selectedProduct.orderNo }">
              {{ selectedProduct.orderNo }}
            </a-typography-text>
            <span v-else>-</span>
          </a-descriptions-item>
          <a-descriptions-item label="购买时间">{{ selectedProduct.createTime || '-' }}</a-descriptions-item>
          <a-descriptions-item label="到期时间">
            <span :class="{ 'text-red-500': !selectedProduct.isActive }">
              {{ selectedProduct.expirationTime || '-' }}
            </span>
          </a-descriptions-item>
        </a-descriptions>
        <div v-if="selectedProduct.adminUrl" class="mt-4 text-right">
          <a-button type="primary" @click="goAdmin(selectedProduct!)">进入管理后台</a-button>
        </div>
      </template>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { message } from 'ant-design-vue'
import { getUserInfo } from '@/api/layout'
import { pageShopOrder } from '@/api/shop/shopOrder'
import type { ShopOrder } from '@/api/shop/shopOrder/model'

definePageMeta({ layout: 'console' })

const loading = ref(false)
const error = ref('')
const list = ref<ShopOrder[]>([])
const page = ref(1)
const pageSize = ref(20)
const total = ref(0)
const keywords = ref('')
const statusFilter = ref('active')
const productType = ref<string | undefined>(undefined)

const currentUserId = ref<number | null>(null)

const statusOptions = [
  { label: '生效中', value: 'active' },
  { label: '已过期', value: 'expired' },
  { label: '全部', value: 'all' },
]

interface ProductItem {
  id: string
  name: string
  desc: string
  icon: string
  typeClass: string
  typeName: string
  type: string
  isActive: boolean
  price: string
  period: string
  tenantName: string
  domain: string
  adminUrl: string
  orderNo: string
  createTime: string
  expirationTime: string
  raw: ShopOrder
}

function safeJsonParse(value: string): unknown {
  try { return JSON.parse(value) }
  catch { return undefined }
}

function pickFirstRemark(order?: ShopOrder | null) {
  if (!order) return ''
  const record = order as unknown as Record<string, unknown>
  const keys = ['buyerRemarks', 'merchantRemarks', 'description']
  for (const key of keys) {
    const v = record[key]
    if (typeof v === 'string' && v.trim()) return v.trim()
  }
  return ''
}

function parseExtra(order?: ShopOrder | null): Record<string, unknown> | null {
  const raw = pickFirstRemark(order)
  if (!raw) return null
  const parsed = safeJsonParse(raw)
  if (!parsed || typeof parsed !== 'object') return null
  return parsed as Record<string, unknown>
}

const productCatalog: Record<string, { name: string; icon: string; typeClass: string; desc: string }> = {
  website: { name: '企业官网', icon: '🌐', typeClass: 'blue', desc: '响应式企业建站系统' },
  shop: { name: '电商系统', icon: '🛒', typeClass: 'green', desc: '多端电商解决方案' },
  mp: { name: '小程序/公众号', icon: '📱', typeClass: 'purple', desc: '微信生态应用' },
}

function toProductItem(order: ShopOrder): ProductItem {
  const extra = parseExtra(order)
  const code = typeof extra?.product === 'string' ? extra.product.trim() : ''
  const catalog = code && productCatalog[code] ? productCatalog[code] : { name: code || '其他产品', icon: '📦', typeClass: 'gray', desc: '' }
  const months = extra?.months
  const tenantName = typeof extra?.tenantName === 'string' ? extra.tenantName.trim() : ''
  const domain = typeof extra?.domain === 'string' ? extra.domain.trim() : ''
  const payPrice = order.payPrice || order.totalPrice || '0'

  // 判断是否过期
  const expirationTime = order.expirationTime || ''
  let isActive = true
  if (expirationTime) {
    isActive = new Date(expirationTime) > new Date()
  }
  if (Number(order.orderStatus) === 2 || Number(order.orderStatus) === 3 || Number(order.orderStatus) === 6) {
    isActive = false
  }

  return {
    id: `${order.orderId}-${code}`,
    name: catalog.name,
    desc: catalog.desc,
    icon: catalog.icon,
    typeClass: catalog.typeClass,
    typeName: catalog.name,
    type: code,
    isActive,
    price: typeof months === 'number' || typeof months === 'string' ? payPrice : payPrice,
    period: typeof months === 'number' || typeof months === 'string' ? `${months}个月` : '永久',
    tenantName,
    domain,
    adminUrl: isActive && tenantName ? `https://${tenantName}` : '',
    orderNo: order.orderNo || '',
    createTime: order.createTime || '',
    expirationTime,
    raw: order,
  }
}

const productList = computed(() => {
  const result: ProductItem[] = []
  const seen = new Set<string>()

  for (const order of list.value) {
    const product = toProductItem(order)

    // 状态筛选
    if (statusFilter.value === 'active' && !product.isActive) continue
    if (statusFilter.value === 'expired' && product.isActive) continue

    // 类型筛选
    if (productType.value && product.type !== productType.value) continue

    // 关键词筛选
    if (keywords.value?.trim()) {
      const kw = keywords.value.trim().toLowerCase()
      if (!product.name.toLowerCase().includes(kw) && !product.tenantName.toLowerCase().includes(kw)) continue
    }

    // 去重（按 product + tenantName）
    const dedupeKey = `${product.type}-${product.tenantName}`
    if (seen.has(dedupeKey)) {
      // 更新已有项为生效中的
      const existing = result.find(p => `${p.type}-${p.tenantName}` === dedupeKey)
      if (existing && product.isActive) {
        Object.assign(existing, product)
      }
      continue
    }
    seen.add(dedupeKey)
    result.push(product)
  }

  return result
})

const stats = computed(() => {
  const allProducts = list.value.map(toProductItem)
  const activeCount = allProducts.filter(p => p.isActive).length
  const expiredCount = allProducts.filter(p => !p.isActive).length
  const totalSpent = list.value.reduce((sum, o) => sum + Number(o.payPrice || o.totalPrice || 0), 0)

  return [
    { label: '总产品', value: list.value.length, color: 'blue' },
    { label: '生效中', value: activeCount, color: 'green' },
    { label: '已过期', value: expiredCount, color: 'orange' },
    { label: '累计消费', value: `¥${totalSpent.toFixed(0)}`, color: 'purple' },
  ]
})

const detailOpen = ref(false)
const selectedProduct = ref<ProductItem | null>(null)

function openDetail(product: ProductItem) {
  selectedProduct.value = product
  detailOpen.value = true
}

function goAdmin(product: ProductItem) {
  if (product.adminUrl) {
    window.open(product.adminUrl, '_blank')
  }
}

async function ensureUser() {
  if (currentUserId.value) return
  const user = await getUserInfo()
  currentUserId.value = user.userId ?? null
}

async function load() {
  loading.value = true
  error.value = ''
  try {
    await ensureUser()
    const userId = currentUserId.value
    if (!userId) {
      throw new Error('缺少用户信息')
    }

    const data = await pageShopOrder({
      page: page.value,
      limit: pageSize.value,
      userId,
      payStatus: 1, // 只查已支付
      keywords: keywords.value?.trim() || undefined,
    })

    list.value = data?.list || []
    total.value = data?.count || 0
  } catch (e: unknown) {
    console.error(e)
    list.value = []
    total.value = 0
    error.value = e instanceof Error ? e.message : '加载失败'
    message.error(error.value)
  } finally {
    loading.value = false
  }
}

function refresh() { load() }
function doSearch() { page.value = 1; load() }
function onPageChange(p: number) { page.value = p; load() }

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

<style scoped>
.card {
  border-radius: 12px;
}

/* 迷你统计 */
.mini-stat {
  padding: 14px;
  border-radius: 10px;
  border: 1px solid transparent;
  text-align: center;
}

.mini-stat.blue { background: #eff6ff; border-color: #dbeafe; }
.mini-stat.green { background: #f0fdf4; border-color: #bbf7d0; }
.mini-stat.orange { background: #fff7ed; border-color: #fed7aa; }
.mini-stat.purple { background: #f5f3ff; border-color: #e9d5ff; }

.mini-stat-value {
  font-size: 20px;
  font-weight: 700;
  color: rgba(0, 0, 0, 0.85);
}

.mini-stat-label {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
  margin-top: 2px;
}

/* 加载/空 */
.product-loading {
  display: flex;
  justify-content: center;
  padding: 60px 0;
}

.product-empty {
  padding: 60px 0;
}

/* 产品网格 */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 16px;
}

@media (max-width: 768px) {
  .product-grid {
    grid-template-columns: 1fr;
  }
}

/* 产品卡片 */
.product-card {
  border: 1px solid #f0f0f0;
  border-radius: 12px;
  overflow: hidden;
  transition: all 0.2s;
}

.product-card:hover {
  border-color: #d0d7ff;
  box-shadow: 0 4px 16px rgba(79, 70, 229, 0.08);
}

.product-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 16px 0;
}

.product-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
}

.product-icon.blue { background: #eff6ff; }
.product-icon.green { background: #f0fdf4; }
.product-icon.purple { background: #f5f3ff; }
.product-icon.gray { background: #f9fafb; }

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

.product-card-body {
  padding: 12px 16px;
}

.product-name {
  font-size: 15px;
  font-weight: 600;
  color: rgba(0, 0, 0, 0.88);
  margin-bottom: 4px;
}

.product-desc {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.4);
  margin-bottom: 8px;
}

.product-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.meta-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: rgba(0, 0, 0, 0.5);
}

.meta-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #d1d5db;
}

.product-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
}

.product-price {
  display: flex;
  align-items: baseline;
  gap: 2px;
}

.price-amount {
  font-size: 16px;
  font-weight: 700;
  color: rgba(0, 0, 0, 0.85);
}

.price-period {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.4);
}
</style>
