/* The analysis page: what the Lojo engine understands about an
   organization after its questionnaire, graded; the gaps, with what each
   would change; and each module's free insights with the rest locked
   until that module is bought. /app/?analysis=<inquiry id>. No account:
   the email on the request is the key, kept in sessionStorage. */

const GRADE_TONE = { A: 'good', B: 'accent', C: 'warn', D: 'warn', '-': 'fg-subtle' };
const GRADE_LABEL = { A: 'A · you provided it', B: 'B · your own public sources', C: 'C · third-party public sources', D: 'D · Lojo estimate', '-': 'not attempted' };

function Grade({ g, long }) {
  const t = GRADE_TONE[g] || 'fg-subtle';
  return <span className="mono" title={GRADE_LABEL[g] || g} style={{ fontSize: 10.5, padding: '2px 7px', borderRadius: 999, whiteSpace: 'nowrap',
    border: '1px solid color-mix(in oklab, var(--' + t + ') 45%, transparent)', color: `var(--${t})` }}>{long ? (GRADE_LABEL[g] || g) : (g === '-' ? 'not attempted' : 'grade ' + g)}</span>;
}

function emailKey(id) { return 'lojo.inquiry.' + id; }
function readEmail(id) { try { return sessionStorage.getItem(emailKey(id)) || localStorage.getItem(emailKey(id)) || ''; } catch (e) { return ''; } }
function writeEmail(id, email) { try { sessionStorage.setItem(emailKey(id), email); localStorage.setItem(emailKey(id), email); } catch (e) { /* fine */ } }

