<template>
  <div class="all-apps-page">
    <!-- 页面头部 -->
    <div class="page-header">
      <div>
        <h2 class="page-title">🌐 全局应用管理</h2>
        <p class="page-desc">查看所有租户的应用，支持按租户筛选</p>
      </div>
      <a-space>
        <a-button @click="loadApps" :loading="loading">
          <template #icon><ReloadOutlined /></template>
          刷新
        </a-button>
      </a-space>
    </div>

    <!-- 统计卡片 -->
    <a-row :gutter="[16, 16]" class="mb-6">
      <a-col :xs="12" :md="6" v-for="stat in stats" :key="stat.key">
        <div
          class="stat-card"
          :class="[stat.color, { active: filterTenantId === stat.key }]"
          @click="handleStatFilter(stat.key)"
        >
          <div class="stat-icon">{{ stat.icon }}</div>
          <div class="stat-info">
            <div class="stat-value">{{ stat.value }}</div>
            <div class="stat-label">{{ stat.label }}</div>
          </div>
        </div>
      </a-col>
    </a-row>

    <!-- 筛选 + 列表 -->
    <div class="panel">
      <div class="panel-header">
        <span class="panel-title">📋 应用列表</span>
        <a-space wrap>
          <a-select
            v-model:value="filterTenantId"
            style="width: 180px"
            allow-clear
            placeholder="全部租户"
            :loading="loadingTenants"
            @change="handleSearch"
          >
            <a-select-option v-for="t in tenantList" :key="t.tenantId" :value="t.tenantId">
              {{ t.tenantName }}
            </a-select-option>
          </a-select>
          <a-select v-model:value="filterStatus" style="width: 130px" @change="handleSearch">
            <a-select-option value="">全部状态</a-select-option>
            <a-select-option :value="0">未开通</a-select-option>
            <a-select-option :value="1">运行中</a-select-option>
            <a-select-option :value="2">维护中</a-select-option>
            <a-select-option :value="3">已关闭</a-select-option>
          </a-select>
          <a-select v-model:value="filterType" style="width: 140px" allow-clear placeholder="全部类型" @change="handleSearch">
            <a-select-option v-for="(name, key) in APP_TYPE_NAME" :key="key" :value="Number(key)">
              {{ name }}
            </a-select-option>
          </a-select>
          <a-input-search
            v-model:value="searchKeyword"
            placeholder="搜索应用名称/标识/租户"
            style="width: 240px"
            @search="handleSearch"
          />
        </a-space>
      </div>

      <a-table
        :columns="columns"
        :data-source="apps"
        :loading="loading"
        :pagination="pagination"
        row-key="productId"
        @change="handleTableChange"
        size="middle"
        :scroll="{ x: 1400 }"
      >
        <template #bodyCell="{ column, record }">
          <!-- 应用信息 -->
          <template v-if="column.key === 'appInfo'">
            <div class="app-info-cell">
              <img v-if="record.icon" :src="record.icon" class="app-icon" />
              <div v-else class="app-icon-placeholder" :style="{ background: iconBgColor(record.productName) }">
                {{ (record.productName || 'A').charAt(0).toUpperCase() }}
              </div>
              <div class="app-info-text">
                <div class="app-name">{{ record.productName }}</div>
                <div class="app-code">{{ record.productCode }}</div>
              </div>
            </div>
          </template>

          <!-- 所属租户 -->
          <template v-if="column.key === 'tenantName'">
            <a-tag>{{ record.tenantId }}</a-tag>
          </template>

          <!-- 类型 -->
          <template v-if="column.key === 'type'">
            <a-tag color="blue">{{ APP_TYPE_NAME[record.appType ?? 10] || '未知' }}</a-tag>
            <a-tag v-if="record.official === 1" color="gold" style="margin-left:4px">官方</a-tag>
          </template>

          <!-- 状态 -->
          <template v-if="column.key === 'status'">
            <a-badge :status="statusBadge(record.status)" :text="statusText(record.status)" />
          </template>

          <!-- 发布状态 -->
          <template v-if="column.key === 'publishStatus'">
            <a-tag v-if="record.publishStatus" :color="pubStatusColor(record.publishStatus)">
              {{ pubStatusText(record.publishStatus) }}
            </a-tag>
            <span v-else class="text-gray-400">-</span>
          </template>

          <!-- 域名 -->
          <template v-if="column.key === 'domain'">
            <a v-if="record.domain" :href="'https://' + record.domain" target="_blank" class="domain-link">
              {{ record.domain }}
            </a>
            <span v-else class="text-gray-400">-</span>
          </template>

          <!-- 创建时间 -->
          <template v-if="column.key === 'createTime'">
            <span class="text-sm text-gray">{{ record.createTime?.substring(0, 10) || '-' }}</span>
          </template>

          <!-- 操作 -->
          <template v-if="column.key === 'action'">
            <a-space>
              <a-button type="link" size="small" @click="handleView(record)">详情</a-button>
              <a-dropdown :trigger="['click']">
                <a-button type="link" size="small">更多 <DownOutlined /></a-button>
                <template #overlay>
                  <a-menu @click="({ key }) => handleMoreAction(key as string, record)">
                    <a-menu-item key="toggle-status">
                      {{ record.status === 1 ? '🔒 暂停运行' : '▶️ 恢复运行' }}
                    </a-menu-item>
                    <a-menu-item key="toggle-official">
                      {{ record.official === 1 ? '取消官方' : '设为官方' }}
                    </a-menu-item>
                    <a-menu-item key="toggle-market">
                      {{ record.market === 1 ? '下架市场' : '上架市场' }}
                    </a-menu-item>
                    <a-menu-divider />
                    <a-menu-item key="delete" class="danger-item">🗑️ 删除应用</a-menu-item>
                  </a-menu>
                </template>
              </a-dropdown>
            </a-space>
          </template>
        </template>
      </a-table>
    </div>

    <!-- 详情弹窗 -->
    <a-modal
      v-model:open="showDetailModal"
      :title="`应用详情：${currentApp?.productName || ''}`"
      width="720px"
      :footer="null"
    >
      <template v-if="currentApp">
        <a-descriptions :column="2" bordered size="small">
          <a-descriptions-item label="应用名称">{{ currentApp.productName }}</a-descriptions-item>
          <a-descriptions-item label="应用标识">{{ currentApp.productCode }}</a-descriptions-item>
          <a-descriptions-item label="所属租户">
            <a-tag color="purple">{{ getTenantName(currentApp.tenantId) }}</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="开发者">{{ currentApp.developer || '-' }}</a-descriptions-item>
          <a-descriptions-item label="应用类型">
            <a-tag color="blue">{{ APP_TYPE_NAME[currentApp.appType ?? 10] || '未知' }}</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="运行状态">
            <a-badge :status="statusBadge(currentApp.status)" :text="statusText(currentApp.status)" />
          </a-descriptions-item>
          <a-descriptions-item label="发布状态">
            <a-tag v-if="currentApp.publishStatus" :color="pubStatusColor(currentApp.publishStatus)">
              {{ pubStatusText(currentApp.publishStatus) }}
            </a-tag>
            <span v-else>-</span>
          </a-descriptions-item>
          <a-descriptions-item label="绑定域名" :span="2">
            <a v-if="currentApp.domain" :href="'https://' + currentApp.domain" target="_blank">{{ currentApp.domain }}</a>
            <span v-else>-</span>
          </a-descriptions-item>
          <a-descriptions-item label="ICP备案">{{ currentApp.icpNo || '-' }}</a-descriptions-item>
          <a-descriptions-item label="安装次数">{{ currentApp.installs ?? '-' }}</a-descriptions-item>
          <a-descriptions-item label="评分">{{ currentApp.rating ? currentApp.rating + ' ⭐' : '-' }}</a-descriptions-item>
          <a-descriptions-item label="到期时间">{{ currentApp.expirationTime || '-' }}</a-descriptions-item>
          <a-descriptions-item label="创建时间" :span="2">{{ currentApp.createTime || '-' }}</a-descriptions-item>
          <a-descriptions-item v-if="currentApp.description" label="应用简介" :span="2">
            {{ currentApp.description }}
          </a-descriptions-item>
        </a-descriptions>
      </template>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ReloadOutlined, DownOutlined } from '@ant-design/icons-vue'
