<script setup lang="ts">
import type { Tenant } from '~/types/tenant'

// Platform-wide billing. Real data from /api/billing/* → platform-api
// (operator-guarded). Invoices sync from Stripe when live; empty in dev, where
// the summary still reflects real outstanding/paid across stored invoices.
interface BillingSummary {
  invoicedMinor: number
  paidMinor: number
  outstandingMinor: number
  openInvoices: number
  pastDueInvoices: number
  stripeLive: boolean
}
interface Invoice {
  _id: string
  number?: string
  tenantId: string
  currency: 'DKK' | 'EUR' | 'USD'
  amountDue: number
  amountPaid: number
  status: string
  periodEnd?: string
  createdAt?: string
  hostedInvoiceUrl?: string
  pdfUrl?: string
}

const { data: summary, pending, refresh: rS } = await useFetch<BillingSummary>('/api/billing/summary', {
  default: () => ({ invoicedMinor: 0, paidMinor: 0, outstandingMinor: 0, openInvoices: 0, pastDueInvoices: 0, stripeLive: false }),
})
const { data: invoices, refresh: rI } = await useFetch<Invoice[]>('/api/billing/invoices', { default: () => [] })
const { data: tenants } = await useFetch<Tenant[]>('/api/tenants', { default: () => [] })

const tenantName = (id: string) => (tenants.value ?? []).find((t) => t._id === id)?.name ?? id
const money = (m: number) => Math.round(m / 100).toLocaleString('da-DK')
function invoiceTone(s: string): 'ok' | 'warn' | 'bad' | 'neutral' {
  if (s === 'paid') return 'ok'
  if (s === 'past_due' || s === 'uncollectible') return 'bad'
  if (s === 'open') return 'warn'
  return 'neutral'
}
function fmtDate(iso?: string) {
  return iso ? new Date(iso).toLocaleDateString('da-DK', { day: '2-digit', month: 'short' }) : '—'
}
async function refresh() {
  await Promise.all([rS(), rI()])
}
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Commercial"
      title="Platform billing"
      :subtitle="`${money(summary?.outstandingMinor ?? 0)} DKK outstanding · ${summary?.openInvoices ?? 0} open`"
    >
      <template #actions>
        <UiButton variant="secondary" :disabled="pending" @click="refresh">
          <template #leading><UiIcon name="refresh" :size="13" /></template>
          Refresh
        </UiButton>
      </template>
    </PageHeader>

    <div class="stage">
      <div v-if="!summary?.stripeLive" class="derived-note">
        <UiIcon name="card" :size="13" />
        <Mono dim>Stripe not connected · invoices populate from webhooks once billing is live. Outstanding/paid reflect stored invoices.</Mono>
      </div>

      <div class="vitals">
        <Card><Stat label="Invoiced" :value="`${money(summary?.invoicedMinor ?? 0)} DKK`" /></Card>
        <Card><Stat label="Paid" :value="`${money(summary?.paidMinor ?? 0)} DKK`" /></Card>
        <Card><Stat label="Outstanding" :value="`${money(summary?.outstandingMinor ?? 0)} DKK`" :delta-tone="(summary?.outstandingMinor ?? 0) > 0 ? 'down' : undefined" /></Card>
        <Card><Stat label="Past due" :value="summary?.pastDueInvoices ?? 0" :delta-tone="(summary?.pastDueInvoices ?? 0) > 0 ? 'down' : undefined" /></Card>
      </div>

      <Card :pad="0">
        <div class="head"><div><Eyebrow>Invoices</Eyebrow><div class="cap">Platform-wide</div></div></div>
        <table>
          <thead>
            <tr><th>Invoice</th><th>Tenant</th><th>Date</th><th class="num">Amount</th><th>Status</th></tr>
          </thead>
          <tbody>
            <tr v-for="inv in invoices" :key="inv._id">
              <td><Mono>{{ inv.number || inv._id.slice(-8) }}</Mono></td>
              <td class="name">{{ tenantName(inv.tenantId) }}</td>
              <td><Mono dim>{{ fmtDate(inv.periodEnd || inv.createdAt) }}</Mono></td>
              <td class="num"><Mono>{{ money(inv.amountDue) }} {{ inv.currency }}</Mono></td>
              <td><Badge :tone="invoiceTone(inv.status)" dot>{{ inv.status.replace('_', '-') }}</Badge></td>
            </tr>
            <tr v-if="!invoices.length"><td colspan="5" class="empty"><Mono dim>// no invoices yet</Mono></td></tr>
          </tbody>
        </table>
      </Card>
    </div>
  </div>
</template>

<style scoped>
.stage { padding: 24px 40px 64px 40px; display: flex; flex-direction: column; gap: 16px; }
.derived-note { display: flex; align-items: center; gap: 8px; }
.derived-note :deep(svg) { color: var(--text-mute); }
.vitals {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.vitals > * { background: var(--surface); padding: 20px; }
.head { padding: 16px 20px; border-bottom: 1px solid var(--border); }
.cap { font-family: var(--font-display); font-weight: 600; font-size: 17px; margin-top: 4px; }
table { width: 100%; border-collapse: collapse; }
th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
  padding: 12px 20px;
  font-weight: 500;
  border-bottom: 1px solid var(--border);
}
th.num, td.num { text-align: right; }
td { padding: 10px 20px; font-size: 12px; border-top: 1px solid var(--border); }
td.name { font-weight: 500; }
.empty { text-align: center; padding: 32px; }
</style>