function AnalysisPage({ id }) {
  const params = new URLSearchParams(window.location.search);
  const [email, setEmail] = React.useState(readEmail(id));
  const [draft, setDraft] = React.useState('');
  const [inq, setInq] = React.useState(null);
  const [a, setA] = React.useState(null);
  const [pay, setPay] = React.useState(null);
  const [stale, setStale] = React.useState(false);
  const [phase, setPhase] = React.useState(email ? 'loading' : 'email');
  const [error, setError] = React.useState('');
  const [flash, setFlash] = React.useState('');
  const [elapsed, setElapsed] = React.useState(0);
  const [more, setMore] = React.useState(false);
  const [opts, setOpts] = React.useState(null);

  const fetchAnalysis = React.useCallback(async () => {
    const d = await lojo('', { module: 'inquiry', action: 'analysis', id, email });
    if (!d.ok) { setError(d.status === 403 ? 'That email does not match this request.' : (d.message || 'Could not open the analysis.')); setPhase(d.status === 403 ? 'email' : 'error'); return null; }
    setInq(d.inquiry); setA(d.analysis); setPay(d.pay); setStale(!!d.stale);
    return d;
  }, [id, email]);

  const runAnalysis = React.useCallback(async (force) => {
    setPhase('running'); setError(''); setElapsed(0);
    const t0 = Date.now();
    const tick = setInterval(() => setElapsed(Math.round((Date.now() - t0) / 1000)), 1000);
    const d = await lojo('', { module: 'inquiry', action: 'analyze', id, email, force: !!force });
    clearInterval(tick);
    if (!d.ok) { setError(d.message || 'The analysis did not run.'); setPhase('error'); return; }
    setInq(d.inquiry); setA(d.analysis); setStale(false);
    const again = await lojo('', { module: 'inquiry', action: 'analysis', id, email });
    if (again.ok) { setPay(again.pay); setStale(!!again.stale); }
    setPhase(d.analysis.status === 'ready' ? 'ready' : (d.inquiry.analysis.status === 'not-applicable' ? 'na' : 'failed'));
  }, [id, email]);

  React.useEffect(() => {
    if (!email) return;
    (async () => {
      setPhase('loading');
      const paid = params.get('paid');
      if (paid) {
        const c = await lojo('', { module: 'inquiry', action: 'pay-confirm', id, email, session_id: paid });
        if (c.ok && c.paid) setFlash('Thank you. ' + (c.product ? c.product.replace('module_', '').replace(/^\w/, (x) => x.toUpperCase()) : 'The module') + ' is unlocked below. We will email within one business day to book your walkthrough.');
        try { window.history.replaceState({}, '', '/app/?analysis=' + id); } catch (e) { /* fine */ }
      }
      const d = await fetchAnalysis();
      if (!d) return;
      const st = d.inquiry.analysis && d.inquiry.analysis.status;
      if (st === 'ready') setPhase('ready');
      else if (st === 'running') { setPhase('running'); setTimeout(() => fetchAnalysis().then((x) => x && x.inquiry.analysis.status === 'ready' && setPhase('ready')), 8000); }
      else if (st === 'not-applicable') setPhase('na');
      else runAnalysis(false);
    })();
  }, [email]);
  React.useEffect(() => { lojo('', { module: 'inquiry', action: 'options' }).then((d) => d.ok && setOpts(d)); }, []);

  const shell = (children) => (
    <div className="wrap" style={{ maxWidth: 980, padding: '40px var(--s6) 100px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 22, gap: 12, flexWrap: 'wrap' }}>
        <a href="/" style={{ display: 'inline-flex' }}><Wordmark size={16} /></a>
        <div style={{ display: 'flex', gap: 14, fontSize: 13.5 }}><a href="/app/?demo=1" style={{ color: 'var(--fg-muted)' }}>Platform demo</a><a href="/app/?request=1" style={{ color: 'var(--accent)' }}>Talk to us</a></div>
      </div>
      {children}
    </div>);

  if (phase === 'email') return shell(
    <div style={{ maxWidth: 480 }}>
      <div className="overline" style={{ marginBottom: 8 }}>Your Lojo analysis</div>
      <h1 className="display" style={{ fontSize: 'clamp(26px,4vw,36px)', margin: '0 0 10px' }}>Open your analysis</h1>
      <p style={{ color: 'var(--fg-muted)', fontSize: 15, lineHeight: 1.6 }}>Enter the email you used on the request. Nothing is shown to anyone else.</p>
      {error && <div className="flash warn">{error}</div>}
      <Field label="Email on the request"><Input type="email" value={draft} onChange={(e) => setDraft(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter' && draft.includes('@')) { writeEmail(id, draft.trim().toLowerCase()); setEmail(draft.trim().toLowerCase()); } }} /></Field>
      <button className="btn btn-primary" disabled={!draft.includes('@')} onClick={() => { writeEmail(id, draft.trim().toLowerCase()); setError(''); setEmail(draft.trim().toLowerCase()); }}>Open</button>
    </div>);
  if (phase === 'loading' || !inq) return shell(<div style={{ color: 'var(--fg-subtle)', padding: '40px 0' }}>Loading…</div>);
  if (phase === 'error') return shell(<div className="flash warn">{error}</div>);

  const company = (inq.contact.company || inq.contact.name);
  const labelOf = (mid) => (opts && (opts.modules.find((m) => m.id === mid) || {}).label) || mid;
  const priceOf = (mid) => { const mp = pay && pay.module_prices; if (!mp) return null; const key = Object.keys(mp).find((k) => mp[k].module === mid); return key ? { product: key, ...mp[key] } : null; };
  const buy = async (mid) => {
    setError('');
    const d = await lojo('', { module: 'inquiry', action: 'checkout', id, email, module_id: mid, origin: window.location.origin });
    if (d.ok && d.url) { window.location.assign(d.url); return; }
    setError(d.message || (d.error === 'payments-off' ? 'Payments are not switched on yet; talk to us and we will unlock it after the call.' : 'Checkout did not start.'));
  };

  const head = (
    <div style={{ marginBottom: 22 }}>
      <div className="overline" style={{ marginBottom: 8 }}>Lojo analysis · {inq.modules.map(labelOf).join(' · ')}</div>
      <h1 className="display" style={{ fontSize: 'clamp(26px,4vw,40px)', margin: '0 0 10px' }}>What Lojo understands about {company}</h1>
      {flash && <div className="flash good">{flash}</div>}
      {error && <div className="flash warn">{error}</div>}
    </div>);

  if (phase === 'running') return shell(<div>{head}
    <div className="app-panel" style={{ maxWidth: 640 }}>
      <h3>Reading, researching, writing…</h3>
      <div style={{ fontSize: 14, color: 'var(--fg-muted)', lineHeight: 1.7 }}>
        Lojo is reading what you sent, fetching your own website, researching the public record where it helps, and writing the first analysis.
        Every fact gets an evidence grade; what cannot be known without you is listed as a gap, never guessed. This takes one to three minutes.
      </div>
      <div className="mono" style={{ marginTop: 12, fontSize: 12, color: 'var(--fg-subtle)' }}>{elapsed}s</div>
    </div></div>);
  if (phase === 'na') return shell(<div>{head}<div className="app-panel"><h3>No engine analysis for these modules</h3><div style={{ fontSize: 14, color: 'var(--fg-muted)', lineHeight: 1.6 }}>AI visibility is analysed by the free report on the home page; Execute is set up from Stack intelligence. Add a module to your request and the engine runs.</div>
    <div style={{ marginTop: 12 }}><a href="/" className="app-btn primary">Run the free report</a></div></div></div>);
  if (phase === 'failed' || !a || a.status !== 'ready') return shell(<div>{head}<div className="app-panel"><h3>The analysis did not complete</h3>
    <div style={{ fontSize: 14, color: 'var(--fg-muted)', lineHeight: 1.6 }}>{(inq.analysis && inq.analysis.error) || 'Something went wrong while writing it.'} You can try again; nothing you sent is lost.</div>
    <div style={{ marginTop: 12 }}><button className="app-btn primary" onClick={() => runAnalysis(true)}>Run it again</button></div></div></div>);

  const closable = a.gaps.filter((g) => !g.unknowable);
  const unknowable = a.gaps.filter((g) => g.unknowable);
  const gapTitle = (gid) => (a.gaps.find((g) => g.id === gid) || {}).title || gid;

  return shell(
    <div>
      {head}
      <div className="app-panel" style={{ marginBottom: 14 }}>
        <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start', flexWrap: 'wrap' }}>
          <div style={{ flex: '1 1 420px', fontSize: 15, lineHeight: 1.65 }}>{a.company.summary}</div>
          <div style={{ flex: '0 0 auto', display: 'flex', flexDirection: 'column', gap: 6, alignItems: 'flex-end' }}>
            <span style={{ display: 'inline-flex', gap: 6, alignItems: 'center', fontSize: 12.5, color: 'var(--fg-muted)' }}>Overall evidence <Grade g={a.confidence.overall} /></span>
            <span className="mono" style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>{a.researched ? 'public research included' : 'no public research in this run'} · {shortDate(a.at)}</span>
          </div>
        </div>
        <div style={{ fontSize: 13, color: 'var(--fg-muted)', marginTop: 8, lineHeight: 1.6 }}>{a.confidence.note}</div>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 12, alignItems: 'center' }}>
          {stale && <span className="flash warn" style={{ margin: 0, padding: '6px 10px' }}>You added inputs since this run.</span>}
          <button className={'app-btn small' + (stale ? ' primary' : '')} onClick={() => runAnalysis(true)}>Re-run the analysis</button>
          <button className="app-btn small" onClick={() => setMore(true)}>Add answers or files</button>
          {inq.needs_nda && !inq.nda_ok && <a className="app-btn small" href={'/app/?request=' + id}>Sign the NDA for sensitive detail</a>}
        </div>
      </div>

      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center', margin: '0 0 14px', fontSize: 12.5, color: 'var(--fg-muted)' }}>
        <span>Evidence grades:</span>{['A', 'B', 'C', 'D', '-'].map((g) => <Grade key={g} g={g} long />)}
      </div>

      <h2 className="display" style={{ fontSize: 22, margin: '18px 0 10px' }}>The picture today</h2>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: 10, marginBottom: 22 }}>
        {a.profile.map((p, i) => <div key={i} className="stat" style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'center' }}><div className="label" style={{ margin: 0 }}>{p.label}</div><Grade g={p.grade} /></div>
          <div style={{ fontSize: 15, fontWeight: 600, lineHeight: 1.35 }}>{p.value}</div>
          {p.source && <div style={{ fontSize: 12, color: 'var(--fg-subtle)' }}>{p.source}</div>}
          {p.note && <div style={{ fontSize: 12.5, color: 'var(--fg-muted)', lineHeight: 1.5 }}>{p.note}</div>}
        </div>)}
      </div>

      <h2 className="display" style={{ fontSize: 22, margin: '18px 0 4px' }}>What would sharpen it</h2>
      <p style={{ fontSize: 14, color: 'var(--fg-muted)', margin: '0 0 12px', lineHeight: 1.6, maxWidth: 720 }}>
        These are the gaps in Lojo's understanding. Each says what is known today, why it matters, and how the analysis changes once you close it. Some of them change it dramatically.
      </p>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: 10, marginBottom: 14 }}>
        {closable.map((g) => <div key={g.id} className="app-panel" style={{ borderColor: 'color-mix(in oklab, var(--accent) 35%, var(--line))' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'flex-start' }}><h3 style={{ margin: 0 }}>{g.title}</h3><span className="mono" style={{ fontSize: 10.5, color: 'var(--fg-subtle)', whiteSpace: 'nowrap' }}>TIER {g.tier}{g.tier === 3 ? ' · NDA' : ''}</span></div>
          <div style={{ fontSize: 13.5, lineHeight: 1.6, marginTop: 8, display: 'grid', gap: 6 }}>
            <div><b>Today:</b> {g.know}</div>
            <div><b>Why it matters:</b> {g.why}</div>
            <div style={{ color: 'var(--accent)' }}><b>Once provided:</b> {g.changes}</div>
            <div style={{ color: 'var(--fg-muted)' }}><b>How:</b> {g.how}</div>
          </div>
          {g.modules.length > 0 && <div style={{ display: 'flex', gap: 5, flexWrap: 'wrap', marginTop: 8 }}>{g.modules.map((m) => <span key={m} className="kind-pill">{labelOf(m)}</span>)}</div>}
          <div style={{ marginTop: 10 }}>{g.tier === 3 && inq.needs_nda && !inq.nda_ok
            ? <a className="app-btn small" href={'/app/?request=' + id}>Sign the NDA, then add it</a>
            : <button className="app-btn small primary" onClick={() => setMore(true)}>Add it now</button>}</div>
        </div>)}
      </div>
      {unknowable.length > 0 && <div className="app-panel" style={{ borderStyle: 'dashed', marginBottom: 22 }}>
        <h3>Only you can tell us</h3>
        <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginBottom: 8 }}>Lojo does not estimate these. Until they are provided, the analyses that need them say so instead of guessing.</div>
        {unknowable.map((g) => <div key={g.id} style={{ padding: '10px 0', borderTop: '1px solid var(--line)', fontSize: 13.5, lineHeight: 1.6 }}>
          <div style={{ fontWeight: 600 }}>{g.title} <Grade g="-" /></div>
          <div style={{ color: 'var(--fg-muted)' }}>{g.why} <span style={{ color: 'var(--accent)' }}>{g.changes}</span></div>
          <div style={{ color: 'var(--fg-subtle)', fontSize: 12.5 }}>How: {g.how}</div>
        </div>)}
        <div style={{ marginTop: 8 }}>{inq.needs_nda && !inq.nda_ok ? <a className="app-btn small" href={'/app/?request=' + id}>Provide under NDA</a> : <button className="app-btn small" onClick={() => setMore(true)}>Provide it</button>}</div>
      </div>}

      <h2 className="display" style={{ fontSize: 22, margin: '18px 0 4px' }}>By module</h2>
      <p style={{ fontSize: 14, color: 'var(--fg-muted)', margin: '0 0 12px', lineHeight: 1.6, maxWidth: 720 }}>
        The first insights are free. The findings, recommendations and the honest list of what cannot be modelled yet are unlocked per module. Beta pricing; each unlock includes a 45-minute walkthrough with the founders and is credited against an implementation in the following 90 days.
      </p>
      {Object.values(a.modules).map((m) => {
        const price = priceOf(m.id);
        return <div key={m.id} id={'module-' + m.id} className="app-panel" style={{ marginBottom: 14, borderColor: m.unlocked ? 'var(--accent)' : 'var(--line)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, alignItems: 'flex-start', flexWrap: 'wrap' }}>
            <div><div className="overline" style={{ marginBottom: 4 }}>{m.title}</div><div style={{ fontSize: 16.5, fontWeight: 600, lineHeight: 1.4, maxWidth: 680 }}>{m.headline}</div></div>
            {m.unlocked ? <Pill tone="good">Unlocked</Pill> : <Pill tone="fg-subtle">{price ? `Locked · $${Number(price.usd).toLocaleString('en-US')} ${price.unit}` : 'Locked'}</Pill>}
          </div>
          <div style={{ marginTop: 14 }}>
            <div className="mono" style={{ fontSize: 10.5, letterSpacing: '0.09em', textTransform: 'uppercase', color: 'var(--accent)', marginBottom: 6 }}>Free insights</div>
            {m.free.map((f, i) => <div key={i} style={{ padding: '10px 0', borderTop: '1px solid var(--line)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8 }}><div style={{ fontWeight: 600, fontSize: 14.5 }}>{f.title}</div><Grade g={f.grade} /></div>
              <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginTop: 3 }}>{f.text}</div>
              {f.sources.length > 0 && <div style={{ fontSize: 11.5, color: 'var(--fg-subtle)', marginTop: 3 }}>Sources: {f.sources.join(' · ')}</div>}
            </div>)}
          </div>
          {m.unlocked ? <div style={{ marginTop: 14 }}>
            <div className="mono" style={{ fontSize: 10.5, letterSpacing: '0.09em', textTransform: 'uppercase', color: 'var(--fg-subtle)', marginBottom: 6 }}>Findings</div>
            {m.findings.map((f, i) => <div key={i} style={{ padding: '10px 0', borderTop: '1px solid var(--line)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, flexWrap: 'wrap' }}><div style={{ fontWeight: 600, fontSize: 14.5 }}>{f.title}</div>
                <span style={{ display: 'inline-flex', gap: 6 }}><Pill tone={f.impact === 'high' ? 'crit' : f.impact === 'medium' ? 'warn' : 'fg-subtle'}>{f.impact} impact</Pill><Grade g={f.grade} /></span></div>
              <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginTop: 3 }}>{f.text}</div>
              {f.depends_on.length > 0 && <div style={{ fontSize: 12, color: 'var(--accent)', marginTop: 3 }}>Changes once provided: {f.depends_on.map(gapTitle).join(' · ')}</div>}
            </div>)}
            <div className="mono" style={{ fontSize: 10.5, letterSpacing: '0.09em', textTransform: 'uppercase', color: 'var(--fg-subtle)', margin: '14px 0 6px' }}>Recommendations</div>
            {m.recommendations.map((r, i) => <div key={i} style={{ padding: '10px 0', borderTop: '1px solid var(--line)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, flexWrap: 'wrap' }}><div style={{ fontWeight: 600, fontSize: 14.5 }}>{r.title}</div>
                <span style={{ display: 'inline-flex', gap: 6 }}><Pill tone="accent">{r.effort} effort</Pill><Grade g={r.grade} /></span></div>
              <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginTop: 3 }}>{r.text}</div>
              {r.value && <div style={{ fontSize: 12.5, color: 'var(--fg)', marginTop: 3 }}>Worth: {r.value}</div>}
            </div>)}
            {m.cannot_yet.length > 0 && <div style={{ marginTop: 14, padding: '10px 12px', borderRadius: 'var(--r-md)', border: '1px dashed var(--line-strong)' }}>
              <div className="mono" style={{ fontSize: 10.5, letterSpacing: '0.09em', textTransform: 'uppercase', color: 'var(--fg-subtle)', marginBottom: 6 }}>Cannot be modelled yet</div>
              {m.cannot_yet.map((c, i) => <div key={i} style={{ fontSize: 13.5, lineHeight: 1.6 }}>{c.title} <span style={{ color: 'var(--fg-subtle)' }}>needs {c.needs.map(gapTitle).join(', ') || 'more input'}</span></div>)}
            </div>}
          </div> : <div style={{ marginTop: 14, padding: '14px 16px', borderRadius: 'var(--r-md)', background: 'var(--navy)', border: '1px solid var(--line)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
              <div style={{ fontSize: 14, lineHeight: 1.6 }}>
                <b>{m.counts.findings} findings, {m.counts.recommendations} recommendations</b> and {m.counts.cannot_yet} analyses that need your input, each with its evidence grade.
                <div style={{ color: 'var(--fg-muted)', fontSize: 13, marginTop: 4, filter: 'blur(0)' }}>Including: {m.preview.findings.concat(m.preview.recommendations).join(' · ')}{m.preview.cannot_yet.length ? ` · not yet: ${m.preview.cannot_yet.join(', ')}` : ''}</div>
              </div>
              <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                {price && pay && pay.enabled && <button className="btn btn-primary" style={{ padding: '10px 16px', fontSize: 14 }} onClick={() => buy(m.id)}>Unlock {m.title} · ${Number(price.usd).toLocaleString('en-US')}</button>}
                <a className="app-btn" href={'/app/?request=' + m.id}>Talk to us first</a>
              </div>
            </div>
            {price && <div style={{ fontSize: 12, color: 'var(--fg-subtle)', marginTop: 8 }}>{price.unit}, one-time, beta pricing. {price.description}</div>}
          </div>}
        </div>;
      })}

      {a.research && a.research.length > 0 && <div className="app-panel" style={{ marginTop: 10 }}>
        <h3>What Lojo looked for in public</h3>
        {a.research.map((r, i) => <div key={i} style={{ fontSize: 13, lineHeight: 1.6, padding: '6px 0', borderTop: '1px solid var(--line)' }}><b>{r.looked_for}</b>: {r.found} <span style={{ color: 'var(--fg-subtle)' }}>{r.source}</span> <Grade g={r.grade} /></div>)}
      </div>}
      <div style={{ fontSize: 12.5, color: 'var(--fg-subtle)', marginTop: 18, lineHeight: 1.6 }}>
        Reference {id}. Your inputs are seen only by the Lojo founders and used only for this analysis; nothing trains shared models. {a.website_pages.length > 0 && `Pages read on your site: ${a.website_pages.length}.`}
      </div>

      {more && <AddMoreDrawer inq={inq} opts={opts} id={id} email={email} onClose={() => setMore(false)} onSaved={async () => { setMore(false); await fetchAnalysis(); setStale(true); setFlash('Saved. Re-run the analysis to use it.'); }} />}
    </div>);
}

function AddMoreDrawer({ inq, opts, id, email, onClose, onSaved }) {
  const [t2, setT2] = React.useState(inq.tiers['2'] || {});
  const [t3, setT3] = React.useState(inq.tiers['3'] || {});
  const [files, setFiles] = React.useState([]);
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');
  if (!opts) return null;
  const canT3 = !inq.needs_nda || inq.nda_ok;
  const upload = async (file) => {
    const b64 = await fileToBase64(file);
    const d = await lojo('', { module: 'inquiry', action: 'file-upload', id, email, filename: file.name, content_type: file.type || 'application/octet-stream', content_base64: b64 });
    if (d.ok) setFiles([...files, file.name]); else setError(d.message || Object.values(d.errors || {}).join(' ') || 'Upload failed');
  };
  const save = async () => {
    setBusy(true); setError('');
    const tiers = { 2: t2 }; if (canT3) tiers[3] = t3;
    const d = await lojo('', { module: 'inquiry', action: 'update', id, email, tiers });
    setBusy(false);
    if (!d.ok) { setError(d.message || Object.values(d.errors || {}).join(' ') || 'Not saved'); return; }
    onSaved(d.inquiry);
  };
  return <Drawer title="Add answers or files" onClose={onClose} width={720}>
    <div style={{ fontSize: 13.5, color: 'var(--fg-muted)', lineHeight: 1.6, marginBottom: 12 }}>Everything you add enters the next run at grade A. Text and CSV files are read in full; other formats are stored and named as a gap until their key figures are pasted in.</div>
    <TierPanel tier={opts.tiers[2]} n={2} value={t2} onChange={setT2} />
    {canT3 ? <div>
      <TierPanel tier={opts.tiers[3]} n={3} value={t3} onChange={setT3} readOnlyNote=" Under the mutual NDA on file." />
      <div className="app-panel" style={{ marginBottom: 14 }}><h3>Files under NDA</h3>
        <input type="file" accept=".pdf,.doc,.docx,.txt,.csv,.xlsx,.png,.jpg,.jpeg" onChange={(e) => { const f = e.target.files && e.target.files[0]; if (f) upload(f); }} />
        {files.length > 0 && <div style={{ fontSize: 13, color: 'var(--fg-muted)', marginTop: 8 }}>Uploaded: {files.join(', ')}</div>}
      </div>
    </div> : <div className="flash warn">Sensitive detail (structure, bands, financials, deal material, files) needs the mutual NDA first. <a href={'/app/?request=' + id} style={{ color: 'inherit' }}>Sign it or upload yours →</a></div>}
    {error && <div className="flash warn">{error}</div>}
    <button className="btn btn-primary" disabled={busy} onClick={save}>{busy ? 'Saving…' : 'Save'}</button>
  </Drawer>;
}

Object.assign(window, { AnalysisPage, Grade });