import { message, Modal } from 'ant-design-vue'
import { pageAppProduct, updateAppProduct, removeAppProduct } from '@/api/app/appProduct'
import type { AppProduct } from '@/api/app/appProduct/model'
import { APP_TYPE_NAME } from '@/api/app/appProduct/model'
import { listTenant } from '@/api/system/tenant/index'
import type { Tenant } from '@/api/system/tenant/model'

definePageMeta({ layout: 'admin' })
useHead({ title: '全局应用管理 - 平台管理' })

const loading = ref(false)
const apps = ref<AppProduct[]>([])
const filterStatus = ref<number | ''>('')
const filterType = ref<number | ''>('')
const filterTenantId = ref<number | ''>('')
const searchKeyword = ref('')

const pagination = reactive({
  current: 1,
  pageSize: 20,
  total: 0,
  showSizeChanger: true,
  showQuickJumper: true,
})

// 租户列表
const tenantList = ref<Tenant[]>([])
const loadingTenants = ref(false)

async function loadTenantList() {
  loadingTenants.value = true
  try {
    const res = await listTenant()
    tenantList.value = res || []
  } catch {
    // 静默失败
  } finally {
    loadingTenants.value = false
  }
}

function getTenantName(tenantId?: number) {
  if (!tenantId) return '-'
  const tenant = tenantList.value.find(t => t.tenantId === tenantId)
  return tenant?.tenantName || `租户${tenantId}`
}

