<!-- SPEC: PJ2026-010405 云端控制台. -->
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { billingAPI, usageAPI } from "@/api";
import UserBillingWorkspace from "@/components/billing/UserBillingWorkspace.vue";
import AsyncBoundary from "@/components/common/AsyncBoundary.vue";
import PageCommandBar from "@/components/layout/PageCommandBar.vue";
import type { PaymentSummaryResponse, RedeemResponse, SubscriptionSummaryResponse, UsageSummary } from "@/types";

const loading = ref(true);
const loaded = ref(false);
const error = ref<string | null>(null);
const pending = ref(false);
const redeemError = ref<string | null>(null);
const redeemResult = ref<RedeemResponse | null>(null);
const summary = ref<UsageSummary | null>(null);
const subscription = ref<SubscriptionSummaryResponse | null>(null);
const payment = ref<PaymentSummaryResponse | null>(null);
const redeemOpen = ref(false);
const hasContent = computed(() => Boolean(summary.value || subscription.value || payment.value));
const asyncState = computed(() => loading.value ? hasContent.value ? "refreshing" : "initial-loading" : error.value ? hasContent.value ? "partial" : "error" : loaded.value ? "ready" : "empty");
onMounted(refreshAll);

async function refreshAll(): Promise<void> {
  loading.value = true;
  const [usage, subs, pay] = await Promise.all([usageAPI.summary(), billingAPI.subscriptionSummary(), billingAPI.paymentSummary()]);
  if (usage.ok) summary.value = usage.data;
  if (subs.ok) subscription.value = subs.data;
  if (pay.ok) payment.value = pay.data;
  const failures = [usage, subs, pay].filter((response) => !response.ok);
  error.value = failures.length ? failures.map((response) => response.error ?? `HTTP ${response.status}`).join("；") : null;
  loading.value = false;
  loaded.value = true;
}

async function redeem(payload: { code: string; idempotencyKey?: string }): Promise<void> {
  pending.value = true;
  redeemError.value = null;
  redeemResult.value = null;
  const response = await billingAPI.redeem(payload);
  pending.value = false;
  if (!response.ok) { redeemError.value = response.error ?? `HTTP ${response.status}`; return; }
  redeemResult.value = response.data;
  await refreshAll();
}
</script>

<template>
  <section class="route-stack billing-page">
    <PageCommandBar eyebrow="Billing" title="充值与订阅" description="兑换码、订阅计划和支付状态均由 PK01 user-billing authority 返回。" />
    <AsyncBoundary :state="asyncState" :has-content="hasContent" label="加载余额、订阅和支付状态" empty-title="暂无账务信息" empty-description="账务接口未返回当前用户数据。" error-title="账务接口不可用" :error="error || '请求未完成'" @retry="refreshAll">
      <UserBillingWorkspace v-model:redeem-open="redeemOpen" :summary="summary" :subscription="subscription" :payment="payment" :pending="pending" :redeem-error="redeemError" :redeem-result="redeemResult" @redeem="redeem" />
    </AsyncBoundary>
  </section>
</template>
