// calc-app.jsx — shell + the live purchase flow.
// hero → quote (build / budget) → "Make this video":
//   • anonymous  → signup gate → real /login?next=/calculator
//   • signed-in  → POST /api/calculator/create-checkout → hosted Stripe redirect
// Stripe success_url returns to /calculator?purchase=<session> → poll purchase-status
// → render fires server-side (webhook). Stripe is in TEST mode here (no real money).

const CALC_TWEAK_DEFAULTS = {
  stage: "hero",
  returningBuyer: true,
  avatar: "twin",
  length: "60s",
  cinematic: false,
  margin: 3,
  quoteMode: "build",
};

function App() {
  const [t, setTweak] = useTweaks(CALC_TWEAK_DEFAULTS);

  const [sel, setSel] = React.useState({
    avatar: t.avatar,
    length: t.length,
    style: t.cinematic ? 'cinematic' : 'talking',
    voice: t.avatar === 'twin' ? 'cloned' : 'stock',
    music: false,
    script: '',
  });
  const set = (patch) => setSel((s) => ({ ...s, ...patch }));

  const [modal, setModal] = React.useState(null); // null | 'gate' | 'upsell'
  const [budget, setBudget] = React.useState(30);
  const [purchase, setPurchase] = React.useState(null); // {session_id, status, video_id}

  const effectiveSel = t.quoteMode === 'budget'
    ? { ...window.optimizeForBudget(budget, t.margin).sel, script: sel.script }
    : sel;
  React.useEffect(() => {
    if (t.quoteMode === 'budget') setSel((s) => ({ ...window.optimizeForBudget(budget, t.margin).sel, script: s.script }));
  }, [t.quoteMode, budget, t.margin]);

  // Stripe return: /calculator?purchase=<session> → land on the "rendering" screen + poll.
  React.useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const sess = params.get('purchase');
    if (sess) { setTweak('stage', 'done'); setPurchase({ session_id: sess, status: 'paid' }); }
  }, []);

  // Auto-resume after login: an anonymous "Make this video" stashes the selection and
  // sends the visitor to /login; on return we re-attempt checkout automatically — a 401
  // means still-anonymous (no-op, normal page), a {url} means now-authed → straight to Stripe.
  const [resuming, setResuming] = React.useState(false);
  React.useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    if (params.get('purchase')) return;                 // Stripe-return flow, not a resume
    let stored = null;
    try { stored = JSON.parse(localStorage.getItem('calc_resume') || 'null'); } catch (e) {}
    if (!stored || !stored.sel) return;
    if (Date.now() - (stored.ts || 0) > 15 * 60 * 1000) { localStorage.removeItem('calc_resume'); return; }
    setResuming(true);
    (async () => {
      try {
        const r = await fetch('/api/calculator/create-checkout', {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ selection: stored.sel }),
        });
        if (r.status === 401) { setResuming(false); return; }   // still anonymous → leave page normal
        const d = await r.json();
        if (d.url) { localStorage.removeItem('calc_resume'); window.location.href = d.url; return; }
        localStorage.removeItem('calc_resume'); setResuming(false);
      } catch (e) { setResuming(false); }
    })();
  }, []);

  React.useEffect(() => {
    if (!purchase || !purchase.session_id) return;
    if (purchase.status === 'ready' || purchase.status === 'render_failed') return;
    const iv = setInterval(async () => {
      try {
        const r = await fetch('/api/calculator/purchase-status?session_id=' + encodeURIComponent(purchase.session_id));
        if (r.ok) { const d = await r.json(); setPurchase((p) => ({ ...p, status: d.status, video_id: d.video_id })); }
      } catch (e) { /* keep polling */ }
    }, 4000);
    return () => clearInterval(iv);
  }, [purchase]);

  const v30 = window.quotePrice({ avatar: 'ready', length: '30s', style: 'talking', voice: 'stock', music: false }, t.margin).render;
  const priorHistory = t.returningBuyer ? [v30, v30] : [];

  const stage = t.stage; // 'hero' | 'quote' | 'done'
  const goQuote = () => { setTweak('stage', 'quote'); setModal(null); window.scrollTo({ top: 0, behavior: 'smooth' }); };

  // "Make this video" — auth-aware live checkout.
  const onBuy = async () => {
    try {
      const r = await fetch('/api/calculator/create-checkout', {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ selection: effectiveSel }),
      });
      if (r.status === 401) {                                    // anonymous → stash selection, show gate
        try { localStorage.setItem('calc_resume', JSON.stringify({ sel: effectiveSel, ts: Date.now() })); } catch (e) {}
        setModal('gate'); return;
      }
      const d = await r.json();
      if (d.url) { window.location.href = d.url; return; }       // signed-in → Stripe
      setModal('gate');
    } catch (e) { setModal('gate'); }
  };
  // The gate's CTA → the real login/signup wall, returning to the calculator.
  const goLogin = () => { window.location.href = '/login?next=/calculator'; };

  const sampleSel = { avatar: 'twin', length: '60s', style: 'talking', voice: 'cloned', music: false, script: '' };
  const purchaseHistory = [...priorHistory, window.quotePrice(effectiveSel, t.margin).render];

  const renderStatus = purchase ? purchase.status : null;
  const failed = renderStatus === 'render_failed';

  if (resuming) {
    return (
      <div className="calc-root" style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <div style={{ textAlign: 'center', color: 'var(--muted)' }}>
          <div style={{ fontSize: '1.4rem', fontWeight: 900, color: 'var(--ink)', marginBottom: 8 }}>Taking you to checkout…</div>
          <div>Picking up where you left off.</div>
        </div>
      </div>
    );
  }

  return (
    <div className="calc-root">
      <CalcNav onStart={goQuote} />

      {stage === 'hero' ? (
        <Hero onStart={goQuote} sampleSel={sampleSel} margin={t.margin} />
      ) : stage === 'done' ? (
        <div className="calc-wrap" style={{ padding: '70px 28px 90px', textAlign: 'center' }}>
          <span style={{ width: 64, height: 64, borderRadius: 18, background: failed ? 'rgba(224,106,90,.12)' : 'rgba(141,198,63,.12)', border: '1px solid var(--line)', color: failed ? 'var(--danger)' : 'var(--lime)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.9rem', marginBottom: 20 }}><i className={'ti ti-' + (failed ? 'info' : 'circle-check')}></i></span>
          <h2 style={{ fontSize: '2rem', marginBottom: 12 }}>{failed ? "We hit a snag" : "Your video is being made"}</h2>
          <p style={{ color: 'var(--muted)', fontSize: '1.08rem', maxWidth: '46ch', margin: '0 auto 26px' }}>
            {failed
              ? "Your payment went through but the render didn't start. We've been alerted and will sort it — you won't be charged again."
              : "Payment received. It'll be ready in a few minutes — we'll email you, and it'll be waiting in your account."}
          </p>
          <div style={{ display: 'flex', gap: 14, justifyContent: 'center' }}>
            <a className="calc-btn calc-btn-primary calc-btn-lg" href="/videos"><i className="ti ti-play"></i>See it in My Videos</a>
            {purchaseHistory.length >= 3 ? <button className="calc-btn calc-btn-ghost calc-btn-lg" onClick={() => setModal('upsell')}><i className="ti ti-trending"></i>See subscription value</button> : null}
          </div>
        </div>
      ) : (
        <QuoteFlow sel={effectiveSel} set={set} onBuy={onBuy} margin={t.margin}
          mode={t.quoteMode} setMode={(m) => setTweak('quoteMode', m)} budget={budget} setBudget={setBudget} />
      )}

      <CalcFooter />

      {modal === 'gate' ? <SignupGate sel={effectiveSel} onClose={() => setModal(null)} onSignup={goLogin} margin={t.margin} /> : null}
      {modal === 'upsell' ? <UpsellCompare history={purchaseHistory} onClose={() => setModal(null)} onSubscribe={() => { window.location.href = '/pricing'; }} /> : null}
    </div>
  );
}

function CalcFooter() {
  return (
    <div className="calc-footer">
      <div className="calc-wrap calc-footer-inner">
        <div className="calc-logo" style={{ fontSize: '1rem' }}><span className="mark"></span>MyAvatar</div>
        <div className="fnote">One-off videos · <b>no subscription required</b> · prices exclude VAT, added at checkout for your country.</div>
        <div className="fnote">© MyAvatar</div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
