<script setup lang="ts">
// Partner billing. Real data: aggregate billing across the portfolio (derived
// from active subscriptions + marginPct), customer invoices + payouts (synced
// from Stripe when live; empty in dev). Four tabs: Overview / Customer invoices
// / Margin & revenue / Payouts.
const toast = useToast()
const billingLive = useFeatureFlag('new_billing_engine')

const tab = ref<'overview' | 'invoices' | 'margin' | 'payouts'>('overview')

interface BillingSummary {
  marginPct: number
  mrr: Array<{ currency: 'DKK' | 'EUR' | 'USD'; monthlyMinor: number; partnerCutMinor: number; netMinor: number }>
  customers: number
  openInvoices: number
  openAmountMinor: number
  stripeLive: boolean
}
interface BillingInvoice {
  _id: string
  number?: string
  tenantId: string
  currency: 'DKK' | 'EUR' | 'USD'
  amountDue: number
  amountPaid: number
  status: string
  periodEnd?: string
  createdAt?: string
  hostedInvoiceUrl?: string
  pdfUrl?: string
}
interface BillingPayout {
  _id: string
  periodMonth: string
  currency: 'DKK' | 'EUR' | 'USD'
  payoutMinor: number
  status: 'pending' | 'paid'
  paidAt?: string
}

const { data: summary } = useFetch<BillingSummary>('/api/partner/billing/summary', {
  key: 'partner-billing-summary',
  default: () => ({ marginPct: 0, mrr: [], customers: 0, openInvoices: 0, openAmountMinor: 0, stripeLive: false }),
})
const { data: invoices } = useFetch<BillingInvoice[]>('/api/partner/billing/invoices', {
  key: 'partner-billing-invoices',
  default: () => [],
})
const { data: payouts } = useFetch<BillingPayout[]>('/api/partner/billing/payouts', {
  key: 'partner-billing-payouts',
  default: () => [],
})
const { tenants } = usePartnerTenants()
const { mrrByTenant } = usePartnerMrr()

const tabs = computed(() => [
  { value: 'overview', label: 'Overview' },
  { value: 'invoices', label: 'Customer invoices', count: invoices.value?.length ?? 0 },
  { value: 'margin', label: 'Margin & revenue' },
  { value: 'payouts', label: 'Payouts', count: payouts.value?.length ?? 0 },
])

const marginPct = computed(() => summary.value?.marginPct ?? 0)
const sumMinor = (sel: (r: BillingSummary['mrr'][number]) => number) =>
  Math.round((summary.value?.mrr ?? []).reduce((s, r) => s + sel(r), 0) / 100)
const mrrMajor = computed(() => sumMinor((r) => r.monthlyMinor))
const cutMajor = computed(() => sumMinor((r) => r.partnerCutMinor))
const netMajor = computed(() => sumMinor((r) => r.netMinor))
const openArMajor = computed(() => Math.round((summary.value?.openAmountMinor ?? 0) / 100))
const dkk = (n: number) => n.toLocaleString('da-DK')

const PLAN_LABEL: Record<'mvp' | 'pro' | 'enterprise', string> = { mvp: 'Starter', pro: 'Business', enterprise: 'Enterprise' }
const tenantName = (id: string) => (tenants.value ?? []).find((t) => t._id === id)?.name ?? id

// Per-customer revenue breakdown (overview) from real tenants + MRR.
const breakdown = computed(() =>
  (tenants.value ?? [])
    .filter((t) => t.status !== 'deleted')
    .map((t) => {
      const sub = mrrByTenant.value.get(t._id)
      const mrr = sub ? Math.round(sub.monthlyMinor / 100) : 0
      return {
        id: t._id,
        name: t.name,
        domain: t.domains?.[0] ?? `${t.slug}.dezky.com`,
        brandColor: t.brandColor || '#3F6BFF',
        planLabel: PLAN_LABEL[t.plan ?? 'pro'],
        seats: t.userCount ?? 0,
        mrrDkk: mrr,
        currency: sub?.currency ?? 'DKK',
        cut: Math.round((mrr * marginPct.value) / 100),
        status: t.status,
      }
    }),
)

function tStatusBadge(s: string): { tone: 'ok' | 'warn' | 'bad' | 'neutral'; label: string } {
  if (s === 'active') return { tone: 'ok', label: 'active' }
  if (s === 'pending') return { tone: 'warn', label: 'pending' }
  if (s === 'suspended') return { tone: 'bad', label: 'suspended' }
  return { tone: 'neutral', label: s }
}
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', year: 'numeric' }) : '—'
}

// Decorative trailing-twelve sparkline (no historical MRR store yet).
const revenueSeries = Array.from({ length: 52 }, (_, i) => 8000 + i * 180 + Math.sin(i / 3) * 600)
</script>

