/* ============================================================
   Subscription view — rendered inside the dashboard SPA shell
   so the sidebar stays visible. All API/ID/Broadcast contracts
   preserved.
   ============================================================ */
const { useEffect: useEffectSV, useRef: useRefSV } = React;

function CheckIcon() {
  return <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>;
}
function XIcon() {
  return <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>;
}
function ArrowRight() {
  return <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>;
}

const PLAN_DEFS = [
  { id: 'free',    name: 'Free',    period: '/ forever', priceLabel: '0',       featured: false, btnLabel: 'Current Plan', btnDisabled: true, icon: (
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>),
    features: [
      { text: 'Basic surebet alerts', on: true },
      { text: 'ROI up to 1%', on: true },
      { text: 'ROI Calculator', on: true },
      { text: 'Full ROI range', on: false },
      { text: 'Telegram bot alerts', on: false },
    ],
  },
  { id: 'daily',   name: 'Daily',   period: '/ day',    priceLabel: '89k',     featured: false, icon: (
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 14"/></svg>) },
  { id: 'weekly',  name: 'Weekly',  period: '/ week',    priceLabel: '549k',    featured: false,  icon: (
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><polyline points="13 17 18 12 13 7"/><polyline points="6 17 11 12 6 7"/></svg>) },
  { id: 'monthly', name: 'Monthly', period: '/ month',   priceLabel: '1,990k',  featured: true, icon: (
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>) },
  { id: 'yearly',  name: 'Yearly',  period: '/ year',     priceLabel: '21,900k', featured: false, icon: (
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2l3 7h7l-5.5 4.5L18 21l-6-4-6 4 1.5-7.5L2 9h7z"/></svg>) },
];
const PAID_FEATURES = [
  'All surebet alerts', 'Unlimited ROI range', 'ROI Calculator', 'Telegram bot alerts',
];
const PLAN_SAVE_DEFAULT = { weekly: 'Save 1% vs daily', monthly: 'Save 16% vs daily', yearly: 'Save 24% vs daily' };

function PlanCard({ plan, onSubscribe }) {
  const isFree = plan.id === 'free';
  const features = isFree ? plan.features : [...PAID_FEATURES.map(t => ({ text: t, on: true })), { text: 'QR payment (bank)', on: plan.id !== 'daily' }];
  return (
    <div className={'plan-card' + (plan.featured ? ' featured' : '')} data-plan={plan.id} id={`card-${plan.id}`}>
      {plan.featured && (
        <span className="featured-ribbon">
          <svg width="9" height="9" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>
          Best Value
        </span>
      )}
      <div className="plan-icon" aria-hidden="true">{plan.icon}</div>
      <div className="plan-name">{plan.name}</div>
      <div className="plan-price-row">
        <span className="plan-price" id={`price-${plan.id}`}>{plan.priceLabel}</span>
        <span className="plan-period">{plan.period}</span>
      </div>
      {plan.id !== 'free' && plan.id !== 'daily' && <div className="plan-perday" id={`perday-${plan.id}`}></div>}
      <ul className="plan-features">
        {features.map((f, i) => (
          <li key={i} className={f.on ? '' : 'disabled'}>
            <span className="feat-icon">{f.on ? <CheckIcon/> : <XIcon/>}</span>
            {f.text}
          </li>
        ))}
      </ul>
      {!isFree && <div className="plan-save" id={`save-${plan.id}`}>{PLAN_SAVE_DEFAULT[plan.id] || ''}</div>}
      {isFree ? (
        <button className="plan-subscribe disabled" id="freeBtn">{plan.btnLabel}</button>
      ) : (
        <button className="plan-subscribe" onClick={() => onSubscribe(plan.id)}>
          Subscribe <ArrowRight />
        </button>
      )}
    </div>
  );
}

function SubscriptionView() {
  const initialized = useRefSV(false);

  useEffectSV(() => {
    if (initialized.current) return;
    initialized.current = true;

    // ── Subscription / Payment logic (preserves UI Contract API & IDs) ───
    const token = localStorage.getItem('fm_token');
    const PLAN_NAMES = { daily: 'Day', weekly: 'Week', monthly: 'Month', yearly: 'Year' };
    const PLAN_UNITS = { daily: 'day', weekly: 'week', monthly: 'month', yearly: 'year' };
    const BASE_PRICES = { daily: 89000, weekly: 549000, monthly: 1990000, yearly: 21900000 };
    const USD_PRICES = { daily: 6, weekly: 29, monthly: 89, yearly: 899 };
    const PLAN_DAYS  = { daily: 1, weekly: 7, monthly: 30, yearly: 365 };
    const ENABLED = ['daily', 'weekly', 'monthly', 'yearly'];

    let prices = { ...BASE_PRICES };
    let promoEnabled = false;
    let promoPrices = {};
    let promoLimits = {};
    let promoUsage = {};
    let currentOrder = null;
    let currentPlan = null;
    let currentQty = 1;
    let currentPaymentMethod = 'qr';
    let _isVN = true; // only VN customers see QR; resolved from /api/geo
    let _usdRate = 25500; // 1 USD = X VND; refined from /api/exchange-rates
    Promise.all([
      fetch('/api/geo').then(r => r.json()).catch(() => null),
      fetch('/api/exchange-rates/convert?amount=1&from=USD&to=VND').then(r => r.json()).catch(() => null),
    ]).then(([g, x]) => {
      if (g && typeof g.isVN === 'boolean') _isVN = g.isVN;
      if (x && x.result) _usdRate = x.result;
      try { updatePriceDisplay(); } catch (e) {}
    });
    let pollingInterval = null;
    let countdownInterval = null;
    let paymentPopup = null;
    let popupCheckInterval = null;

    function fmtK(v) { return (v / 1000).toLocaleString('vi-VN') + 'k'; }
    function fmtVND(v) { return v.toLocaleString('vi-VN') + '₫'; }
    function curOf(plan) { return _isVN ? prices[plan] : USD_PRICES[plan]; }
    function curBaseOf(plan) { return _isVN ? BASE_PRICES[plan] : USD_PRICES[plan]; }
    function fmtCur(n) { return _isVN ? fmtVND(n) : ('$' + n.toLocaleString('en-US')); }
    function fmtCurK(n) { return _isVN ? fmtK(n) : ('$' + n.toLocaleString('en-US')); }
    function calcSaveVsDaily(plan) {
      const dailyRate = curOf('daily');
      const days = PLAN_DAYS[plan];
      const perDay = curOf(plan) / days;
      if (perDay >= dailyRate) return 0;
      return Math.round((1 - perDay / dailyRate) * 100);
    }

    async function loadPricing() {
      try {
        const res = await fetch('/api/admin/pricing');
        const data = await res.json();
        if (data.success && data.data) {
          const p = data.data;
          if (p.promo && p.promo.enabled) {
            promoEnabled = true;
            promoPrices = {
              daily: p.promo.daily || BASE_PRICES.daily,
              weekly: p.promo.weekly || BASE_PRICES.weekly,
              monthly: p.promo.monthly || BASE_PRICES.monthly,
              yearly: p.promo.yearly || BASE_PRICES.yearly
            };
            prices = { ...promoPrices };
            promoLimits = p.promoLimits || {};
            if (p.promoLimits && token) {
              try {
                const uRes = await fetch('/api/payments/my-promo-usage', { headers: { 'Authorization': 'Bearer ' + token } });
                const uData = await uRes.json();
                if (uData.success && uData.usage) {
                  promoUsage = uData.usage;
                  Object.keys(BASE_PRICES).forEach(plan => {
                    const limit = promoLimits[plan];
                    if (limit && limit > 0 && (promoUsage[plan] || 0) >= limit) {
                      prices[plan] = BASE_PRICES[plan];
                    }
                  });
                }
              } catch (e) {}
            }
          }
        }
      } catch (e) {}
      updatePriceDisplay();
    }

    function updatePriceDisplay() {
      Object.keys(BASE_PRICES).forEach(plan => {
        const el = document.getElementById('price-' + plan);
        if (el) el.textContent = fmtCurK(curOf(plan));
        const card = document.getElementById('card-' + plan);
        if (card) {
          const oldOrig = card.querySelector('.plan-original'); if (oldOrig) oldOrig.remove();
          const oldTag  = card.querySelector('.plan-promo-tag'); if (oldTag)  oldTag.remove();
          if (_isVN && promoEnabled && prices[plan] < BASE_PRICES[plan]) {
            const pct = Math.round((1 - prices[plan] / BASE_PRICES[plan]) * 100);
            const priceRow = card.querySelector('.plan-price-row');
            if (priceRow) {
              const origEl = document.createElement('div');
              origEl.className = 'plan-original';
              origEl.textContent = fmtCurK(curBaseOf(plan));
              priceRow.parentNode.insertBefore(origEl, priceRow.nextSibling);
              const tagEl = document.createElement('div');
              tagEl.className = 'plan-promo-tag';
              tagEl.textContent = '-' + pct + '% SALE';
              priceRow.parentNode.insertBefore(tagEl, origEl.nextSibling);
            }
          }
        }
        const saveEl = document.getElementById('save-' + plan);
        if (saveEl && plan !== 'daily') {
          const pct = calcSaveVsDaily(plan);
          saveEl.textContent = pct > 0 ? ('Save ' + pct + '% vs daily') : '';
        }
        const pdEl = document.getElementById('perday-' + plan);
        if (pdEl && plan !== 'daily') {
          const per = curOf(plan) / PLAN_DAYS[plan];
          pdEl.textContent = _isVN ? ('≈ ' + Math.round(per).toLocaleString('vi-VN') + '₫ / day') : ('≈ $' + per.toFixed(2) + ' / day');
        }
      });
    }

    function svgIcon(name) {
      const icons = {
        qr: '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><line x1="14" y1="14" x2="14" y2="17"/><line x1="14" y1="20" x2="17" y2="20"/><line x1="17" y1="14" x2="17" y2="14.01"/><line x1="20" y1="17" x2="20" y2="17.01"/><line x1="20" y1="20" x2="20" y2="20.01"/></svg>',
        crypto: '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 8h6.5a2.5 2.5 0 010 5H8m0 0v3.5h6.5a2.5 2.5 0 010 5H8m2-13.5v15"/></svg>',
      };
      return icons[name] || '';
    }

    function subscribe(plan) {
      if (!ENABLED.includes(plan)) { alert('This plan is temporarily unavailable. Please choose another.'); return; }
      currentPlan = plan; currentQty = 1;
      currentPaymentMethod = _isVN ? (plan === 'daily' ? 'crypto' : 'qr') : 'card';
      renderSubscribeStep();
      document.getElementById('paymentOverlay').classList.add('show');
    }

    function renderSubscribeStep() {
      const modal = document.getElementById('paymentModal');
      const plan = currentPlan;
      const unitPrice = prices[plan];
      const promoPrice = promoPrices[plan] || BASE_PRICES[plan];
      const promoSave = promoEnabled && promoPrice < BASE_PRICES[plan] ? Math.round((1 - promoPrice / BASE_PRICES[plan]) * 100) : 0;
      const limit = promoLimits[plan];
      const used = promoUsage[plan] || 0;
      const remaining = (limit && limit > 0) ? Math.max(0, limit - used) : 0;

      let html = '';
      html += '<div class="pm-header"><h3>Plan ' + PLAN_NAMES[plan] + '</h3><button class="pm-close">&times;</button></div>';
      html += '<div class="pm-body">';
      html += '<div class="pm-amount-box"><div class="pm-amount-label">Unit price</div><div class="pm-amount-value">' + fmtCur(curOf(plan)) + '</div><div class="pm-amount-plan">/ ' + PLAN_UNITS[plan];
      if (promoSave > 0) html += ' <span class="pm-save-badge">-' + promoSave + '% KM</span>';
      html += '</div></div>';
      if (promoEnabled && limit && limit > 0 && promoSave > 0) {
        const cls = remaining > 0 ? '' : ' exhausted';
        html += '<div class="pm-promo-note' + cls + '">Promo left: ' + remaining + '/' + limit + '</div>';
      }
      html += '<div class="pm-section-label">Quantity ' + PLAN_UNITS[plan] + '</div>';
      html += '<div class="pm-qty-row">';
      html += '  <button class="pm-qty-btn" data-act="qty-dec">−</button>';
      html += '  <div class="pm-qty-val" id="modalQty">' + currentQty + '</div>';
      html += '  <button class="pm-qty-btn" data-act="qty-inc">+</button>';
      html += '</div>';
      html += '<div class="pm-summary" id="modalSummary">' + buildSummary() + '</div>';
      html += '<div class="pm-section-label">Payment method</div>';
      html += '<div class="pm-method-row">';
      if (plan !== 'daily' && _isVN) html += '  <button class="pm-method-btn' + (currentPaymentMethod === 'qr' ? ' active' : '') + '" id="methodQr" data-act="method-qr"><div class="pm-m-icon">' + svgIcon('qr') + '</div><div class="pm-m-label">QR Code</div><div class="pm-m-desc">Bank transfer</div></button>';
      html += '  <button class="pm-method-btn' + (currentPaymentMethod === 'card' ? ' active card' : '') + '" id="methodCard" data-act="method-card"><div class="pm-m-icon"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="5" width="20" height="14" rx="2"/><line x1="2" y1="10" x2="22" y2="10"/></svg></div><div class="pm-m-label">Card</div><div class="pm-m-desc">Visa · Mastercard</div></button>';
      html += '  <button class="pm-method-btn' + (currentPaymentMethod === 'crypto' ? ' active' : '') + '" id="methodCrypto" data-act="method-crypto"><div class="pm-m-icon">' + svgIcon('crypto') + '</div><div class="pm-m-label">Crypto</div><div class="pm-m-desc">BTC · ETH · USDT</div></button>';
      html += '</div>';
      html += '<button class="pm-confirm-btn" id="confirmPayBtn" data-act="confirm">Confirm payment</button>';
      html += '<button class="pm-cancel" data-act="close">Cancel</button>';
      html += '</div>';
      modal.innerHTML = html;
      bindModalActions();
    }

    function bindModalActions() {
      const modal = document.getElementById('paymentModal');
      if (!modal) return;
      modal.querySelectorAll('[data-act]').forEach(btn => {
        const act = btn.getAttribute('data-act');
        btn.onclick = () => {
          if (act === 'close') closePayment();
          else if (act === 'qty-dec') changeQty(-1);
          else if (act === 'qty-inc') changeQty(1);
          else if (act === 'method-qr') selectPaymentMethod('qr');
          else if (act === 'method-crypto') selectPaymentMethod('crypto');
          else if (act === 'method-card') selectPaymentMethod('card');
          else if (act === 'confirm') confirmPayment();
          else if (act === 'reopen-qr') reopenPopup();
          else if (act === 'reopen-crypto') reopenCryptoPopup();
        };
      });
      const close = modal.querySelector('.pm-close');
      if (close) close.onclick = closePayment;
    }

    function selectPaymentMethod(method) {
      currentPaymentMethod = method;
      const qrBtn = document.getElementById('methodQr');
      const cryptoBtn = document.getElementById('methodCrypto');
      const cardBtn = document.getElementById('methodCard');
      const confirmBtn = document.getElementById('confirmPayBtn');
      [qrBtn, cryptoBtn, cardBtn].forEach(b => b && b.classList.remove('active', 'crypto', 'card'));
      if (method === 'qr') {
        qrBtn && qrBtn.classList.add('active');
        if (confirmBtn) { confirmBtn.style.background = ''; confirmBtn.style.borderColor = ''; confirmBtn.style.boxShadow = ''; }
      } else if (method === 'card') {
        cardBtn && cardBtn.classList.add('active', 'card');
        if (confirmBtn) {
          confirmBtn.style.background = 'linear-gradient(135deg, #5aa9ff, #2f7ff0)';
          confirmBtn.style.borderColor = '#7bb8ff';
          confirmBtn.style.boxShadow = '0 12px 30px -8px rgba(47,127,240,0.55), 0 0 22px -6px #3a8dff, inset 0 1px 0 rgba(255,255,255,0.45)';
        }
      } else {
        cryptoBtn && cryptoBtn.classList.add('active', 'crypto');
        if (confirmBtn) {
          confirmBtn.style.background = 'linear-gradient(135deg, color-mix(in srgb, var(--acc-warn) 92%, white), var(--acc-warn))';
          confirmBtn.style.borderColor = 'color-mix(in srgb, var(--acc-warn) 70%, white)';
          confirmBtn.style.boxShadow = '0 12px 30px -8px color-mix(in srgb, var(--acc-warn) 65%, transparent), 0 0 22px -6px var(--acc-warn), inset 0 1px 0 rgba(255,255,255,0.45)';
        }
      }
    }

    function changeQty(delta) {
      currentQty = Math.max(1, Math.min(365, currentQty + delta));
      const el = document.getElementById('modalQty'); if (el) el.textContent = currentQty;
      const sumEl = document.getElementById('modalSummary'); if (sumEl) sumEl.innerHTML = buildSummary();
    }

    function calcTotalWithPromo(plan, qty) {
      const limit = promoLimits[plan];
      const used = promoUsage[plan] || 0;
      const promoPrice = promoPrices[plan] || BASE_PRICES[plan];
      const basePrice = BASE_PRICES[plan];
      if (!promoEnabled || promoPrice >= basePrice || !limit || limit <= 0) {
        return { total: prices[plan] * qty, promoQty: 0, baseQty: qty };
      }
      const remaining = Math.max(0, limit - used);
      const promoQty = Math.min(qty, remaining);
      const baseQty = qty - promoQty;
      return { total: promoPrice * promoQty + basePrice * baseQty, promoQty, baseQty };
    }

    function buildSummary() {
      if (!_isVN) {
        const u = USD_PRICES[currentPlan];
        let h = '<div class="row"><span>Plan: ' + PLAN_NAMES[currentPlan] + ' × ' + currentQty + '</span><span>$' + u.toLocaleString('en-US') + ' × ' + currentQty + '</span></div>';
        h += '<div class="row total"><span>Total</span><span>$' + (u * currentQty).toLocaleString('en-US') + '</span></div>';
        return h;
      }
      const calc = calcTotalWithPromo(currentPlan, currentQty);
      const total = calc.total;
      const baseTotal = BASE_PRICES[currentPlan] * currentQty;
      const save = promoEnabled && total < baseTotal ? Math.round((1 - total / baseTotal) * 100) : 0;
      let html = '';
      if (calc.promoQty > 0 && calc.baseQty > 0) {
        const promoPrice = promoPrices[currentPlan] || prices[currentPlan];
        html += '<div class="row"><span>Promo: ' + PLAN_NAMES[currentPlan] + ' × ' + calc.promoQty + '</span><span>' + fmtVND(promoPrice) + ' × ' + calc.promoQty + '</span></div>';
        html += '<div class="row"><span>Plan: ' + PLAN_NAMES[currentPlan] + ' × ' + calc.baseQty + '</span><span>' + fmtVND(BASE_PRICES[currentPlan]) + ' × ' + calc.baseQty + '</span></div>';
      } else {
        const unit = calc.promoQty > 0 ? (promoPrices[currentPlan] || prices[currentPlan]) : prices[currentPlan];
        html += '<div class="row"><span>Plan: ' + PLAN_NAMES[currentPlan] + ' × ' + currentQty + '</span><span>' + fmtVND(unit) + ' × ' + currentQty + '</span></div>';
      }
      if (save > 0) html += '<div class="row"><span>List price</span><span style="text-decoration:line-through;color:rgba(132,148,176,0.6)">' + fmtVND(baseTotal) + '</span></div>';
      html += '<div class="row total"><span>Total</span><span>' + fmtVND(total);
      if (save > 0) html += ' <span class="pm-save-badge">-' + save + '%</span>';
      html += '</span></div>';
      return html;
    }

    async function confirmPayment() {
      if (!token) { alert('Please log in to pay!'); return; }
      if (currentPaymentMethod === 'card') return confirmCardPayment();
      if (currentPaymentMethod === 'crypto') return confirmCryptoPayment();
      return confirmQrPayment();
    }

    async function confirmQrPayment() {
      const modal = document.getElementById('paymentModal');
      modal.innerHTML = '<div class="pm-header"><h3>Payment</h3><button class="pm-close" data-act="close">&times;</button></div><div class="pm-body"><div class="pm-loading"><div class="pm-spinner"></div><div>Creating order...</div></div></div>';
      bindModalActions();
      try {
        const res = await fetch('/api/payments/create-order', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
          body: JSON.stringify({ plan: currentPlan, quantity: currentQty })
        });
        const data = await res.json();
        if (!data.success) throw new Error(data.error);
        currentOrder = data.order;
        currentOrder.planDesc = PLAN_NAMES[currentPlan] + ' × ' + currentQty;

        const w = 520, h = 700;
        const left = (screen.width - w) / 2, top = (screen.height - h) / 2;
        paymentPopup = window.open('about:blank', 'sepay_checkout', `width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`);

        const form = document.createElement('form');
        form.method = 'POST'; form.action = data.order.checkoutUrl; form.target = 'sepay_checkout'; form.style.display = 'none';
        Object.entries(data.order.formFields).forEach(([k, v]) => {
          const input = document.createElement('input'); input.type = 'hidden'; input.name = k; input.value = v; form.appendChild(input);
        });
        document.body.appendChild(form); form.submit(); document.body.removeChild(form);

        renderWaitingPayment();
        startPolling(data.order.orderCode);
        startCountdown(data.order.expiresAt);

        popupCheckInterval = setInterval(() => {
          if (paymentPopup && paymentPopup.closed) {
            clearInterval(popupCheckInterval); popupCheckInterval = null; paymentPopup = null;
          }
        }, 500);
      } catch (err) {
        renderModalError(err.message || 'An error occurred');
      }
    }

    function renderWaitingPayment() {
      const o = currentOrder;
      const modal = document.getElementById('paymentModal');
      modal.innerHTML = `
        <div class="pm-header"><h3>Awaiting payment</h3><button class="pm-close" data-act="close">&times;</button></div>
        <div class="pm-body">
          <div class="pm-amount-box"><div class="pm-amount-label">Amount due</div><div class="pm-amount-value">${o.amount.toLocaleString()}₫</div><div class="pm-amount-plan">${o.planDesc}</div></div>
          <div style="text-align:center;margin:18px 0"><div class="pm-spinner"></div>
            <div style="font-size:14px;color:var(--fg);font-weight:600;margin-bottom:4px">Please complete the payment</div>
            <div style="font-size:13px;color:var(--fg-muted);line-height:1.5">The SePay payment window has opened.<br>Complete the payment to continue.</div>
          </div>
          <button class="pm-reopen" data-act="reopen-qr">Reopen payment window</button>
          <div class="pm-order-info">Order: ${o.orderCode}</div>
          <div class="pm-timer">Expires in <span class="time" id="countdown">15:00</span></div>
          <button class="pm-cancel" data-act="close">Cancel payment</button>
        </div>`;
      bindModalActions();
    }

    function reopenPopup() {
      if (paymentPopup && !paymentPopup.closed) { paymentPopup.focus(); return; }
      if (!currentOrder) return;
      const w = 520, h = 700;
      const left = (screen.width - w) / 2, top = (screen.height - h) / 2;
      paymentPopup = window.open('about:blank', 'sepay_checkout', `width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`);
      const form = document.createElement('form');
      form.method = 'POST'; form.action = currentOrder.checkoutUrl; form.target = 'sepay_checkout'; form.style.display = 'none';
      Object.entries(currentOrder.formFields).forEach(([k, v]) => {
        const input = document.createElement('input'); input.type = 'hidden'; input.name = k; input.value = v; form.appendChild(input);
      });
      document.body.appendChild(form); form.submit(); document.body.removeChild(form);
    }

    async function confirmCardPayment() {
      const token = localStorage.getItem('fm_token');
      const btn = document.getElementById('confirmPayBtn');
      if (btn) { btn.disabled = true; btn.textContent = 'Redirecting to card payment...'; }
      try {
        const r = await fetch('/api/payments/create-card-checkout', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
          body: JSON.stringify({ plan: currentPlan, quantity: currentQty })
        });
        const d = await r.json();
        if (d && d.success && d.url) { window.location.href = d.url; return; }
        alert((d && d.error) || 'Could not start card payment');
      } catch (e) { alert('Network error: ' + e.message); }
      if (btn) { btn.disabled = false; btn.textContent = 'Confirm payment'; }
    }

    async function confirmCryptoPayment() {
      const modal = document.getElementById('paymentModal');
      modal.innerHTML = '<div class="pm-header"><h3>Crypto</h3><button class="pm-close" data-act="close">&times;</button></div><div class="pm-body"><div class="pm-loading"><div class="pm-spinner" style="border-top-color:var(--acc-warn);filter:drop-shadow(0 0 8px color-mix(in srgb, var(--acc-warn) 45%, transparent))"></div><div>Creating crypto order...</div></div></div>';
      bindModalActions();
      try {
        const res = await fetch('/api/payments/create-crypto-order', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
          body: JSON.stringify({ plan: currentPlan, quantity: currentQty })
        });
        const data = await res.json();
        if (!data.success) throw new Error(data.error);
        currentOrder = data.order;
        currentOrder.planDesc = PLAN_NAMES[currentPlan] + ' × ' + currentQty;

        const w = 520, h = 700;
        const left = (screen.width - w) / 2, top = (screen.height - h) / 2;
        paymentPopup = window.open(data.order.invoiceUrl, 'crypto_checkout', `width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`);

        renderCryptoWaiting();
        startPolling(data.order.orderCode);
        startCountdown(data.order.expiresAt);
        popupCheckInterval = setInterval(() => {
          if (paymentPopup && paymentPopup.closed) {
            clearInterval(popupCheckInterval); popupCheckInterval = null; paymentPopup = null;
          }
        }, 500);
      } catch (err) {
        renderModalError(err.message || 'An error occurred');
      }
    }

    function renderCryptoWaiting() {
      const o = currentOrder;
      const modal = document.getElementById('paymentModal');
      modal.innerHTML = `
        <div class="pm-header"><h3>Awaiting crypto payment</h3><button class="pm-close" data-act="close">&times;</button></div>
        <div class="pm-body">
          <div class="pm-amount-box" style="border-color:color-mix(in srgb, var(--acc-warn) 35%, transparent)"><div class="pm-amount-label">Amount</div><div class="pm-amount-value" style="color:var(--acc-warn);text-shadow:0 0 28px color-mix(in srgb, var(--acc-warn) 50%, transparent)">$${o.amountUSD}</div><div class="pm-amount-plan">${o.planDesc} (${o.amount.toLocaleString()}₫)</div></div>
          <div style="text-align:center;margin:18px 0"><div class="pm-spinner" style="border-top-color:var(--acc-warn);filter:drop-shadow(0 0 8px color-mix(in srgb, var(--acc-warn) 45%, transparent))"></div>
            <div style="font-size:14px;color:var(--fg);font-weight:600;margin-bottom:4px">Please complete the payment</div>
            <div style="font-size:13px;color:var(--fg-muted);line-height:1.5">The NOWPayments window has opened.<br>Pick a coin and complete the payment.</div>
          </div>
          <button class="pm-reopen" style="border-color:color-mix(in srgb, var(--acc-warn) 40%, transparent)" data-act="reopen-crypto">Reopen payment window</button>
          <div class="pm-order-info">Order: ${o.orderCode}</div>
          <div class="pm-timer">Expires in <span class="time" id="countdown">15:00</span></div>
          <button class="pm-cancel" data-act="close">Cancel payment</button>
        </div>`;
      bindModalActions();
    }

    function reopenCryptoPopup() {
      if (paymentPopup && !paymentPopup.closed) { paymentPopup.focus(); return; }
      if (currentOrder && currentOrder.invoiceUrl) {
        const w = 520, h = 700;
        const left = (screen.width - w) / 2, top = (screen.height - h) / 2;
        paymentPopup = window.open(currentOrder.invoiceUrl, 'crypto_checkout', `width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`);
      }
    }

    function startPolling(orderCode) {
      if (pollingInterval) clearInterval(pollingInterval);
      pollingInterval = setInterval(async () => {
        try {
          const res = await fetch('/api/payments/order-status/' + orderCode, { headers: { 'Authorization': 'Bearer ' + token } });
          const data = await res.json();
          if (data.status === 'paid') { cleanup(); renderSuccess(data.order); }
          else if (data.status === 'expired') { cleanup(); renderExpired(); }
        } catch (e) {}
      }, 2000);
    }
    function startCountdown(expiresAt) {
      if (countdownInterval) clearInterval(countdownInterval);
      const expires = new Date(expiresAt).getTime();
      countdownInterval = setInterval(() => {
        const diff = expires - Date.now();
        if (diff <= 0) { clearInterval(countdownInterval); const el = document.getElementById('countdown'); if (el) el.textContent = '00:00'; return; }
        const m = Math.floor(diff / 60000), s = Math.floor((diff % 60000) / 1000);
        const el = document.getElementById('countdown');
        if (el) el.textContent = String(m).padStart(2,'0') + ':' + String(s).padStart(2,'0');
      }, 1000);
    }
    function renderSuccess() {
      document.getElementById('paymentModal').innerHTML = `
        <div class="pm-success">
          <div class="pm-success-icon"><svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></div>
          <h2>Payment successful!</h2>
          <p>Account upgraded: <strong>${currentOrder ? currentOrder.planDesc : 'Pro'}</strong></p>
          <button class="pm-success-btn" data-act="close">Close</button>
        </div>`;
      bindModalActions();
    }
    function renderExpired() {
      document.getElementById('paymentModal').innerHTML = `
        <div class="pm-error">
          <div class="pm-error-icon"><svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg></div>
          <h3>Order expired</h3>
          <p>Please create a new order to continue.</p>
          <button class="pm-cancel" data-act="close" style="max-width:200px;margin:0 auto">Close</button>
        </div>`;
      bindModalActions();
    }
    function renderModalError(msg) {
      document.querySelector('.pm-body').innerHTML = `
        <div class="pm-error">
          <div class="pm-error-icon"><svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg></div>
          <h3>An error occurred</h3>
          <p>${msg}</p>
          <button class="pm-cancel" data-act="close" style="max-width:200px;margin:0 auto">Close</button>
        </div>`;
      bindModalActions();
    }
    function cleanup() {
      if (pollingInterval) clearInterval(pollingInterval); pollingInterval = null;
      if (countdownInterval) clearInterval(countdownInterval); countdownInterval = null;
      if (popupCheckInterval) clearInterval(popupCheckInterval); popupCheckInterval = null;
      if (paymentPopup && !paymentPopup.closed) { try { paymentPopup.close(); } catch(e) {} }
      paymentPopup = null;
    }
    function closePayment() { cleanup(); currentOrder = null; const ov = document.getElementById('paymentOverlay'); if (ov) ov.classList.remove('show'); }

    // expose for PlanCard onSubscribe
    window.__fm_subscribe = subscribe;

    // BroadcastChannel listener
    let bcRef = null;
    try {
      bcRef = new BroadcastChannel('fm_payment');
      bcRef.onmessage = (e) => {
        if (e.data && e.data.type === 'payment_success' && currentOrder && e.data.orderCode === currentOrder.orderCode) {
          cleanup();
          currentOrder.status = 'paid'; currentOrder.paidAt = new Date().toISOString();
          renderSuccess();
        }
      };
    } catch (e) {}

    // Click outside overlay to close
    const ov = document.getElementById('paymentOverlay');
    const ovClick = (e) => { if (e.target === ov) closePayment(); };
    if (ov) ov.addEventListener('click', ovClick);
    const keydown = (e) => { if (e.key === 'Escape') { closePayment(); closeSalePopup(); } };
    document.addEventListener('keydown', keydown);

    // FAQ toggle (delegated)
    const onFaqClick = (e) => {
      const q = e.target.closest('.faq-question');
      if (!q) return;
      q.parentElement.classList.toggle('open');
    };
    document.addEventListener('click', onFaqClick);

    // Sale popup
    function closeSalePopup() {
      const el = document.getElementById('salePopup'); if (el) el.classList.remove('show');
      try { sessionStorage.setItem('fm_sale_popup_closed', '1'); } catch(e) {}
    }
    window.__fm_closeSalePopup = closeSalePopup;
    (async () => {
      try {
        if (sessionStorage.getItem('fm_sale_popup_closed')) return;
      } catch(e) {}
      try {
        const res = await fetch('/api/admin/popup-payment');
        const data = await res.json();
        if (data.success && data.data && data.data.enabled) {
          const p = data.data;
          if (p.imageUrl) { const img = document.getElementById('salePopupImg'); if (img) { img.src = p.imageUrl; img.style.display = 'block'; } }
          const t = document.getElementById('salePopupTitle'); if (t) t.textContent = p.title || 'Promotion';
          const c = document.getElementById('salePopupText'); if (c) c.textContent = p.content || '';
          const sp = document.getElementById('salePopup'); if (sp) sp.classList.add('show');
        }
      } catch(e) {}
    })();

    async function checkPlan() {
      if (!token) return;
      try {
        const res = await fetch('/api/auth/me', { headers: { 'Authorization': 'Bearer ' + token } });
        const data = await res.json();
        if (data.success && data.user) {
          const role = data.user.role;
          if (role === 'paid' || role === 'admin') {
            const btn = document.getElementById('freeBtn');
            if (btn) { btn.textContent = 'Free Plan'; btn.classList.remove('disabled'); }
          }
        }
      } catch(e) {}
    }

    loadPricing();
    checkPlan();

    return () => {
      cleanup();
      if (bcRef) try { bcRef.close(); } catch(e) {}
      if (ov) ov.removeEventListener('click', ovClick);
      document.removeEventListener('keydown', keydown);
      document.removeEventListener('click', onFaqClick);
      delete window.__fm_subscribe;
      delete window.__fm_closeSalePopup;
      initialized.current = false;
    };
  }, []);

  const handleSubscribe = (planId) => {
    if (window.__fm_subscribe) window.__fm_subscribe(planId);
  };

  return (
    <div className="sub-shell">
      <div className="sub-hero">
        <div className="sub-hero-tag">Subscription · Tier Selection</div>
        <h1>Unlock the full <span className="acc">surebet engine</span></h1>
        <p>Real-time arbitrage feed, smart-bet alerts, matched pairs view and a full analytics toolkit for every major bookmaker. Choose the plan that fits your trading volume.</p>
      </div>

      <div className="plans-grid">
        {PLAN_DEFS.map(p => <PlanCard key={p.id} plan={p} onSubscribe={handleSubscribe} />)}
      </div>

      <div className="pay-row">
        <div className="pay-row-label">Secure Payment Methods</div>
        <div className="pay-row-methods">
          <span className="pay-method">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/></svg>
            SePay QR Bank Transfer
          </span>
          <span className="pay-method">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9 9h6v6H9z"/></svg>
            Crypto (BTC · ETH · USDT)
          </span>
          <span className="pay-method">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 1l3 6 7 1-5 5 1 7-6-3-6 3 1-7-5-5 7-1z"/></svg>
            End-to-end encrypted
          </span>
        </div>
      </div>

      <div className="faq-wrap">
        <div className="faq-head">
          <div>
            <h2>Frequently asked questions</h2>
            <p>Still have questions? Message the admin in the Telegram group.</p>
          </div>
        </div>
        <div className="faq-list">
          {[
            { q: 'What is a surebet?', a: 'A surebet (or arbitrage bet) is a betting strategy where you place bets on all possible outcomes of an event at different bookmakers, guaranteeing a profit regardless of the result.' },
            { q: 'Can I cancel anytime?', a: 'Yes — your subscription is per-period and does not auto-renew. Access continues until the end of the billing period you paid for.' },
            { q: 'How does payment work?', a: "Click Subscribe, choose quantity, then confirm. You'll be redirected to SePay's secure payment page for bank transfer via QR Code, or to NOWPayments for crypto. After payment, your account is upgraded automatically." },
            { q: 'Which bookmakers are supported?', a: 'All major operators including 1xBet, Parimatch, Pinnacle, BetMGM, DraftKings, FanDuel, Stake, Polymarket and many more. Full 2-way surebets + matched pairs view.' },
          ].map((f, i) => (
            <div className="faq-item" key={i}>
              <div className="faq-question">{f.q} <span className="faq-q-icon">+</span></div>
              <div className="faq-answer">{f.a}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { SubscriptionView });
