// Checkout pages:
//   /checkout            — bridge that loads Paddle.js + opens overlay
//   /checkout/success    — post-payment confirmation
//   /checkout/canceled   — user closed the overlay without paying
//
// CONTEXT: Paddle Billing's "hosted checkout" is misleadingly named — it
// is NOT a Paddle-hosted URL like Stripe Checkout. Paddle requires the
// merchant to load Paddle.js v2 on a URL the merchant controls. When
// Paddle.js sees `?_ptxn=txn_...` in the URL it auto-opens an overlay
// for that transaction; card data is collected inside the overlay (PCI-
// compliant, on Paddle's iframe). After payment Paddle redirects to the
// dashboard-configured `default_payment_url`.
//
// Flow when Mac app calls /billing/checkout:
//   backend POST /transactions to Paddle (with custom_data.user_id)
//   → Paddle returns checkout.url shaped like
//     `https://parleur.app/checkout?_ptxn=txn_01...` (the merchant's
//     default_payment_url + transaction id)
//   → Mac opens that URL in the browser
//   → /checkout component below loads Paddle.js, sees _ptxn, opens overlay
//   → user enters card on Paddle's iframe overlay
//   → on success: Paddle redirects to /checkout/success
//   → on close: Paddle dispatches the `checkout.closed` event
//
// The webhook side (independent of any redirect URL) is what actually
// updates entitlement — see backend/internal/billing/paddle_events.go
// `resolveUser()`, which reads `data.custom_data.user_id` from every
// subscription / transaction event.

// Paddle environment selection. Client-side tokens are PUBLIC by design
// (Paddle calls them "client-side tokens" precisely because they ship in
// browser source code) — both values are safe to commit. The real
// authority is the API key used by the backend.
//
// Selection by hostname so the same bundle works in dev / staging / prod
// without a build step:
//   parleur.app             → production (live_*)
//   staging.parleur.app /   → sandbox (test_*)
//   *.pages.dev / localhost
//
// CONTEXT: Production token is a placeholder until we wire real Paddle
// production. When that happens, drop in the live_* token and keep the
// test token for staging branches; the host check picks correctly.
const PADDLE_PROD_TOKEN    = 'live_TODO_REPLACE_BEFORE_GOING_LIVE';
const PADDLE_SANDBOX_TOKEN = 'test_faa268ee8871120ad2ecce6a94c';

function selectPaddleConfig() {
  const host = window.location.hostname;
  const isProdHost = host === 'parleur.app' || host === 'www.parleur.app';
  if (isProdHost && !PADDLE_PROD_TOKEN.includes('TODO')) {
    return { token: PADDLE_PROD_TOKEN, environment: 'production' };
  }
  return { token: PADDLE_SANDBOX_TOKEN, environment: 'sandbox' };
}

const CheckoutLanding = ({ lang }) => {
  const T = (en, zh, ja) => (lang === 'zh' ? zh : lang === 'ja' ? ja : en);
  const [status, setStatus] = React.useState('loading');
  const [errMsg, setErrMsg] = React.useState('');

  React.useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const txnId = params.get('_ptxn');
    if (!txnId) {
      setStatus('no-txn');
      return;
    }

    let cancelled = false;
    let scriptEl = null;

    const initAndOpen = () => {
      if (cancelled) return;
      try {
        const cfg = selectPaddleConfig();
        if (cfg.environment === 'sandbox') window.Paddle.Environment.set('sandbox');
        window.Paddle.Initialize({
          token: cfg.token,
          eventCallback: (e) => {
            // checkout.completed → user paid; Paddle will redirect to the
            // merchant's default_payment_url right after this fires.
            // checkout.closed   → user dismissed without paying.
            if (!e || !e.name) return;
            if (e.name === 'checkout.closed') {
              window.location.href = '/checkout/canceled';
            }
          },
        });
        window.Paddle.Checkout.open({
          transactionId: txnId,
          settings: {
            displayMode: 'overlay',
            theme: 'light',
            successUrl: window.location.origin + '/checkout/success?_ptxn=' + encodeURIComponent(txnId),
          },
        });
        setStatus('overlay-open');
      } catch (err) {
        setStatus('error');
        setErrMsg(String(err));
      }
    };

    if (window.Paddle && window.Paddle.Checkout) {
      initAndOpen();
      return;
    }
    scriptEl = document.createElement('script');
    scriptEl.src = 'https://cdn.paddle.com/paddle/v2/paddle.js';
    scriptEl.async = true;
    scriptEl.onload = initAndOpen;
    scriptEl.onerror = () => {
      setStatus('error');
      setErrMsg('Failed to load Paddle.js — check network');
    };
    document.head.appendChild(scriptEl);

    return () => { cancelled = true; };
  }, []);

  return (
    <div className="doc">
      <div className="doc-eyebrow">Parleur</div>
      <h1>{T('Opening checkout…', '開啟結帳…', 'チェックアウトを開いています…')}</h1>
      {status === 'loading' && (
        <p>{T(
          'Loading Paddle’s secure checkout. This usually takes a second or two.',
          '正在載入 Paddle 的安全結帳視窗。通常一兩秒就會出現。',
          'Paddle のセキュアなチェックアウトを読み込んでいます。通常 1〜2 秒で表示されます。'
        )}</p>
      )}
      {status === 'overlay-open' && (
        <p>{T(
          'Checkout overlay should appear above this page. Card data is collected by Paddle, not by Parleur.',
          '結帳視窗會在這頁上方彈出。卡片資料由 Paddle 收集,Parleur 不會碰到。',
          'チェックアウトはこのページの上に表示されます。カード情報は Paddle が処理し、Parleur には届きません。'
        )}</p>
      )}
      {status === 'no-txn' && (
        <>
          <p>{T(
            'No checkout in progress. This page only opens automatically when you start a subscription from the Parleur app.',
            '目前沒有進行中的結帳。這頁只會在你從 Parleur app 開始訂閱時自動開啟。',
            '進行中のチェックアウトはありません。Parleur アプリからサブスクリプションを開始するとこのページが自動で開きます。'
          )}</p>
          <p><a href="#/pricing">{T('See pricing →', '查看價格 →', '料金を見る →')}</a></p>
        </>
      )}
      {status === 'error' && (
        <p style={{ color: 'var(--err)' }}>{T('Could not open checkout: ', '無法開啟結帳:', 'チェックアウトを開けませんでした:')} {errMsg}</p>
      )}
    </div>
  );
};