// 统计数据
const stats = computed(() => {
  const total = apps.value.length
  const running = apps.value.filter(a => a.status === 1).length
  const maintenance = apps.value.filter(a => a.status === 2).length
  const closed = apps.value.filter(a => a.status === 3).length
  return [
    { key: '', icon: '📦', label: '全部应用', value: pagination.total, color: 'blue' },
    { key: 1, icon: '✅', label: '运行中', value: running, color: 'green' },
    { key: 2, icon: '🔧', label: '维护中', value: maintenance, color: 'orange' },
    { key: 3, icon: '⛔', label: '已关闭', value: closed, color: 'red' },
  ]
})

const columns = [
  { title: '应用信息', key: 'appInfo', width: 250, fixed: 'left' },
  { title: '所属租户', key: 'tenantName', width: 150 },
  { title: '类型', key: 'type', width: 140 },
  { title: '运行状态', key: 'status', width: 110 },
  { title: '发布状态', key: 'publishStatus', width: 110 },
  { title: '绑定域名', key: 'domain', width: 180 },
  { title: '创建时间', key: 'createTime', width: 110 },
  { title: '操作', key: 'action', width: 160, fixed: 'right' },
]

const showDetailModal = ref(false)
const currentApp = ref<AppProduct | null>(null)

async function loadApps() {
  loading.value = true
  try {
    const res = await pageAppProduct({
      current: pagination.current,
      size: pagination.pageSize,
      status: filterStatus.value !== '' ? (filterStatus.value as number) : undefined,
      appType: filterType.value !== '' ? (filterType.value as number) : undefined,
      tenantId: filterTenantId.value !== '' ? (filterTenantId.value as number) : undefined,
      keywords: searchKeyword.value || undefined,
    })
    apps.value = res?.list || []
    pagination.total = res?.count || 0
  } catch {
    message.error('加载应用列表失败')
  } finally {
    loading.value = false
  }
}

function handleStatFilter(key: number | '') {
  filterTenantId.value = key
  pagination.current = 1
  loadApps()
}

function handleSearch() {
  pagination.current = 1
  loadApps()
}

function handleTableChange(pag: any) {
  pagination.current = pag.current
  pagination.pageSize = pag.pageSize
  loadApps()
}

function handleView(record: AppProduct) {
  currentApp.value = record
  showDetailModal.value = true
}

async function handleMoreAction(key: string, record: AppProduct) {
  if (key === 'toggle-status') {
    const newStatus = record.status === 1 ? 3 : 1
    try {
      await updateAppProduct({ productId: record.productId, status: newStatus })
      message.success('状态已更新')
      loadApps()
    } catch (e: any) { message.error(e?.message || '操作失败') }
  }
  if (key === 'toggle-official') {
    try {
      await updateAppProduct({ productId: record.productId, official: record.official ? 0 : 1 })
      message.success(record.official ? '已取消官方标记' : '已设为官方应用')
      loadApps()
    } catch (e: any) { message.error(e?.message || '操作失败') }
  }
  if (key === 'toggle-market') {
    try {
      await updateAppProduct({ productId: record.productId, market: record.market ? 0 : 1 })
      message.success(record.market ? '已从市场下架' : '已上架至应用市场')
      loadApps()
    } catch (e: any) { message.error(e?.message || '操作失败') }
  }
  if (key === 'delete') {
    Modal.confirm({
      title: '确认删除',
      content: `确定要删除应用「${record.productName}」吗？此操作不可恢复！`,
      okType: 'danger',
      onOk: async () => {
        try {
          await removeAppProduct(record.productId)
          message.success('应用已删除')
          loadApps()
        } catch (e: any) { message.error(e?.message || '删除失败') }
      },
    })
  }
}