<template>
  <div>
    <PageHeader
      eyebrow="Commercial"
      title="Partner billing"
      subtitle="Aggregate billing across your customer portfolio, margins, and payouts from Dezky."
    >
      <template #actions>
        <UiButton variant="secondary" @click="toast.ok('Exporting', 'PDF compiled')">
          <template #leading><UiIcon name="download" :size="14" /></template>
          Export
        </UiButton>
      </template>
    </PageHeader>

    <div class="tabs-wrap">
      <Tabs v-model="tab" :items="tabs" />
    </div>

    <div v-if="!summary?.stripeLive" class="derived-note">
      <UiIcon name="shield" :size="13" />
      <Mono dim>Figures derived from active subscriptions · Stripe not connected{{ billingLive ? ' · billing engine flag on' : '' }}</Mono>
    </div>

    <!-- OVERVIEW -->
    <div v-if="tab === 'overview'" class="content">
      <div class="stat-strip">
        <Card><Stat label="MRR · portfolio" :value="`${dkk(mrrMajor)} DKK`" hint="across all customers" /></Card>
        <Card><Stat :label="`Partner cut · ${marginPct}%`" :value="`${dkk(cutMajor)} DKK`" delta-tone="up" /></Card>
        <Card><Stat label="Net to Dezky" :value="`${dkk(netMajor)} DKK`" hint="monthly" /></Card>
        <Card><Stat label="Open A/R" :value="`${dkk(openArMajor)} DKK`" :hint="`${summary?.openInvoices ?? 0} open invoice(s)`" :delta-tone="openArMajor > 0 ? 'down' : undefined" /></Card>
      </div>

      <Card :pad="0">
        <div class="card-head">
          <div>
            <Eyebrow>Per customer · this month</Eyebrow>
            <div class="card-title">Revenue breakdown</div>
          </div>
        </div>
        <table class="dtable">
          <thead>
            <tr>
              <th>Customer</th>
              <th>Plan</th>
              <th>Seats</th>
              <th class="num">MRR</th>
              <th class="num">Partner cut ({{ marginPct }}%)</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="c in breakdown" :key="c.id">
              <td>
                <div class="cust-cell">
                  <div class="cust-swatch" :style="{ background: c.brandColor }" />
                  <div>
                    <div class="cust-name">{{ c.name }}</div>
                    <Mono dim>{{ c.domain }}</Mono>
                  </div>
                </div>
              </td>
              <td><Badge tone="neutral">{{ c.planLabel }}</Badge></td>
              <td><Mono>{{ c.seats }}</Mono></td>
              <td class="num"><span class="mrr">{{ c.mrrDkk > 0 ? `${dkk(c.mrrDkk)} ${c.currency}` : '—' }}</span></td>
              <td class="num"><span class="cut">{{ c.cut > 0 ? `${dkk(c.cut)} ${c.currency}` : '—' }}</span></td>
              <td><Badge :tone="tStatusBadge(c.status).tone" dot>{{ tStatusBadge(c.status).label }}</Badge></td>
            </tr>
            <tr v-if="!breakdown.length"><td colspan="6" class="empty">No customers yet.</td></tr>
          </tbody>
        </table>
      </Card>
    </div>

    <!-- CUSTOMER INVOICES -->
    <div v-else-if="tab === 'invoices'" class="content">
      <Card :pad="0">
        <table class="dtable">
          <thead>
            <tr>
              <th>Invoice</th>
              <th>Customer</th>
              <th>Date</th>
              <th class="num">Amount</th>
              <th>Status</th>
              <th class="action-col" />
            </tr>
          </thead>
          <tbody>
            <tr v-for="inv in invoices" :key="inv._id">
              <td><Mono>{{ inv.number || inv._id.slice(-8) }}</Mono></td>
              <td><span class="cust-name">{{ tenantName(inv.tenantId) }}</span></td>
              <td><span class="text-13">{{ fmtDate(inv.periodEnd || inv.createdAt) }}</span></td>
              <td class="num"><Mono>{{ dkk(Math.round(inv.amountDue / 100)) }} {{ inv.currency }}</Mono></td>
              <td><Badge :tone="invoiceTone(inv.status)" dot>{{ inv.status.replace('_', '-') }}</Badge></td>
              <td class="action-col">
                <a v-if="inv.pdfUrl || inv.hostedInvoiceUrl" :href="inv.pdfUrl || inv.hostedInvoiceUrl" target="_blank" rel="noopener">
                  <UiButton size="sm" variant="ghost"><template #leading><UiIcon name="download" :size="13" /></template>PDF</UiButton>
                </a>
                <Mono v-else dim>—</Mono>
              </td>
            </tr>
            <tr v-if="!invoices.length">
              <td colspan="6" class="empty">No invoices yet{{ summary?.stripeLive ? '' : ' — invoices appear once Stripe billing is connected' }}.</td>
            </tr>
          </tbody>
        </table>
      </Card>
    </div>

    <!-- MARGIN & REVENUE -->
    <div v-else-if="tab === 'margin'" class="content">
      <div class="grid-2">
        <Card>
          <Eyebrow>Margin</Eyebrow>
          <div class="card-title">Your reseller margin</div>
          <p class="sub">Per your agreement with Dezky · {{ marginPct }}% gross on customer revenue.</p>
          <dl class="def">
            <div><dt>Gross margin</dt><dd>{{ marginPct }}% on all plans</dd></div>
            <div><dt>Monthly partner cut</dt><dd>{{ dkk(cutMajor) }} DKK</dd></div>
            <div><dt>Net to Dezky</dt><dd>{{ dkk(netMajor) }} DKK / mo</dd></div>
            <div><dt>Customers</dt><dd>{{ summary?.customers ?? 0 }}</dd></div>
          </dl>
        </Card>

        <Card>
          <Eyebrow>Revenue · annualized</Eyebrow>
          <div class="card-title">Run-rate</div>
          <div class="ttm-chart">
            <PartnerSparkline :values="revenueSeries" :width="420" :height="120" stroke="var(--text)" fill="var(--row-hover)" />
          </div>
          <div class="ttm-foot">
            <Mono dim>trend · illustrative</Mono>
            <Mono dim>{{ dkk(mrrMajor) }} DKK / mo now</Mono>
          </div>
          <div class="ttm-total">
            <Stat label="Annualized partner cut" :value="`${dkk(cutMajor * 12)} DKK`" hint="current run-rate × 12" />
          </div>
        </Card>
      </div>
    </div>

    <!-- PAYOUTS -->
    <div v-else-if="tab === 'payouts'" class="content">
      <Card :pad="0">
        <table class="dtable">
          <thead>
            <tr>
              <th>Period</th>
              <th class="num">Amount</th>
              <th>Paid on</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="p in payouts" :key="p._id">
              <td><span class="cust-name">{{ p.periodMonth }}</span></td>
              <td class="num"><Mono>{{ dkk(Math.round(p.payoutMinor / 100)) }} {{ p.currency }}</Mono></td>
              <td><Mono>{{ fmtDate(p.paidAt) }}</Mono></td>
              <td><Badge :tone="p.status === 'paid' ? 'ok' : 'warn'" dot>{{ p.status }}</Badge></td>
            </tr>
            <tr v-if="!payouts.length">
              <td colspan="4" class="empty">No payouts recorded yet.</td>
            </tr>
          </tbody>
        </table>
      </Card>
    </div>
  </div>
