// draft.jsx — Draft preview (sectioned, multi-select) + AI chat for edits + DeliveryStep

const { useState: useDraftState, useEffect: useDraftEffect, useRef: useDraftRef } = React;

function DraftStep({ docId, values, notes, onBack, onFinalize }) {
  const doc = window.DOC_BY_ID[docId];
  const [draft, setDraft] = useDraftState(() => window.getDraft(docId, values));
  const [selectedSections, setSelectedSections] = useDraftState([]);
  const [msgs, setMsgs] = useDraftState(() => initialAiMessages(doc, notes));
  const [input, setInput] = useDraftState('');
  const [typing, setTyping] = useDraftState(false);
  // Server-side conversation history — append-only. Each turn we append
  // the user message + the assistantTurn returned by /api/chat so the
  // model has full context on the next call.
  const [conversation, setConversation] = useDraftState([]);
  const msgEndRef = useDraftRef(null);

  useDraftEffect(() => { if (window.lucide) window.lucide.createIcons(); }, [msgs, selectedSections, typing]);
  useDraftEffect(() => {
    if (msgEndRef.current) msgEndRef.current.scrollTop = msgEndRef.current.scrollHeight;
  }, [msgs, typing]);

  const toggleSection = (id) => {
    setSelectedSections(s => s.includes(id) ? s.filter(x => x !== id) : [...s, id]);
  };

  // Map the API's structured response shape to the UI message shape the
  // existing chat UI already renders. The UI shape was originally produced
  // by mockReply; keeping it identical means no other rendering changes.
  const apiResponseToUiMsg = (apiResult) => {
    const escalateToFullName = {
      Jeff: 'Jeff Salzbrun',
      Halie: 'Halie Aarestad',
    };
    const msg = {
      role: 'bot',
      text: apiResult.reply_text,
      src: 'CEG Boilerplate Library',
    };
    if (apiResult.escalate_to) {
      msg.escalate = escalateToFullName[apiResult.escalate_to] || apiResult.escalate_to;
      msg.escalateNote = apiResult.escalate_reason || 'Outside CEG-approved language.';
    }
    if (apiResult.applied_section_ids && apiResult.applied_section_ids.length) {
      msg.applied = apiResult.applied_section_ids;
      msg.aiNote = apiResult.intent === 'escalate'
        ? `Flagged for ${apiResult.escalate_to || 'review'} — outside approved language.`
        : 'Reviewed using approved CEG language.';
    }
    return msg;
  };

  const send = async (text) => {
    if (!text.trim()) return;
    setInput('');
    const userMsg = {
      role: 'user',
      text,
      sections: [...selectedSections],
    };
    setMsgs(m => [...m, userMsg]);
    setTyping(true);

    try {
      const res = await window.authedFetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          docId,
          values,
          sectionTitles: draft.map(s => s.title),
          conversation,
          userMessage: text,
          selectedSectionIds: selectedSections,
        }),
      });

      if (!res.ok) {
        const errBody = await res.json().catch(() => ({ error: res.statusText }));
        throw new Error(errBody.error || `Chat failed (HTTP ${res.status})`);
      }
      const data = await res.json();

      // Append BOTH the user turn and the assistant turn to server-side
      // conversation history. The user turn must include the [Scoped sections: ...]
      // tag that chat.py adds, so the next call sees the same shape the model saw.
      const scopedTag = `[Scoped sections: ${selectedSections.length ? selectedSections.join(', ') : 'none'}]\n\n`;
      setConversation(c => [
        ...c,
        { role: 'user', content: scopedTag + text },
        data.assistantTurn,
      ]);

      const reply = apiResponseToUiMsg(data.result);
      setTyping(false);
      setMsgs(m => [...m, reply]);

      if (reply.applied && reply.applied.length) {
        setDraft(d => d.map(s =>
          reply.applied.includes(s.id) ? { ...s, aiNote: reply.aiNote } : s
        ));
      }
    } catch (e) {
      console.error('chat failed:', e);
      setTyping(false);
      setMsgs(m => [...m, {
        role: 'bot',
        text: `Couldn't reach the assistant — ${e.message}\n\nIf the dev server is running, this might be an API key or network issue. Check Terminal for details.`,
      }]);
    }
  };

  const quickActions = selectedSections.length > 0
    ? [
        'Tighten the language',
        'Add a 30-day cure period',
        'Reduce commission to 5%',
        'Loop in Jeff for review',
      ]
    : [
        'Walk me through this draft',
        'What’s required for Halie’s sign-off?',
        'Which sections are most often edited?',
      ];

  return (
    <div className="canvas-pad canvas-wide fade-in">
      <div className="page-head">
        <div>
          <div className="eyebrow-sm">Step 04 · Review your draft</div>
          <h2 style={{marginTop:6}}>First draft ready for review</h2>
          <div className="lead">
            Skim section-by-section. <b>Select any sections you want to change</b> (one, several, or none), then describe the edit in chat. The assistant will only apply CEG-approved language — anything outside boilerplate routes to <b>{doc?.approver === 'Jeff' ? 'Jeff' : 'Halie'}</b>.
          </div>
        </div>
        <div className="right">
          <span className="chip"><i data-lucide="git-branch" style={{width:11, height:11, strokeWidth:2}}></i> Revision 1</span>
        </div>
      </div>

      <div className="draft-layout">
        {/* Draft document */}
        <div className="draft-doc">
          <div className="draft-doc-head">
            <div>
              <div className="ttl">{doc?.name || 'Document'}</div>
              <div className="sub">
                {values.clientEntity || values.ownerEntity || ''}
                {(values.clientEntity || values.ownerEntity) ? ' · ' : ''}
                Draft · {new Date().toLocaleDateString('en-US', { month:'short', day:'numeric', year:'numeric'})}
              </div>
            </div>
            <div className="right">
              <button className="btn btn-ghost btn-sm"><i data-lucide="eye"></i> Read mode</button>
              <button className="btn btn-ghost btn-sm"><i data-lucide="diff"></i> Compare</button>
            </div>
          </div>

          <div className="draft-body">
            {draft.map((sec, idx) => (
              <div
                key={sec.id}
                className={`draft-sec ${selectedSections.includes(sec.id) ? 'is-selected' : ''}`}
                onClick={() => toggleSection(sec.id)}
              >
                <div className="check">
                  <i data-lucide="check"></i>
                </div>
                <h3>
                  <span className="num">{sec.legalRef || `§ ${idx + 1}`}</span>
                  {sec.title}
                </h3>
                {sec.body}
                {sec.aiNote && (
                  <div className="ai-note">
                    <i data-lucide="sparkles"></i>
                    <div>{sec.aiNote}</div>
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>

        {/* AI panel */}
        <div className="ai-panel">
          <div className="ai-panel-head">
            <div className="ai-avatar"><i data-lucide="sparkles"></i></div>
            <div className="ttl">
              <h4>CEG Boilerplate Assistant</h4>
              <div className="sub">Trained on approved CEG language</div>
            </div>
            <button className="btn btn-text btn-sm" style={{padding: '4px 8px'}}><i data-lucide="more-horizontal" style={{width:16, height:16}}></i></button>
          </div>

          <div className="ai-context">
            <i data-lucide="mouse-pointer-2"></i>
            {selectedSections.length === 0
              ? <span>Click a section to scope your edit, or chat for general guidance.</span>
              : <>
                  <span className="count">{selectedSections.length}</span>
                  <span>{selectedSections.length === 1 ? 'section' : 'sections'} selected as edit scope</span>
                </>}
          </div>

          <div className="ai-msgs" ref={msgEndRef}>
            {msgs.map((m, i) => <AiMsg key={i} msg={m} />)}
            {typing && (
              <div className="ai-msg bot">
                <div className="av"><i data-lucide="sparkles"></i></div>
                <div className="bubble">
                  <span className="typing"><span></span><span></span><span></span></span>
                </div>
              </div>
            )}
          </div>

          <div className="ai-input">
            <div className="row">
              <textarea
                placeholder={selectedSections.length > 0
                  ? `Tell me what to change about ${selectedSections.length === 1 ? 'this section' : 'these sections'}…`
                  : 'Ask anything, or select sections above to edit…'}
                value={input}
                rows={1}
                onChange={e => { setInput(e.target.value); e.target.style.height = 'auto'; e.target.style.height = Math.min(e.target.scrollHeight, 120) + 'px'; }}
                onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(input); }}}
              />
              <button className="send-btn" onClick={() => send(input)} disabled={!input.trim()}>
                <i data-lucide="arrow-up" style={{width:16, height:16, strokeWidth:2.5}}></i>
              </button>
            </div>
            <div className="quick-row">
              {quickActions.map(q => (
                <button key={q} className="quick" onClick={() => send(q)}>{q}</button>
              ))}
            </div>
          </div>
        </div>
      </div>

      <div className="action-bar">
        <div className="left">
          <button className="btn btn-ghost" onClick={onBack}>
            <i data-lucide="arrow-left"></i> Edit details
          </button>
          <div className="status">
            <i data-lucide="history"></i>
            Auto-saved · Revision 1 · just now
          </div>
        </div>
        <div className="right">
          <button className="btn btn-ghost btn-sm">
            <i data-lucide="refresh-cw"></i> Regenerate
          </button>
          <button className="btn btn-accent btn-lg" onClick={() => onFinalize(draft)}>
            Finalize & deliver <i data-lucide="arrow-right"></i>
          </button>
        </div>
      </div>
    </div>
  );
}

function AiMsg({ msg }) {
  if (msg.role === 'user') {
    return (
      <div className="ai-msg user">
        <div className="av">YO</div>
        <div className="bubble">
          {msg.sections && msg.sections.length > 0 && (
            <div style={{fontSize:11, color:'rgba(255,255,255,0.6)', marginBottom: 5, fontFamily:'var(--font-mono)'}}>
              ↳ scoped to {msg.sections.length} section{msg.sections.length === 1 ? '' : 's'}
            </div>
          )}
          {msg.text}
        </div>
      </div>
    );
  }
  return (
    <div className="ai-msg bot">
      <div className="av"><i data-lucide="sparkles"></i></div>
      <div className="bubble">
        <div style={{whiteSpace:'pre-wrap'}}>{msg.text}</div>
        {msg.escalate && (
          <div className="escalate">
            <i data-lucide="user-check"></i>
            <div>
              <b style={{display:'block', color:'#5a3c00'}}>Routed to {msg.escalate}</b>
              {msg.escalateNote || 'This change is outside the CEG-approved boilerplate. I’ve flagged it for review before sending.'}
            </div>
          </div>
        )}
        {msg.src && (
          <div className="src">
            <i data-lucide="library"></i>
            {msg.src}
          </div>
        )}
      </div>
    </div>
  );
}

function initialAiMessages(doc, notes) {
  const base = [{
    role: 'bot',
    text: `I’ve drafted your ${doc?.name || 'document'} using CEG-approved language. Everything you entered is merged in (highlighted in blue) and the rest is boilerplate Jeff and Halie have signed off on.\n\nSkim it section-by-section. If anything needs to change, select the section(s) and tell me what to do. I’ll only apply approved clauses — if you ask for something outside the playbook, I’ll route it to ${doc?.approver || 'Jeff'} before it ships.`,
    src: 'CEG Boilerplate Library · v2026.05',
  }];
  if (notes && notes.trim()) {
    base.push({
      role: 'bot',
      text: `I read your notes too. A few things stood out:\n\n• You mentioned competing brokers — I added a standard "Protected Party" tail period in § 3.\n• Closing pressure noted — I left the effective date as you entered it; suggest confirming with the client.\n\nWant me to tighten anything?`,
      src: 'Used your deal notes',
    });
  }
  return base;
}

// ─── Heuristic mock AI ────────────────────────────────────────────────────
function mockReply(text, sections, draft, doc) {
  const t = text.toLowerCase();
  // Escalation triggers — words/edits that AI should refuse and route up
  const escalateTriggers = [
    { match: /(custom|bespoke|new clause|add a clause|invent|draft from scratch)/i, who: 'Jeff Salzbrun', why: 'New clause language isn’t in the approved CEG library.' },
    { match: /(commission.*(below|under|less than) ?5|sale commission.*(3|4)%|drop.*commission|reduce.*sale.*commission)/i, who: 'Jeff Salzbrun', why: 'Sale commission below 5% needs Jeff’s sign-off — the boilerplate specifically notes a lower price may need a HIGHER fee.' },
    { match: /(co[- ]?broker.*(0|none|skip)|remove.*co[- ]broker)/i, who: 'Jeff Salzbrun', why: 'Removing the co-broker fee is a deviation from the CEG boilerplate.' },
    { match: /(remove.*exclusiv|non[- ]exclusive|drop exclusivity|open listing)/i, who: 'Jeff Salzbrun', why: 'CEG listings are exclusive by design — non-exclusive is not in the boilerplate.' },
    { match: /(out of state|outside minnesota|wisconsin|iowa|north dakota|south dakota)/i, who: 'Jeff Salzbrun', why: 'The listing boilerplate is locked to Minnesota. Out-of-state property needs Jeff before drafting.' },
    { match: /(indemnif|liability cap|warrant|guarantee|hold harmless)/i, who: 'Halie Aarestad', why: 'Indemnification and liability language requires Halie to review.' },
    { match: /(extend.*term|36 months|3 years|5 years|five years|long.?term listing)/i, who: 'Jeff Salzbrun', why: 'Listing terms longer than the boilerplate default need Jeff’s OK.' },
    { match: /(tail period|180 days|150 days|protected period|protection.*period)/i, who: 'Jeff Salzbrun', why: 'The 180-day lease tail and 150-day sale tail are CEG defaults. Changes need Jeff.' },
    { match: /(option 3|new commission structure|hybrid commission)/i, who: 'Jeff Salzbrun', why: 'The boilerplate is Option 1 (Office flat) or Option 2 (Industrial graduated) — a third structure needs Jeff.' },
  ];

  for (const trig of escalateTriggers) {
    if (trig.match.test(text)) {
      return {
        role: 'bot',
        text: `I can’t make that change from approved language alone. ${trig.why} I’ve flagged it on this draft — when you finalize, it’ll go to ${trig.who} for review before it sends.`,
        escalate: trig.who,
        escalateNote: 'A red banner will appear on the finalize screen confirming the routing.',
        applied: sections,
        aiNote: `Flagged for ${trig.who} — outside approved language.`,
      };
    }
  }

  // Loop-in request
  if (/\b(jeff|halie|loop in|send to)\b/i.test(text)) {
    const who = /halie/i.test(text) ? 'Halie Aarestad' : 'Jeff Salzbrun';
    return {
      role: 'bot',
      text: `Done — I’ve added ${who} as a reviewer on this draft. On the finalize screen you’ll see them queued for sign-off before any external delivery.`,
      src: 'Approval routing',
    };
  }

  // Tighten language
  if (/(tighten|shorten|concise|trim)/i.test(text)) {
    return {
      role: 'bot',
      text: sections.length
        ? `Tightened ${sections.length} section${sections.length === 1 ? '' : 's'}. Removed redundant "hereunder" phrasing and consolidated the two paragraphs in each. Still using CEG-approved language — review the highlighted notes below each section to confirm.`
        : 'Select one or more sections first, then tell me to tighten — I’ll work within the selection.',
      applied: sections,
      aiNote: 'Tightened — approved CEG phrasing preserved.',
      src: 'CEG Boilerplate Library · Style guide',
    };
  }

  // Cure period
  if (/cure period|30[- ]day cure|grace period/i.test(text)) {
    return {
      role: 'bot',
      text: 'Added a standard 30-day cure-and-notice provision pulled from the CEG approved Termination clause. Applied to the section(s) you selected.',
      applied: sections.length ? sections : ['termination'],
      aiNote: 'Cure-and-notice (30 days) added per CEG standard.',
      src: 'CEG Approved Clause · Termination v3',
    };
  }

  // Commission within range
  if (/commission.*(4|5|6)/.test(t)) {
    return {
      role: 'bot',
      text: 'Updated the commission to the requested percentage. That’s within CEG’s standard 4–6% band so no extra sign-off required.',
      applied: sections.length ? sections : ['compensation','commission'],
      aiNote: 'Commission within CEG-approved range.',
      src: 'CEG Approved Clause · Compensation',
    };
  }

  // Walkthrough
  if (/walk me through|explain|what is|tell me about/i.test(text)) {
    return {
      role: 'bot',
      text: `Sure. This ${doc?.name || 'document'} has ${draft.length} sections:\n\n${draft.map((s,i) => `${i+1}. ${s.title} — ${shortDescription(s.id)}`).join('\n')}\n\nThe highlighted fields are merged from your form. Everything else is approved boilerplate. Want me to break any of those down further?`,
      src: 'CEG document playbook',
    };
  }

  // Default — couldn't confidently apply, ask clarifying
  if (sections.length === 0) {
    return {
      role: 'bot',
      text: 'Got it. Which section is this change about? Click one or more sections on the left to scope the edit — that way I know exactly where to apply approved language.',
    };
  }
  return {
    role: 'bot',
    text: `I’ll apply that to the ${sections.length} section${sections.length === 1 ? '' : 's'} you selected, drawing only from approved CEG clauses. If the change drifts outside my library while I work, I’ll stop and ask. Anything you want me to preserve verbatim?`,
    applied: sections,
    aiNote: 'Edit applied from approved CEG language.',
    src: 'CEG Boilerplate Library',
  };
}

function shortDescription(secId) {
  return ({
    parties: 'who’s signing and against what property',
    scope: 'what CEG is engaged to do',
    grant: 'the exclusive grant from owner to CEG',
    term: 'duration and tail-period rights',
    rent: 'asking rent and lease structure',
    compensation: 'commission, timing of payment',
    commission: 'commission, timing of payment',
    confidentiality: 'nonpublic info, conflicts, disclosure',
    termination: 'how either side gets out',
    marketing: 'channels CEG uses to market the property',
    signatures: 'who signs and in what capacity',
  })[secId] || 'standard CEG clause';
}

// ─── DELIVERY STEP (Step 05) ──────────────────────────────────────────────
function DeliveryStep({ docId, values, onBack, onStartOver }) {
  const doc = window.DOC_BY_ID[docId];
  const [stage, setStage] = useDraftState('preview'); // preview | sent
  const [choice, setChoice] = useDraftState(null);
  const [busy, setBusy] = useDraftState(false);
  const [downloadError, setDownloadError] = useDraftState(null);
  const [airtableLink, setAirtableLink] = useDraftState(null);  // populated after a successful Send-to-Halie push

  useDraftEffect(() => { if (window.lucide) window.lucide.createIcons(); }, [stage, choice, busy, downloadError, airtableLink]);

  const draft = window.getDraft(docId, values);
  const isRouted = doc?.approver === 'Jeff' || doc?.approver === 'Halie';
  const approver = doc?.approver || 'Jeff';

  // Hit the backend /api/generate endpoint to produce a real .docx,
  // then trigger a browser download. Falls back to error display on failure.
  const downloadRealDocx = async () => {
    setBusy(true);
    setDownloadError(null);
    try {
      const res = await window.authedFetch('/api/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ docId, values }),
      });
      if (!res.ok) {
        const errBody = await res.json().catch(() => ({ error: res.statusText }));
        throw new Error(errBody.error || `Generation failed (HTTP ${res.status})`);
      }
      const blob = await res.blob();
      // Pull the friendly filename out of the Content-Disposition header
      const cd = res.headers.get('Content-Disposition') || '';
      const fname = (cd.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i) || [])[1]
        || `${doc?.name || 'CEG-Document'}.docx`;
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = decodeURIComponent(fname);
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
      setStage('sent');
    } catch (e) {
      console.error('download failed:', e);
      setDownloadError(String(e.message || e));
    } finally {
      setBusy(false);
    }
  };

  // Hit /api/finalize — currently this triggers an Airtable push for
  // listing agreements (no-op for other doc types). Will eventually also
  // drop the .docx in Halie's review folder + email her.
  const sendToReviewer = async () => {
    setBusy(true);
    setDownloadError(null);
    setAirtableLink(null);
    try {
      const res = await window.authedFetch('/api/finalize', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ docId, values }),
      });
      if (!res.ok) {
        const errBody = await res.json().catch(() => ({ error: res.statusText }));
        throw new Error(errBody.error || `Finalize failed (HTTP ${res.status})`);
      }
      const data = await res.json();

      // Order matters: transition stage FIRST so React unmounts the delivery
      // panel cleanly before any new conditional UI mounts. Otherwise the
      // Lucide icon library (which mutates `<i data-lucide>` into `<svg>`
      // outside React's awareness) leaves the DOM out of sync with React's
      // virtual tree, and reconciliation throws a removeChild error.
      const airtablePush = (data.actions || []).find(a => a.type === 'airtable_push');
      if (airtablePush && !airtablePush.ok) {
        setDownloadError(
          `Airtable push failed (${airtablePush.error}). The document is ready, ` +
          `but you'll need to manually create the listing record in Airtable.`
        );
      }
      setStage('sent');
      // Surface the Airtable link AFTER the stage transition has committed
      // (next microtask). The 'sent' screen renders without the callout
      // first, then the callout fades in once airtableLink populates.
      if (airtablePush && airtablePush.ok) {
        setTimeout(() => setAirtableLink(airtablePush.url), 0);
      }
    } catch (e) {
      console.error('finalize failed:', e);
      setDownloadError(String(e.message || e));
    } finally {
      setBusy(false);
    }
  };

  const handlePrimaryAction = () => {
    if (choice === 'download') {
      downloadRealDocx();
    } else if (choice === 'review') {
      sendToReviewer();
    }
  };

  // NOTE: We render BOTH the preview and sent screens at all times, toggling
  // visibility via CSS. The reason is that the prototype uses Lucide's
  // `createIcons()` to mutate <i data-lucide=...> elements into <svg> at
  // runtime — outside of React's awareness. When stage transitions and React
  // tries to unmount the preview tree, it fails (`removeChild` errors)
  // because the DOM no longer matches its virtual tree (Lucide already
  // replaced the <i>s). Keeping both subtrees mounted means React never has
  // to unmount Lucide-mutated nodes during this transition.
  return (
    <>
      {/* ─── SENT (confirmation) screen ────────────────────────────── */}
      <div className="canvas-pad fade-in" style={{display: stage === 'sent' ? 'block' : 'none'}}>
        <div style={{maxWidth: 640, margin: '60px auto', textAlign: 'center'}}>
          <div style={{
            width: 80, height: 80, borderRadius: '50%',
            background: 'linear-gradient(135deg, var(--cyan-400), var(--cyan-600))',
            color: 'var(--ceg-navy)', margin: '0 auto 24px',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            boxShadow: '0 12px 32px -8px rgba(0,201,255,0.5)',
          }}>
            <i data-lucide="check" style={{width: 40, height: 40, strokeWidth: 2.5}}></i>
          </div>
          <div className="eyebrow-sm">Step 05 · Delivered</div>
          <h2 style={{fontSize: 32, marginTop: 8, marginBottom: 14}}>
            {choice === 'review' && `Sent to ${approver}`}
            {choice === 'download' && 'Word document downloaded'}
          </h2>
          <p style={{fontSize: 16, color: 'var(--ink-500)', lineHeight: 1.6, marginBottom: 28}}>
            {choice === 'review' && <>{approver} has been notified and will review your draft. You'll hear back when it's ready to send for signature.</>}
            {choice === 'download' && <><b>{doc?.name}.docx</b> is in your downloads folder.</>}
          </p>

          <div style={{
            background: '#fff', border: '1px solid var(--border-subtle)',
            borderRadius: 'var(--radius-lg)', padding: '18px 22px',
            display: 'flex', alignItems: 'center', gap: 16, textAlign: 'left',
            marginBottom: 24,
          }}>
            <div style={{
              width: 44, height: 44, borderRadius: 'var(--radius-md)',
              background: 'var(--ink-100)', display: 'flex',
              alignItems: 'center', justifyContent: 'center',
            }}>
              <i data-lucide={doc?.icon || 'file-text'} style={{width: 22, height: 22, color: 'var(--ceg-navy)', strokeWidth: 1.75}}></i>
            </div>
            <div style={{flex: 1}}>
              <div style={{fontWeight: 600, color: 'var(--ceg-navy)', fontSize: 14.5}}>{doc?.name}</div>
              <div style={{fontSize: 12, color: 'var(--ink-500)', marginTop: 3}}>
                {values.clientEntity || values.ownerEntity}
              </div>
            </div>
            <span className={`chip ${choice === 'review' ? 'review' : 'sent'}`}>
              <span className="dot"></span>
              {choice === 'review' ? `Awaiting ${approver}` : choice === 'download' ? 'Downloaded' : 'Saved'}
            </span>
          </div>

          <div style={{display: 'flex', gap: 10, justifyContent: 'center', flexWrap: 'wrap'}}>
            <button className="btn btn-primary" onClick={onStartOver}>
              <i data-lucide="plus"></i> Start a new document
            </button>
          </div>
        </div>
      </div>

      {/* ─── PREVIEW screen ─────────────────────────────────────────── */}
      <div className="canvas-pad fade-in" style={{display: stage === 'preview' ? 'block' : 'none'}}>
      <div className="page-head">
        <div>
          <div className="eyebrow-sm">Step 05 · Finalize & deliver</div>
          <h2 style={{marginTop: 6}}>How would you like to send this?</h2>
          <div className="lead">Final preview on the left. Pick a delivery option on the right.</div>
        </div>
      </div>

      <div className="delivery">
        <div className="delivery-doc">
          <div className="preview-strip">
            <i data-lucide="check-circle-2"></i>
            FINAL PREVIEW · uses approved CEG language only
          </div>
          <div className="draft-doc-head">
            <div>
              <div className="ttl">{doc?.name}</div>
              <div className="sub">
                {values.clientEntity || values.ownerEntity || ''} · {new Date().toLocaleDateString('en-US', { month:'long', day:'numeric', year:'numeric'})}
              </div>
            </div>
            <div className="right">
              <span className="chip live"><span className="dot"></span>Ready</span>
            </div>
          </div>
          <div className="draft-body">
            {draft.map((sec, idx) => (
              <div key={sec.id} className="draft-sec" style={{cursor: 'default'}}>
                <h3>
                  <span className="num">{sec.legalRef || `§ ${idx + 1}`}</span>
                  {sec.title}
                </h3>
                {sec.body}
              </div>
            ))}
          </div>
        </div>

        <div className="delivery-options">
          {isRouted && (
            <div className="deliv-card primary" onClick={() => setChoice('review')} style={{outline: choice === 'review' ? '2px solid var(--cyan-400)' : 'none'}}>
              <div className="row">
                <i data-lucide="send"></i>
                <h5>Send to {approver} for review</h5>
              </div>
              <p>Routed for sign-off before external delivery. {approver} will be notified and replies in your inbox.</p>
              <div className="footrow">
                <div className="approver">
                  <span className="av">{approver === 'Jeff' ? 'JS' : 'HA'}</span>
                  {approver === 'Jeff' ? 'Jeff Salzbrun · Owner' : 'Halie Aarestad · Operations'}
                </div>
                <span style={{fontSize: 11, color: 'var(--cyan-400)', fontFamily: 'var(--font-mono)'}}>~24h SLA</span>
              </div>
            </div>
          )}

          <div className="deliv-card" onClick={() => setChoice('download')} style={{outline: choice === 'download' ? '2px solid var(--cyan-400)' : 'none'}}>
            <div className="row">
              <i data-lucide="file-down" style={{color: 'var(--ceg-navy)'}}></i>
              <h5>Download as Word (.docx)</h5>
            </div>
            <p>Editable Word doc — for client redlines or your own polish.</p>
          </div>

        </div>
      </div>

      {downloadError && (
        <div style={{
          marginTop: 16, padding: '12px 16px',
          background: 'rgba(220, 38, 38, 0.08)',
          border: '1px solid rgba(220, 38, 38, 0.25)',
          borderRadius: 'var(--radius-md)',
          color: '#991B1B', fontSize: 13, lineHeight: 1.5,
          display: 'flex', alignItems: 'flex-start', gap: 10,
        }}>
          <span style={{fontSize: 16, marginTop: 2, flexShrink: 0}}>⚠</span>
          <div>
            <div style={{fontWeight: 600, marginBottom: 2}}>Couldn't generate the document</div>
            <div style={{color: '#7F1D1D'}}>{downloadError}</div>
            <div style={{marginTop: 6, fontSize: 12, color: '#991B1B', opacity: 0.8}}>
              Make sure the dev server is running: <code>backend/.venv/bin/python -m backend.server</code>
            </div>
          </div>
        </div>
      )}

      <div className="action-bar">
        <div className="left">
          <button className="btn btn-ghost" onClick={onBack} disabled={busy}>
            <i data-lucide="arrow-left"></i> Back to review
          </button>
        </div>
        <div className="right">
          <button className="btn btn-accent btn-lg" disabled={!choice || busy} onClick={handlePrimaryAction}>
            {busy && <>Working… <span style={{display: 'inline-block', animation: 'spin 1s linear infinite', marginLeft: 6}}>⟳</span></>}
            {!busy && choice === 'review' && <>Send to {approver} →</>}
            {!busy && choice === 'download' && <>Download .docx ↓</>}
            {!busy && !choice && <>Pick a delivery option →</>}
          </button>
        </div>
      </div>
      </div>
    </>
  );
}

Object.assign(window, { DraftStep, DeliveryStep, AiMsg });