const CheckoutSuccess = ({ lang }) => {
  const T = (en, zh, ja) => (lang === 'zh' ? zh : lang === 'ja' ? ja : en);
  const params = new URLSearchParams(window.location.search);
  const txnId = params.get('_ptxn');

  return (
    <div className="doc">
      <div className="doc-eyebrow">Parleur</div>
      <h1>{T('Subscription confirmed', '訂閱已啟動', 'サブスクリプション開始')}</h1>
      <p>{T(
        'Your 7-day free trial is running. We won’t charge your card until day 8.',
        '7 天免費試用已開始。第 8 天才會扣款。',
        '7日間の無料トライアルが開始されました。8日目から課金されます。'
      )}</p>

      <h2>{T('What to do next', '接下來怎麼用', '次のステップ')}</h2>
      <ol>
        <li>{T(
          'Switch back to the Parleur app on your Mac.',
          '切回你 Mac 上的 Parleur app。',
          'Mac の Parleur アプリに戻ります。'
        )}</li>
        <li>{T(
          'The app will detect your subscription within a minute and unlock writing + reading mode.',
          'app 會在一分鐘內偵測到訂閱，自動解鎖 Writing 跟 Reading mode。',
          'アプリは 1 分以内にサブスクリプションを検知し、Writing と Reading モードを開放します。'
        )}</li>
        <li>{T(
          'Hover any text with the modifier key, or press ⌘⇧T to translate what you’re typing.',
          '按住 modifier 鍵 hover 任何段落，或按 ⌘⇧T 翻譯你正在打的字。',
          '修飾キーを押しながらテキストにホバーするか、⌘⇧T でタイピング中の文章を翻訳します。'
        )}</li>
      </ol>

      <h2>{T('Manage your plan', '管理你的方案', 'プラン管理')}</h2>
      <p>{T(
        'You can cancel any time before day 7 to avoid the first charge — from inside the app or via the link in your Paddle receipt email. After day 7, cancellation stops the next renewal but keeps access through the current period.',
        '第 7 天前隨時可以取消，不會被扣款 — 在 app 內或透過 Paddle 收據 email 裡的連結都可以。第 7 天之後取消，會在當期結束停用，期內仍能使用。',
        '7日目までに解約すれば課金されません — アプリ内、または Paddle のレシートメールのリンクから解約できます。7日目以降の解約は、当期間終了時に停止されますが、期間内は利用可能です。'
      )}</p>

      {txnId && (
        <p style={{ fontSize: 12, color: 'var(--fg-dim)', fontFamily: 'var(--font-mono)', marginTop: 32 }}>
          {T('Transaction', '交易編號', 'トランザクション')}: {txnId}
        </p>
      )}

      <p style={{ marginTop: 24 }}>
        {T(
          'Questions? Email ',
          '有問題?寄信到 ',
          'お問い合わせは '
        )}
        <a href="mailto:support@parleur.app">support@parleur.app</a>
        {T('.', '。', ' まで。')}
      </p>
    </div>
  );
};

const CheckoutCanceled = ({ lang, setRoute }) => {
  const T = (en, zh, ja) => (lang === 'zh' ? zh : lang === 'ja' ? ja : en);

  return (
    <div className="doc">
      <div className="doc-eyebrow">Parleur</div>
      <h1>{T('Checkout canceled', '已取消結帳', 'お支払いはキャンセルされました')}</h1>
      <p>{T(
        'You closed the checkout before completing payment. No card was charged and no subscription was created.',
        '你在完成付款前關閉了結帳頁。沒有任何扣款,也沒有建立訂閱。',
        '支払い完了前にチェックアウトを閉じました。課金もサブスクリプション作成も発生していません。'
      )}</p>
      <p>{T(
        'You can pick a plan again from the Parleur app, or browse pricing here:',
        '可以回 Parleur app 重新選方案,或在這邊看完整價格:',
        'Parleur アプリから再度プランを選択するか、こちらで料金を確認できます:'
      )}</p>
      <p>
        <a
          href="#/pricing"
          onClick={(e) => {
            e.preventDefault();
            setRoute('/pricing');
          }}
        >
          {T('See pricing →', '查看價格 →', '料金を見る →')}
        </a>
      </p>
    </div>
  );
};
