/**
 * CancellationFlow.jsx — Cancel subscription, account deletion, subscription-ended banner
 * Repo: wpsitebeam-app / design/CancellationFlow.jsx
 * Version: v1.0.0 — 2026-05-26
 *
 * Exports:
 *   window.CancelModal           — win-back modal shown before redirecting to Stripe portal
 *   window.AccountDeletion       — danger zone account deletion with confirm input
 *   window.SubscriptionEndedBanner — read-only state banner when is_active === false
 *
 * Integration notes:
 *   CancelModal: trigger from Billing settings "Cancel subscription" button
 *   AccountDeletion: render in Account Settings → Danger Zone section
 *   SubscriptionEndedBanner: render at top of App when account.is_active === false
 */

(function () {
  'use strict';
  const VERSION = '1.0.0';
  console.log('[CancellationFlow] v' + VERSION + ' loaded');

  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, opts) {
    const r = await fetch(apiBase() + path, {
      ...opts,
      headers: { Authorization: 'Bearer ' + getToken(), 'Content-Type': 'application/json', ...(opts && opts.headers) },
    });
    const b = await r.json().catch(() => ({}));
    if (!r.ok) throw new Error(b.error || 'HTTP ' + r.status);
    return b;
  }
  function fmt(n, cur) {
    return new Intl.NumberFormat('en-US', { style: 'currency', currency: (cur || 'usd').toUpperCase(), minimumFractionDigits: 0 }).format((n || 0) / 100);
  }
  function fmtDate(ts) {
    return ts ? new Date(ts * 1000).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }) : '';
  }

  /* ─────────────────────────────────────────────────────────── */
  /* COMPONENT 1: CancelModal                                    */
  /* ─────────────────────────────────────────────────────────── */
  const CANCEL_CSS = `
.cm-overlay { position:fixed;inset:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:8000;padding:20px; }
.cm-card { background:var(--panel);border:1px solid var(--border);border-radius:16px;width:100%;max-width:480px;overflow:hidden; }
.cm-header { padding:20px 24px 0;display:flex;justify-content:space-between;align-items:center; }
.cm-title { font-size:18px;font-weight:700; }
.cm-close { background:none;border:none;cursor:pointer;color:var(--dim);font-size:20px;padding:4px;border-radius:6px;min-height:32px;min-width:32px; }
.cm-close:hover { background:rgba(0,0,0,.1); }
.cm-body { padding:16px 24px 24px; }
.cm-usage-grid { display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:12px 0 20px; }
.cm-usage-card { background:rgba(0,0,0,.06);border-radius:8px;padding:10px 12px;text-align:center; }
.cm-usage-num { font-size:22px;font-weight:700;color:var(--cyan,#06b6d4);line-height:1; }
.cm-usage-label { font-size:11px;color:var(--dim);margin-top:3px; }
.cm-offer { border:1px solid rgba(6,182,212,.3);background:rgba(6,182,212,.06);border-radius:10px;padding:14px 16px;margin-bottom:16px; }
.cm-offer-label { font-size:11px;font-weight:600;color:var(--cyan,#06b6d4);text-transform:uppercase;letter-spacing:.05em;margin-bottom:5px; }
.cm-offer-text { font-size:13px;font-weight:500;margin-bottom:8px; }
.cm-offer-btn { padding:8px 16px;font-size:13px;font-weight:600;background:var(--cyan,#06b6d4);color:#fff;border:none;border-radius:7px;cursor:pointer;min-height:36px; }
.cm-offer-btn:hover { opacity:.9; }
.cm-cancel-link { display:block;text-align:center;font-size:13px;color:var(--dim);cursor:pointer;padding:10px;background:none;border:none;width:100%;min-height:36px; }
.cm-cancel-link:hover { color:var(--red,#ef4444); }
`;

  function CancelModal({ sub, usage, onClose, onCancelAnyway }) {
    const [loading, setLoading] = React.useState(false);
    sub = sub || {};
    usage = usage || {};

    function getOffer() {
      if (sub.billing_interval === 'month' && sub.status === 'active') {
        return { label: 'Save 10%', text: 'Switch to annual billing and save 10% — locked in for the year.', cta: 'Switch to annual' };
      }
      if (sub.plan === 'agency' || sub.plan === 'growth') {
        return { label: 'Downgrade option', text: 'Switch to the Starter plan for ' + fmt(9900, sub.currency) + '/mo — keep your data.', cta: 'Switch to Starter' };
      }
      return null;
    }
    const offer = getOffer();

    async function handleCancelAnyway() {
      setLoading(true);
      try {
        const data = await apiFetch('/billing/portal', { method: 'POST' });
        if (data.url) window.location.href = data.url;
      } catch (e) { console.error('[CancelModal]', e.message); }
      finally { setLoading(false); }
    }

    return React.createElement(React.Fragment, null,
      React.createElement('style', null, CANCEL_CSS),
      React.createElement('div', { className: 'cm-overlay', role: 'dialog', 'aria-modal': 'true', 'aria-label': 'Cancel subscription' },
        React.createElement('div', { className: 'cm-card' },
          React.createElement('div', { className: 'cm-header' },
            React.createElement('h2', { className: 'cm-title' }, 'Before you go\u2026'),
            React.createElement('button', { className: 'cm-close', onClick: onClose, 'aria-label': 'Close' }, '\u00D7')
          ),
          React.createElement('div', { className: 'cm-body' },
            (usage.scans_run || usage.issues_found) && React.createElement(React.Fragment, null,
              React.createElement('p', { style: { fontSize: 13, color: 'var(--dim)', marginBottom: 4 } }, 'Here\u2019s what you\u2019ve accomplished:'),
              React.createElement('div', { className: 'cm-usage-grid' },
                usage.sites_connected && React.createElement('div', { className: 'cm-usage-card' },
                  React.createElement('div', { className: 'cm-usage-num' }, usage.sites_connected),
                  React.createElement('div', { className: 'cm-usage-label' }, 'Sites connected')
                ),
                usage.scans_run && React.createElement('div', { className: 'cm-usage-card' },
                  React.createElement('div', { className: 'cm-usage-num' }, usage.scans_run),
                  React.createElement('div', { className: 'cm-usage-label' }, 'Scans run')
                ),
                usage.issues_found && React.createElement('div', { className: 'cm-usage-card' },
                  React.createElement('div', { className: 'cm-usage-num' }, usage.issues_found),
                  React.createElement('div', { className: 'cm-usage-label' }, 'Issues found')
                ),
                usage.issues_fixed && React.createElement('div', { className: 'cm-usage-card' },
                  React.createElement('div', { className: 'cm-usage-num' }, usage.issues_fixed),
                  React.createElement('div', { className: 'cm-usage-label' }, 'Issues fixed')
                )
              )
            ),
            offer && React.createElement('div', { className: 'cm-offer' },
              React.createElement('div', { className: 'cm-offer-label' }, offer.label),
              React.createElement('div', { className: 'cm-offer-text' }, offer.text),
              React.createElement('button', { className: 'cm-offer-btn', onClick: onClose }, offer.cta)
            ),
            React.createElement('button', {
              className: 'cm-cancel-link', onClick: handleCancelAnyway, disabled: loading,
              'aria-label': 'Cancel subscription anyway',
            }, loading ? 'Redirecting to Stripe\u2026' : 'Cancel subscription anyway')
          )
        )
      )
    );
  }

  /* ─────────────────────────────────────────────────────────── */
  /* COMPONENT 2: SubscriptionEndedBanner                        */
  /* ─────────────────────────────────────────────────────────── */
  const BANNER_CSS = `
.seb-banner { background:rgba(245,158,11,.1);border-bottom:1px solid rgba(245,158,11,.3);padding:10px 20px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;font-size:13px; }
.seb-text { color:var(--text); }
.seb-text strong { color:var(--warn,#f59e0b); }
.seb-cta { padding:6px 16px;font-size:13px;font-weight:600;background:var(--warn,#f59e0b);color:#fff;border:none;border-radius:7px;cursor:pointer;min-height:32px;white-space:nowrap; }
.seb-cta:hover { opacity:.88; }
`;

  function SubscriptionEndedBanner({ endedAt, onReactivate }) {
    return React.createElement(React.Fragment, null,
      React.createElement('style', null, BANNER_CSS),
      React.createElement('div', { className: 'seb-banner', role: 'alert' },
        React.createElement('span', { className: 'seb-text' },
          React.createElement('strong', null, 'Your subscription has ended.'),
          endedAt ? ' Access expired ' + fmtDate(endedAt) + '.' : '',
          ' Your data is preserved for 90 days.'
        ),
        React.createElement('button', { className: 'seb-cta', onClick: onReactivate }, 'Reactivate')
      )
    );
  }

  /* ─────────────────────────────────────────────────────────── */
  /* COMPONENT 3: AccountDeletion (Danger Zone)                  */
  /* ─────────────────────────────────────────────────────────── */
  const DELETION_CSS = `
.ad-section { border:1px solid rgba(239,68,68,.3);border-radius:12px;padding:20px 24px;background:rgba(239,68,68,.04); }
.ad-title { font-size:15px;font-weight:600;color:var(--red,#ef4444);margin-bottom:8px; }
.ad-desc { font-size:13px;color:var(--dim);line-height:1.6;margin-bottom:16px; }
.ad-consequences { font-size:12px;color:var(--dim);margin:0 0 16px;padding-left:16px;line-height:1.8; }
.ad-confirm-label { font-size:12px;font-weight:500;color:var(--dim);margin-bottom:6px; }
.ad-confirm-input { width:100%;padding:9px 12px;font-size:13px;border:1px solid rgba(239,68,68,.4);border-radius:7px;background:var(--panel);color:var(--text);box-sizing:border-box;font-family:monospace;margin-bottom:12px; }
.ad-confirm-input:focus { outline:2px solid var(--red,#ef4444);outline-offset:1px; }
.ad-delete-btn { padding:9px 20px;font-size:13px;font-weight:600;background:var(--red,#ef4444);color:#fff;border:none;border-radius:7px;cursor:pointer;min-height:36px; }
.ad-delete-btn:disabled { opacity:.4;cursor:not-allowed; }
.ad-result { font-size:13px;padding:10px 14px;border-radius:8px;margin-top:12px; }
.ad-result-ok { background:rgba(16,185,129,.1);color:var(--green,#10b981);border:1px solid rgba(16,185,129,.3); }
.ad-result-err { background:rgba(239,68,68,.1);color:var(--red,#ef4444);border:1px solid rgba(239,68,68,.3); }
`;

  function AccountDeletion({ onDeleted }) {
    const REQUIRED = 'DELETE MY ACCOUNT';
    const [input, setInput] = React.useState('');
    const [loading, setLoading] = React.useState(false);
    const [result, setResult] = React.useState(null);

    async function handleDelete() {
      if (input !== REQUIRED) return;
      setLoading(true); setResult(null);
      try {
        const data = await apiFetch('/account/close', { method: 'DELETE', body: JSON.stringify({ confirm: REQUIRED }) });
        setResult({ ok: true, message: data.message, closes_at: data.closes_at });
        onDeleted && onDeleted(data);
      } catch (e) {
        setResult({ ok: false, message: e.message });
      } finally { setLoading(false); }
    }

    return React.createElement(React.Fragment, null,
      React.createElement('style', null, DELETION_CSS),
      React.createElement('div', { className: 'ad-section' },
        React.createElement('h3', { className: 'ad-title' }, '\u26A0\uFE0F Delete account'),
        React.createElement('p', { className: 'ad-desc' }, 'Permanently delete your account and all associated data. This cannot be undone after 30 days.'),
        React.createElement('ul', { className: 'ad-consequences' },
          React.createElement('li', null, 'Your subscription is canceled immediately'),
          React.createElement('li', null, 'All scans, projects, and settings are deleted'),
          React.createElement('li', null, 'Data is preserved for 30 days, then permanently removed'),
          React.createElement('li', null, 'Contact support within 30 days to cancel deletion')
        ),
        !result
          ? React.createElement(React.Fragment, null,
              React.createElement('p', { className: 'ad-confirm-label' }, 'Type DELETE MY ACCOUNT to confirm:'),
              React.createElement('input', {
                type: 'text', className: 'ad-confirm-input',
                value: input, onChange: e => setInput(e.target.value),
                placeholder: 'DELETE MY ACCOUNT',
                'aria-label': 'Type DELETE MY ACCOUNT to confirm account deletion',
                autoComplete: 'off',
              }),
              React.createElement('button', {
                className: 'ad-delete-btn',
                onClick: handleDelete,
                disabled: input !== REQUIRED || loading,
              }, loading ? 'Processing\u2026' : 'Delete my account')
            )
          : React.createElement('div', {
              className: 'ad-result ' + (result.ok ? 'ad-result-ok' : 'ad-result-err'),
              role: 'alert',
            },
              result.ok
                ? result.message || 'Account scheduled for deletion.'
                : 'Error: ' + result.message
            )
      )
    );
  }

  /* ─── Exports ─────────────────────────────────────────────── */
  window.CancelModal            = CancelModal;
  window.SubscriptionEndedBanner = SubscriptionEndedBanner;
  window.AccountDeletion        = AccountDeletion;

})();
