(function () {
  'use strict';

/**
 * BillingInfo.jsx — Real billing data from Stripe (Wiring Sprint 2: B2/B3/B4)
 * Repo: wpsitebeam-app / design/BillingInfo.jsx
 * Version: v1.0.0 — 2026-05-26
 *
 * Replaces placeholder billing UI in Pages1.jsx Billing section.
 * Consumes:
 *   GET /billing/subscription  → current plan + status
 *   GET /billing/payment-methods → saved cards
 *   GET /billing/invoices      → last 12 invoices
 *
 * Integration: In Pages1.jsx Billing tab, replace the static mockup section
 * with: <window.BillingInfo />
 *
 * WCAG 2.1 AA — keyboard nav, aria-live for loading states, semantic HTML.
 */

  const VERSION = '1.0.0';
  console.log('[BillingInfo] v' + VERSION + ' loaded');

  /* ── Helpers ─────────────────────────────────────────────── */
  function apiBase() {
    return (window.WPSBD && window.WPSBD.apiBase) || 'https://api.wpsitebeam.io';
  }
  function getToken() {
    return window.WPSBD && window.WPSBD.getToken ? window.WPSBD.getToken() : '';
  }
  async function apiFetch(path) {
    const r = await fetch(apiBase() + path, {
      headers: { Authorization: 'Bearer ' + getToken() },
    });
    if (!r.ok) throw new Error('HTTP ' + r.status);
    return r.json();
  }

  function formatCents(cents, currency) {
    return new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: (currency || 'usd').toUpperCase(),
      minimumFractionDigits: 2,
    }).format((cents || 0) / 100);
  }

  function formatDate(unixTs) {
    if (!unixTs) return '—';
    return new Date(unixTs * 1000).toLocaleDateString('en-US', {
      year: 'numeric', month: 'short', day: 'numeric',
    });
  }

  function cardIcon(brand) {
    const icons = {
      visa: '💳', mastercard: '💳', amex: '💳',
      discover: '💳', jcb: '💳', unionpay: '💳',
    };
    return icons[brand] || '💳';
  }

  function brandLabel(brand) {
    if (!brand) return 'Card';
    return brand.charAt(0).toUpperCase() + brand.slice(1);
  }

  function statusPill(status) {
    const map = {
      active:        { label: 'Active',      bg: 'rgba(16,185,129,.15)', color: 'var(--green,#10b981)' },
      trialing:      { label: 'Trial',       bg: 'rgba(6,182,212,.15)',  color: 'var(--cyan,#06b6d4)'  },
      past_due:      { label: 'Past due',    bg: 'rgba(245,158,11,.15)', color: 'var(--warn,#f59e0b)'  },
      canceled:      { label: 'Canceled',    bg: 'rgba(239,68,68,.15)',  color: 'var(--red,#ef4444)'   },
      incomplete:    { label: 'Incomplete',  bg: 'rgba(239,68,68,.15)',  color: 'var(--red,#ef4444)'   },
      none:          { label: 'No plan',     bg: 'rgba(0,0,0,.08)',      color: 'var(--dim)'            },
      paid:          { label: 'Paid',        bg: 'rgba(16,185,129,.15)', color: 'var(--green,#10b981)' },
      open:          { label: 'Open',        bg: 'rgba(245,158,11,.15)', color: 'var(--warn,#f59e0b)'  },
      void:          { label: 'Void',        bg: 'rgba(0,0,0,.08)',      color: 'var(--dim)'            },
      uncollectible: { label: 'Overdue',     bg: 'rgba(239,68,68,.15)',  color: 'var(--red,#ef4444)'   },
    };
    const s = map[status] || { label: status, bg: 'rgba(0,0,0,.08)', color: 'var(--dim)' };
    return React.createElement('span', {
      style: {
        display: 'inline-block',
        padding: '2px 8px',
        borderRadius: '12px',
        fontSize: '11px',
        fontWeight: 600,
        background: s.bg,
        color: s.color,
      },
    }, s.label);
  }

  /* ── CSS ─────────────────────────────────────────────────── */
  const CSS = `
.bi-root { display: flex; flex-direction: column; gap: 20px; max-width: 720px; }
.bi-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}
.bi-card-header {
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.bi-card-title { font-size: 14px; font-weight: 600; color: var(--text); }
.bi-card-body { padding: 16px 18px; }
.bi-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid rgba(0,0,0,.05);
  font-size: 13px;
  gap: 12px;
}
.bi-row:last-child { border-bottom: none; }
.bi-label { color: var(--dim); flex-shrink: 0; }
.bi-value { font-weight: 500; text-align: right; }
.bi-plan-name {
  font-size: 22px;
  font-weight: 700;
  color: var(--cyan,#06b6d4);
  line-height: 1;
}
.bi-plan-sub { font-size: 12px; color: var(--dim); margin-top: 4px; }
.bi-plan-hero { display: flex; align-items: flex-end; gap: 16px; padding: 4px 0 12px; }
.bi-amount { font-size: 28px; font-weight: 700; }
.bi-amount-interval { font-size: 13px; color: var(--dim); padding-bottom: 5px; }
.bi-card-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(0,0,0,.05);
  font-size: 13px;
}
.bi-card-row:last-child { border-bottom: none; }
.bi-card-icon { font-size: 20px; width: 28px; text-align: center; flex-shrink: 0; }
.bi-card-detail { flex: 1; }
.bi-card-brand { font-weight: 500; }
.bi-card-meta { font-size: 11px; color: var(--dim); }
.bi-default-badge {
  font-size: 10px;
  padding: 2px 7px;
  border-radius: 10px;
  background: rgba(6,182,212,.12);
  color: var(--cyan,#06b6d4);
  font-weight: 600;
}
.bi-invoice-row {
  display: grid;
  grid-template-columns: 1fr 80px 80px 60px;
  gap: 8px;
  align-items: center;
  padding: 9px 0;
  border-bottom: 1px solid rgba(0,0,0,.05);
  font-size: 12px;
}
.bi-invoice-row:last-child { border-bottom: none; }
.bi-invoice-header {
  font-size: 11px;
  font-weight: 600;
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: .04em;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
  display: grid;
  grid-template-columns: 1fr 80px 80px 60px;
  gap: 8px;
}
.bi-invoice-link {
  color: var(--cyan,#06b6d4);
  text-decoration: none;
  font-size: 11px;
}
.bi-invoice-link:hover { text-decoration: underline; }
.bi-empty { padding: 20px; text-align: center; color: var(--dim); font-size: 13px; }
.bi-loader {
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.bi-spinner {
  width: 24px; height: 24px;
  border: 3px solid var(--border);
  border-top-color: var(--cyan,#06b6d4);
  border-radius: 50%;
  animation: bi-spin .8s linear infinite;
}
@keyframes bi-spin { to { transform: rotate(360deg); } }
.bi-action-btn {
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
  min-height: 32px;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.bi-action-btn:hover { background: rgba(0,0,0,.05); }
.bi-action-btn.primary {
  background: var(--cyan,#06b6d4);
  color: #fff;
  border-color: transparent;
}
.bi-cancel-warning {
  font-size: 12px;
  color: var(--warn,#f59e0b);
  background: rgba(245,158,11,.08);
  padding: 8px 12px;
  border-radius: 7px;
  border-left: 3px solid var(--warn,#f59e0b);
  margin-top: 10px;
}
@media (max-width: 480px) {
  .bi-invoice-row, .bi-invoice-header {
    grid-template-columns: 1fr 70px 50px;
  }
  .bi-invoice-row > :last-child,
  .bi-invoice-header > :last-child { display: none; }
}
`;

  /* ── Main component ──────────────────────────────────────── */
  function BillingInfo() {
    const [sub, setSub] = React.useState(null);
    const [pms, setPms] = React.useState(null);
    const [invoices, setInvoices] = React.useState(null);
    const [loading, setLoading] = React.useState(true);
    const [error, setError] = React.useState(null);

    React.useEffect(() => {
      Promise.all([
        apiFetch('/billing/subscription'),
        apiFetch('/billing/payment-methods'),
        apiFetch('/billing/invoices'),
      ])
        .then(([s, p, i]) => {
          setSub(s);
          setPms(p.payment_methods || []);
          setInvoices(i.invoices || []);
          setLoading(false);
        })
        .catch(err => {
          setError(err.message);
          setLoading(false);
        });
    }, []);

    if (loading) {
      return React.createElement('div', { className: 'bi-root' },
        React.createElement('style', null, CSS),
        React.createElement('div', { className: 'bi-loader', 'aria-live': 'polite', 'aria-label': 'Loading billing info' },
          React.createElement('div', { className: 'bi-spinner' })
        )
      );
    }

    if (error) {
      return React.createElement('div', { className: 'bi-root' },
        React.createElement('style', null, CSS),
        React.createElement('div', { className: 'bi-card' },
          React.createElement('div', { className: 'bi-card-body' },
            React.createElement('p', { style: { color: 'var(--red,#ef4444)', fontSize: 13 } },
              'Could not load billing info: ' + error
            ),
            React.createElement('button', {
              className: 'bi-action-btn',
              onClick: () => window.location.reload(),
              style: { marginTop: 10 },
            }, 'Retry')
          )
        )
      );
    }

    const handleManageInStripe = () => {
      fetch(apiBase() + '/billing/portal', {
        method: 'POST',
        headers: { Authorization: 'Bearer ' + getToken(), 'Content-Type': 'application/json' },
      })
        .then(r => r.json())
        .then(d => { if (d.url) window.location.href = d.url; })
        .catch(() => {});
    };

    return React.createElement('div', { className: 'bi-root' },
      React.createElement('style', null, CSS),

      /* ── Subscription card ─── */
      React.createElement('div', { className: 'bi-card' },
        React.createElement('div', { className: 'bi-card-header' },
          React.createElement('span', { className: 'bi-card-title' }, 'Current plan'),
          sub && sub.has_subscription && React.createElement('button', {
            className: 'bi-action-btn',
            onClick: handleManageInStripe,
          }, 'Manage in Stripe')
        ),
        React.createElement('div', { className: 'bi-card-body' },
          sub && !sub.has_subscription
            ? React.createElement('div', { className: 'bi-empty' },
                'No active subscription. ',
                React.createElement('a', {
                  href: 'https://wpsitebeam.io/pricing',
                  className: 'bi-invoice-link',
                }, 'View plans')
              )
            : sub && React.createElement(React.Fragment, null,
                React.createElement('div', { className: 'bi-plan-hero' },
                  React.createElement('div', null,
                    React.createElement('div', { className: 'bi-plan-name' }, sub.plan_display),
                    sub.is_byok && React.createElement('div', { className: 'bi-plan-sub' }, 'BYOK — 20% off')
                  ),
                  sub.amount_cents > 0 && React.createElement('div', null,
                    React.createElement('span', { className: 'bi-amount' },
                      formatCents(sub.amount_cents, sub.currency)
                    ),
                    React.createElement('span', { className: 'bi-amount-interval' },
                      ' / ' + (sub.billing_interval === 'year' ? 'year' : 'month')
                    )
                  ),
                  statusPill(sub.status)
                ),
                React.createElement('div', { className: 'bi-row' },
                  React.createElement('span', { className: 'bi-label' }, 'Billing cycle'),
                  React.createElement('span', { className: 'bi-value' },
                    sub.billing_interval === 'year' ? 'Annual' : 'Monthly'
                  )
                ),
                sub.current_period_end && React.createElement('div', { className: 'bi-row' },
                  React.createElement('span', { className: 'bi-label' },
                    sub.cancel_at_period_end ? 'Access ends' : 'Next billing date'
                  ),
                  React.createElement('span', { className: 'bi-value' },
                    formatDate(sub.current_period_end)
                  )
                ),
                sub.trial_end && sub.status === 'trialing' && React.createElement('div', { className: 'bi-row' },
                  React.createElement('span', { className: 'bi-label' }, 'Trial ends'),
                  React.createElement('span', { className: 'bi-value' }, formatDate(sub.trial_end))
                ),
                sub.cancel_at_period_end && React.createElement('div', { className: 'bi-cancel-warning', role: 'alert' },
                  'Your subscription is canceled and will end on ' + formatDate(sub.current_period_end) + '. ',
                  'Manage in Stripe to reactivate.'
                )
              )
        )
      ),

      /* ── Payment methods card ─── */
      React.createElement('div', { className: 'bi-card' },
        React.createElement('div', { className: 'bi-card-header' },
          React.createElement('span', { className: 'bi-card-title' }, 'Payment methods'),
          React.createElement('button', {
            className: 'bi-action-btn',
            onClick: handleManageInStripe,
            'aria-label': 'Manage payment methods in Stripe',
          }, 'Add / remove')
        ),
        React.createElement('div', { className: 'bi-card-body' },
          !pms || pms.length === 0
            ? React.createElement('div', { className: 'bi-empty' }, 'No saved payment methods.')
            : pms.map(pm =>
                React.createElement('div', { key: pm.id, className: 'bi-card-row' },
                  React.createElement('span', { className: 'bi-card-icon', 'aria-hidden': 'true' },
                    cardIcon(pm.brand)
                  ),
                  React.createElement('div', { className: 'bi-card-detail' },
                    React.createElement('div', { className: 'bi-card-brand' },
                      brandLabel(pm.brand) + ' ending in ' + pm.last4
                    ),
                    React.createElement('div', { className: 'bi-card-meta' },
                      'Expires ' + pm.exp_month + '/' + pm.exp_year +
                      (pm.wallet ? ' \u00B7 ' + pm.wallet.replace('_', ' ') : '')
                    )
                  ),
                  pm.is_default && React.createElement('span', { className: 'bi-default-badge' }, 'Default')
                )
              )
        )
      ),

      /* ── Invoices card ─── */
      React.createElement('div', { className: 'bi-card' },
        React.createElement('div', { className: 'bi-card-header' },
          React.createElement('span', { className: 'bi-card-title' }, 'Invoice history')
        ),
        React.createElement('div', { className: 'bi-card-body' },
          !invoices || invoices.length === 0
            ? React.createElement('div', { className: 'bi-empty' }, 'No invoices yet.')
            : React.createElement('div', null,
                React.createElement('div', { className: 'bi-invoice-header', 'aria-hidden': 'true' },
                  React.createElement('span', null, 'Description'),
                  React.createElement('span', null, 'Date'),
                  React.createElement('span', null, 'Amount'),
                  React.createElement('span', null, 'Status')
                ),
                invoices.map(inv =>
                  React.createElement('div', {
                    key: inv.id,
                    className: 'bi-invoice-row',
                    role: 'row',
                  },
                    React.createElement('span', null,
                      inv.lines_summary || inv.description || inv.number || 'Invoice',
                      inv.hosted_invoice_url && React.createElement('a', {
                        href: inv.hosted_invoice_url,
                        target: '_blank',
                        rel: 'noopener noreferrer',
                        className: 'bi-invoice-link',
                        style: { marginLeft: 8 },
                        'aria-label': 'View invoice ' + (inv.number || ''),
                      }, 'View'),
                      inv.invoice_pdf && React.createElement('a', {
                        href: inv.invoice_pdf,
                        target: '_blank',
                        rel: 'noopener noreferrer',
                        className: 'bi-invoice-link',
                        style: { marginLeft: 6 },
                        'aria-label': 'Download PDF for invoice ' + (inv.number || ''),
                      }, 'PDF')
                    ),
                    React.createElement('span', null, formatDate(inv.created)),
                    React.createElement('span', null,
                      formatCents(inv.amount_paid || inv.amount_due, inv.currency)
                    ),
                    React.createElement('span', null, statusPill(inv.status))
                  )
                )
              )
        )
      )
    );
  }

  window.BillingInfo = BillingInfo;
})();