function statusText(status?: number) {
  const map: Record<number, string> = { 0: '未开通', 1: '运行中', 2: '维护中', 3: '已关闭', 4: '已欠费', 5: '违规停止' }
  return map[status ?? -1] || '未知'
}

function statusBadge(status?: number): 'success' | 'warning' | 'error' | 'default' {
  if (status === 1) return 'success'
  if (status === 2) return 'warning'
  if (status === 3 || status === 5) return 'error'
  return 'default'
}

function pubStatusColor(status?: string) {
  const map: Record<string, string> = {
    developing: 'default',
    pending_review: 'orange',
    published: 'success',
    rejected: 'error',
    deprecated: 'default',
  }
  return map[status || ''] || 'default'
}

function pubStatusText(status?: string) {
  const map: Record<string, string> = {
    developing: '开发中',
    pending_review: '待审核',
    published: '已上架',
    rejected: '已拒绝',
    deprecated: '已下架',
  }
  return map[status || ''] || '-'
}

const PALETTE = ['#4e6ef2', '#f4a261', '#e76f51', '#2a9d8f', '#e9c46a', '#457b9d']
function iconBgColor(name?: string) {
  if (!name) return PALETTE[0]
  let h = 0
  for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) & 0xffffffff
  return PALETTE[Math.abs(h) % PALETTE.length]
}

onMounted(() => {
  loadTenantList()
  loadApps()
})
</script>

<style scoped>
.all-apps-page { min-height: 100%; }

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.page-title {
  font-size: 18px;
  font-weight: 700;
  color: #1f2937;
  margin: 0;
}

.page-desc {
  font-size: 13px;
  color: #9ca3af;
  margin: 2px 0 0;
}

.stat-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  border-radius: 12px;
  border: 2px solid transparent;
  cursor: pointer;
  transition: all 0.2s;
}

.stat-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.stat-card.active { box-shadow: 0 4px 12px rgba(0,0,0,0.12); }
.stat-card.blue { background: #eff6ff; border-color: #dbeafe; }
.stat-card.orange { background: #fff7ed; border-color: #fed7aa; }
.stat-card.green { background: #f0fdf4; border-color: #bbf7d0; }
.stat-card.red { background: #fff1f2; border-color: #fecdd3; }
.stat-card.active.blue { border-color: #3b82f6; }
.stat-card.active.orange { border-color: #f97316; }
.stat-card.active.green { border-color: #22c55e; }
.stat-card.active.red { border-color: #ef4444; }
.stat-icon { font-size: 28px; flex-shrink: 0; }
.stat-value { font-size: 22px; font-weight: 700; color: rgba(0,0,0,0.85); line-height: 1.2; }
.stat-label { font-size: 12px; color: rgba(0,0,0,0.45); margin-top: 2px; }

.panel {
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 12px;
  overflow: hidden;
}

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid #f5f5f5;
  flex-wrap: wrap;
  gap: 10px;
}

.panel-title { font-size: 14px; font-weight: 600; color: rgba(0,0,0,0.85); }

.app-info-cell { display: flex; align-items: center; gap: 12px; }

.app-icon {
  width: 44px; height: 44px;
  border-radius: 8px; object-fit: cover; flex-shrink: 0;
}

.app-icon-placeholder {
  width: 44px; height: 44px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 600; color: #fff; flex-shrink: 0;
}

.app-info-text { flex: 1; min-width: 0; }
.app-name { font-size: 14px; font-weight: 500; color: rgba(0,0,0,0.85); }
.app-code { font-size: 12px; color: rgba(0,0,0,0.45); }

.domain-link { font-size: 13px; color: #4f46e5; text-decoration: none; }
.domain-link:hover { text-decoration: underline; }

.text-sm { font-size: 12px; }
.text-gray { color: rgba(0,0,0,0.45); }
.text-gray-400 { color: #9ca3af; }

.danger-item { color: #ff4d4f !important; }

.mb-6 { margin-bottom: 24px; }
</style>