</template>

<style scoped>
.tabs-wrap { padding: 0 40px; margin-top: 16px; }
.derived-note { padding: 8px 40px 0; display: flex; align-items: center; gap: 8px; }
.derived-note :deep(svg) { color: var(--text-mute); }

.content { padding: 24px 40px 64px; display: flex; flex-direction: column; gap: 16px; }

.stat-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

.card-head { padding: 20px 24px; border-bottom: 1px solid var(--border); }
.card-title { font-family: var(--font-display); font-weight: 600; font-size: 18px; margin-top: 4px; }
.sub { font-size: 13px; color: var(--text-mute); margin: 6px 0 0; line-height: 1.5; }

.dtable { width: 100%; border-collapse: collapse; }
.dtable th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 500;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.dtable th.num, .dtable td.num { text-align: right; }
.dtable th.action-col, .dtable td.action-col { width: 80px; text-align: right; }
.dtable td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  vertical-align: middle;
}
.dtable tbody tr:hover { background: var(--row-hover); }
.dtable .empty { text-align: center; color: var(--text-mute); padding: 40px 0; }

.cust-cell { display: flex; align-items: center; gap: 12px; }
.cust-swatch { width: 24px; height: 24px; border-radius: 4px; flex-shrink: 0; }
.cust-name { font-size: 13px; font-weight: 500; }
.text-13 { font-size: 13px; }
.mrr { font-family: var(--font-mono); font-size: 12px; font-weight: 500; }
.cut { font-family: var(--font-mono); font-size: 12px; color: var(--ok); }

.def { display: flex; flex-direction: column; gap: 10px; margin: 14px 0 0; padding: 0; }
.def div { display: grid; grid-template-columns: 160px 1fr; gap: 12px; font-size: 13px; }
.def dt { color: var(--text-mute); font-family: var(--font-mono); font-size: 11px; }
.def dd { margin: 0; }

.ttm-chart { margin-top: 14px; }
.ttm-chart :deep(svg) { width: 100%; height: 120px; }
.ttm-foot { display: flex; justify-content: space-between; margin-top: 16px; }
.ttm-total { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--border); }
</style>
