// review-scenes.jsx: the three scenes of the Document Review demo (18 s loop).
//   0.0 to  6.0  SceneImport  the Import modal: Google Drive, Dropbox, then a file from the computer
//   6.0 to 12.0  SceneSend    the document in the chat, a brief, sent to a lawyer
//  12.0 to 18.0  SceneReturn  the lawyer's reply with the reviewed Word document
//
// Copy follows the firm voice used everywhere a client reads: "we", no
// contractions, no em dashes, and no mention of AI. The Import modal mirrors
// components/CloudImportModal.tsx; the chat mirrors the Overview assistant's
// review flow; the reply mirrors a request thread in My Requests.
/* global OV, Icon, useLiveAnchor, Appear, ConversationPanel, DockedComposer,
   UserBubble, AgentText, StepLine, FileChip, AppButton, BriefField, SceneCaption,
   BRAND, Cursor, ModalShell, TabBar, DropZone, FileRow, ModalFooter, Spinner,
   useSprite, Easing, interpolate, clamp */

function fadeInOut(t, duration, { fadeIn = true, fadeOut = true } = {}) {
  const enter = fadeIn ? Easing.easeOutCubic(clamp(t / 0.4, 0, 1)) : 1;
  const exit = fadeOut ? 1 - clamp((t - (duration - 0.4)) / 0.4, 0, 1) : 1;
  return enter * exit;
}

function BigCursor({ x, y, clicking = false, opacity = 1 }) {
  return (
    <div style={{
      position: 'absolute', left: x, top: y, transform: 'translate(-4px, -4px)',
      pointerEvents: 'none', zIndex: 1000, opacity,
    }}>
      {clicking && (
        <div style={{
          position: 'absolute', left: -24, top: -24, width: 60, height: 60, borderRadius: 30,
          background: 'rgba(28,25,23,0.14)',
        }}/>
      )}
      <svg width="44" height="52" viewBox="0 0 22 26" style={{ filter: 'drop-shadow(0 3px 5px rgba(0,0,0,0.25))' }}>
        <path d="M2 2 L2 20 L7 16 L10 23 L13 22 L10 15 L17 15 Z" fill="#1C1917" stroke="#FFFFFF" strokeWidth="1.25" strokeLinejoin="round"/>
      </svg>
    </div>
  );
}

function cursorAt(t, keys) {
  const times = keys.map((k) => k[0]);
  const ease = Easing.easeInOutCubic;
  return {
    x: interpolate(times, keys.map((k) => k[1].x), ease)(t),
    y: interpolate(times, keys.map((k) => k[1].y), ease)(t),
  };
}

// Visible for a window of the scene, fading at both ends.
const window_ = (t, from, to) => clamp((t - from) / 0.25, 0, 1) * (1 - clamp((t - to) / 0.25, 0, 1));

const DOC = 'Services Agreement - Acme.docx';
const DOC_REVIEWED = 'Services Agreement - Acme (reviewed).docx';

// A cloud provider's file list inside the Import modal (Drive or Dropbox).
function CloudList({ provider, files, chosen }) {
  const icon = provider === 'gdrive' ? (
    <svg width="16" height="16" viewBox="0 0 24 24">
      <path d="M7.5 3l-6 10.5 3 5 6-10.5-3-5z" fill="#1FA463"/>
      <path d="M16.5 3h-9l6 10.5h9L16.5 3z" fill="#FFC107"/>
      <path d="M4.5 18.5h12l3-5h-12l-3 5z" fill="#3777E3"/>
    </svg>
  ) : (
    <svg width="16" height="16" viewBox="0 0 24 24">
      <path d="M6 3l6 4-6 4-6-4 6-4zM18 3l6 4-6 4-6-4 6-4zM0 13l6 4 6-4-6-4-6 4zM18 11l-6 4 6 4 6-4-6-4zM6 18l6 4 6-4-6-4-6 4z" fill="#0061FF"/>
    </svg>
  );
  return (
    <div style={{ margin: '22px 28px 0' }}>
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12,
        fontSize: 13, color: BRAND.subtle, fontWeight: 500,
      }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
          {icon}
          {provider === 'gdrive' ? 'Connected as k.townsend@acme.co' : 'Connected to Acme Dropbox'}
        </span>
        <span>Legal / Contracts</span>
      </div>
      <div style={{ border: `1px solid ${BRAND.border}`, borderRadius: 12, overflow: 'hidden' }}>
        {files.map((f, i) => {
          const on = f === chosen;
          return (
            <div key={f} style={{
              display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px',
              background: on ? '#F1F0EB' : '#FDFDFB',
              borderTop: i ? `1px solid ${BRAND.border}` : 'none',
              transition: 'background 180ms',
            }}>
              <div style={{
                width: 16, height: 16, borderRadius: 4, flexShrink: 0,
                border: `1.5px solid ${on ? BRAND.ink : BRAND.dashed}`,
                background: on ? BRAND.ink : 'transparent',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                transition: 'background 180ms, border-color 180ms',
              }}>
                {on && (
                  <svg width="10" height="10" viewBox="0 0 16 16" fill="none">
                    <path d="M3 8l3.5 3.5L13 5" stroke="#FFFFFF" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                )}
              </div>
              <div style={{ color: BRAND.subtle, display: 'flex' }}>
                <svg width="16" height="18" viewBox="0 0 16 18" fill="none">
                  <path d="M2 1h8l4 4v11a1 1 0 01-1 1H2a1 1 0 01-1-1V2a1 1 0 011-1z" stroke="currentColor" strokeWidth="1.2"/>
                  <path d="M10 1v4h4" stroke="currentColor" strokeWidth="1.2"/>
                </svg>
              </div>
              <div style={{ flex: 1, fontSize: 14, fontWeight: 500, color: BRAND.ink }}>{f}</div>
              <div style={{ fontSize: 12, color: BRAND.subtle }}>Modified 2 days ago</div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

const DRIVE_FILES = ['Board minutes - March.pdf', DOC, 'Employment Agreement - J Lee.docx'];
const DROPBOX_FILES = ['Shareholders Agreement.pdf', 'NDA - Northwind.docx', 'Supplier Terms 2026.docx'];

// ─── Scene 1: the Import modal ────────────────────────────────────────────
function SceneImport() {
  const { localTime: t, duration } = useSprite();

  // Which tab is open: Drive first, then Dropbox, then the computer.
  const tab = t < 2.05 ? 'gdrive' : t < 3.35 ? 'dropbox' : 'upload';
  const driveChosen = t >= 1.5;
  const dropped = t >= 4.35;
  const dragActive = t > 3.9 && t < 4.35;
  const imported = t >= 5.3;

  const containerRef = React.useRef(null);
  const driveRef = React.useRef(null);
  const dropboxRef = React.useRef(null);
  const uploadRef = React.useRef(null);
  const dropRef = React.useRef(null);
  const importRef = React.useRef(null);
  const drive = useLiveAnchor(driveRef, containerRef) || { x: 90, y: 86 };
  const dropbox = useLiveAnchor(dropboxRef, containerRef) || { x: 230, y: 86 };
  const upload = useLiveAnchor(uploadRef, containerRef) || { x: 350, y: 86 };
  const drop = useLiveAnchor(dropRef, containerRef) || { x: 410, y: 230 };
  const imp = useLiveAnchor(importRef, containerRef) || { x: 700, y: 520 };
  const row2 = { x: 300, y: 226 };

  const pos = cursorAt(t, [
    [0.2, { x: drive.x + 520, y: drive.y + 420 }],
    [0.8, drive],
    [1.1, { x: row2.x, y: row2.y }],
    [1.45, row2],
    [1.7, row2],
    [2.0, dropbox],
    [2.4, dropbox],
    [2.9, { x: dropbox.x + 40, y: dropbox.y + 180 }],
    [3.3, upload],
    [3.55, upload],
    [3.95, drop],
    [4.5, drop],
    [5.0, imp],
  ]);
  const clicking =
    (t > 0.82 && t < 0.98) ||
    (t > 1.47 && t < 1.62) ||
    (t > 2.02 && t < 2.18) ||
    (t > 3.32 && t < 3.48) ||
    (t > 5.22 && t < 5.4);

  const entryT = Easing.easeOutCubic(clamp(t / 0.5, 0, 1));
  const exitT = clamp((t - (duration - 0.4)) / 0.4, 0, 1);

  return (
    <div style={{
      position: 'absolute', inset: 0,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      background: 'rgba(20,20,20,0.22)',
      opacity: entryT * (1 - exitT),
    }}>
      <div
        ref={containerRef}
        style={{
          position: 'relative',
          transform: `scale(${1.6 * (0.97 + 0.03 * entryT)})`,
          transformOrigin: 'center',
        }}
      >
        <ModalShell title="Import Documents" width={820}>
          <TabBarRefs active={tab} refs={{ gdrive: driveRef, dropbox: dropboxRef, upload: uploadRef }} />
          {tab === 'gdrive' && <CloudList provider="gdrive" files={DRIVE_FILES} chosen={driveChosen ? DOC : null} />}
          {tab === 'dropbox' && <CloudList provider="dropbox" files={DROPBOX_FILES} chosen={null} />}
          {tab === 'upload' && (
            <div ref={dropRef}>
              <DropZone dragActive={dragActive} />
            </div>
          )}

          <div style={{ padding: '18px 28px 0', minHeight: 84 }}>
            {tab === 'upload' && dropped && (
              <div style={{ opacity: Easing.easeOutCubic(clamp((t - 4.35) / 0.36, 0, 1)) }}>
                <FileRow name={DOC} size="412 KB" analyzing={imported} />
              </div>
            )}
            {tab === 'gdrive' && driveChosen && (
              <div style={{ fontSize: 12, color: BRAND.subtle, fontWeight: 500 }}>1 file selected from Google Drive</div>
            )}
          </div>

          <ModalFooter
            leftText={tab === 'upload' && dropped ? '1 file ready' : tab === 'gdrive' && driveChosen ? '1 file selected' : 'Pick files from any source'}
            primaryLabel={imported ? 'Importing…' : 'Import & Analyze'}
            primaryActive={(tab === 'upload' && dropped) || (tab === 'gdrive' && driveChosen)}
            primaryRef={importRef}
          />
        </ModalShell>

        <Cursor x={pos.x} y={pos.y} clicking={clicking} opacity={1 - exitT} />
      </div>
      <SceneCaption show={t > 0.3 && t < duration - 0.3} placement="bottom">
        FROM YOUR COMPUTER, GOOGLE DRIVE OR DROPBOX
      </SceneCaption>
    </div>
  );
}

// The shared TabBar with a ref on each tab, so the cursor can aim at them.
function TabBarRefs({ active, refs }) {
  const tabs = [
    { id: 'gdrive', label: 'Google Drive', icon: (
      <svg width="18" height="18" viewBox="0 0 24 24">
        <path d="M7.5 3l-6 10.5 3 5 6-10.5-3-5z" fill="#1FA463"/>
        <path d="M16.5 3h-9l6 10.5h9L16.5 3z" fill="#FFC107"/>
        <path d="M4.5 18.5h12l3-5h-12l-3 5z" fill="#3777E3"/>
      </svg>
    )},
    { id: 'dropbox', label: 'Dropbox', icon: (
      <svg width="18" height="18" viewBox="0 0 24 24">
        <path d="M6 3l6 4-6 4-6-4 6-4zM18 3l6 4-6 4-6-4 6-4zM0 13l6 4 6-4-6-4-6 4zM18 11l-6 4 6 4 6-4-6-4zM6 18l6 4 6-4-6-4-6 4z" fill="#0061FF"/>
      </svg>
    )},
    { id: 'upload', label: 'Upload Files', icon: (
      <svg width="18" height="18" viewBox="0 0 20 20" fill="none">
        <rect x="2" y="5" width="16" height="11" rx="1.5" stroke={BRAND.ink} strokeWidth="1.3"/>
        <path d="M2 10h16" stroke={BRAND.ink} strokeWidth="1.3"/>
      </svg>
    )},
  ];
  return (
    <div style={{ display: 'flex', borderBottom: `1px solid ${BRAND.border}`, padding: '0 28px', gap: 28 }}>
      {tabs.map((tb) => (
        <div key={tb.id} ref={refs[tb.id]} style={{
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '10px 2px 12px',
          fontSize: 14, fontWeight: 500,
          color: active === tb.id ? BRAND.ink : BRAND.subtle,
          borderBottom: active === tb.id ? `2px solid ${BRAND.ink}` : '2px solid transparent',
          marginBottom: -1,
          transition: 'color 160ms, border-color 160ms',
        }}>
          <div style={{ opacity: active === tb.id ? 1 : 0.7 }}>{tb.icon}</div>
          {tb.label}
        </div>
      ))}
    </div>
  );
}

// ─── Scene 2: sent to a lawyer from the chat ──────────────────────────────
function ReviewCard({ stage = 'brief', submitRef }) {
  const submitted = stage === 'submitted';
  return (
    <div style={{
      borderRadius: 32, border: `2px solid ${OV.line}`, background: OV.surface, overflow: 'hidden',
      boxShadow: '0 2px 6px rgba(28,25,23,0.05)',
    }}>
      <div style={{ display: 'flex', gap: 20, padding: '24px 32px', borderBottom: `2px solid ${OV.line}` }}>
        <div style={{ paddingTop: 4 }}>
          <Icon name={submitted ? 'check' : 'scale'} size={32} color={submitted ? OV.success : OV.indigo} />
        </div>
        <div>
          <div style={{ fontSize: 28, fontWeight: 600, color: OV.ink }}>
            {submitted ? 'Review request submitted' : 'Ready to send to a lawyer'}
          </div>
          <div style={{ fontSize: 22, color: OV.muted, marginTop: 4 }}>
            {submitted
              ? 'Your document is with our legal team. You can track its progress in My Requests.'
              : 'Check the brief below and edit anything, then send it through.'}
          </div>
        </div>
      </div>
      <div style={{ padding: '24px 32px 28px', display: 'flex', flexDirection: 'column', gap: 20 }}>
        {!submitted && (
          <>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20 }}>
              <BriefField label="Document type" value="Services agreement" />
              <BriefField label="Your role" value="Service provider" />
            </div>
            <BriefField label="Concerns" value="Payment terms in clause 6, and who owns the work in clause 11" />
            <div style={{ borderRadius: 24, border: `2px solid ${OV.line}`, background: OV.subtle, padding: '18px 24px' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 14, fontSize: 26, fontWeight: 500, color: OV.ink }}>
                <Icon name="creditCard" size={30} color={OV.muted} />
                Lawyer review fee
              </div>
              <div style={{ fontSize: 22, color: OV.muted, marginTop: 6 }}>
                Shown here before you submit, based on 9 pages. Nothing is charged until you do.
              </div>
            </div>
          </>
        )}
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 20 }}>
          {submitted ? (
            <>
              <AppButton variant="secondary">Go to My Documents</AppButton>
              <AppButton>Go to My Requests</AppButton>
            </>
          ) : (
            <>
              <AppButton variant="secondary">Keep chatting</AppButton>
              <AppButton buttonRef={submitRef} busy={stage === 'submitting'}>
                {stage === 'submitting' ? 'Sending…' : 'Submit for review'}
              </AppButton>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

function SceneSend() {
  const { localTime: t, duration } = useSprite();
  const rootRef = React.useRef(null);
  const submitRef = React.useRef(null);
  const submit = useLiveAnchor(submitRef, rootRef) || { x: 1500, y: 880 };

  const stage = t >= 4.9 ? 'submitted' : t >= 4.45 ? 'submitting' : 'brief';

  const pos = cursorAt(t, [[3.5, { x: submit.x - 520, y: submit.y - 320 }], [4.3, submit]]);
  const clicking = t > 4.35 && t < 4.52;
  const cursorOpacity = window_(t, 3.5, 4.9);

  return (
    <div ref={rootRef} style={{ position: 'absolute', inset: 0, opacity: fadeInOut(t, duration) }}>
      <ConversationPanel
        title="Review: Services Agreement"
        subtitle="Lawyer review"
        composer={<DockedComposer placeholder="Tell us about the document…" uploadLabel="Upload a document" />}
      >
        <Appear at={0.1} t={t}>
          <UserBubble><FileChip name={`Attached: ${DOC}`} /></UserBubble>
        </Appear>
        <Appear at={0.3} t={t}>
          <StepLine running="Reading the document" label="Read the document" done={t >= 0.9} />
        </Appear>
        <Appear at={0.95} t={t}>
          <AgentText>
            This is a services agreement between Acme Pty Ltd and your company. It sets the scope, the payment terms and who owns the work. The review would look closely at the 60-day payment terms in clause 6 and the ownership of deliverables in clause 11. What matters most to you here?
          </AgentText>
        </Appear>
        <Appear at={1.9} t={t}><UserBubble>Getting paid on time, and keeping ownership of our work.</UserBubble></Appear>
        <Appear at={2.3} t={t}>
          <AgentText>Thank you. We have put together a brief for the lawyer below. Check it over, then send it through.</AgentText>
        </Appear>
        <Appear at={2.6} t={t}><ReviewCard stage={stage} submitRef={submitRef} /></Appear>
      </ConversationPanel>
      <BigCursor x={pos.x} y={pos.y} clicking={clicking} opacity={cursorOpacity} />
      <SceneCaption show={t > 0.3 && t < duration - 0.3} placement="top">SENT TO A LAWYER FROM THE CHAT</SceneCaption>
    </div>
  );
}

// ─── Scene 3: the reviewed document comes back ────────────────────────────
function LawyerLine({ name, role, when }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 14 }}>
      <div style={{
        width: 52, height: 52, borderRadius: 26, background: OV.ink, color: '#FFFFFF',
        display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22, fontWeight: 600,
      }}>{name.split(' ').map((w) => w[0]).join('')}</div>
      <div style={{ fontSize: 24, color: OV.ink, fontWeight: 600 }}>{name}</div>
      <div style={{ fontSize: 22, color: OV.muted }}>{role} · Gosai Law · {when}</div>
    </div>
  );
}

function ReturnedFile({ downloadRef, downloading }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 24, padding: '22px 28px', borderRadius: 24,
      border: `2px solid ${OV.line}`, background: OV.surface, maxWidth: 1180,
    }}>
      <div style={{
        width: 72, height: 72, borderRadius: 18, background: '#EDF2FF', color: '#2B579A',
        display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      }}>
        <Icon name="fileText" size={38} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 26, fontWeight: 600, color: OV.ink, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
          {DOC_REVIEWED}
        </div>
        <div style={{ fontSize: 22, color: OV.muted, marginTop: 4 }}>Word document · tracked changes and 6 comments · 9 pages</div>
      </div>
      <AppButton buttonRef={downloadRef} busy={downloading}>{downloading ? 'Downloading…' : 'Download'}</AppButton>
    </div>
  );
}

// A corner of the returned Word document: a struck run, an inserted run, a comment.
function TrackedChangesPeek() {
  const del = { color: '#B91C1C', textDecoration: 'line-through', textDecorationColor: '#B91C1C' };
  const ins = { color: '#1D4ED8', textDecoration: 'underline', textDecorationColor: '#1D4ED8' };
  return (
    <div style={{
      display: 'flex', gap: 28, padding: '28px 32px', borderRadius: 24,
      border: `2px solid ${OV.line}`, background: '#FFFFFF', maxWidth: 1180,
      fontFamily: "'Times New Roman', Georgia, serif", color: '#1C1917',
    }}>
      <div style={{ flex: 1, fontSize: 24, lineHeight: 1.6 }}>
        <div style={{ fontWeight: 700, marginBottom: 10 }}>6. Payment</div>
        <div>
          6.1 The Client must pay each invoice within{' '}
          <span style={del}>60 days</span>{' '}
          <span style={ins}>14 days</span>{' '}
          of the date of the invoice.{' '}
          <span style={ins}>Interest accrues on any overdue amount at 2% per month.</span>
        </div>
        <div style={{ fontWeight: 700, margin: '18px 0 10px' }}>11. Intellectual property</div>
        <div>
          11.1 <span style={del}>All intellectual property in the Deliverables vests in the Client on creation.</span>{' '}
          <span style={ins}>The Provider owns the Deliverables until paid in full.</span>
        </div>
      </div>
      <div style={{
        width: 300, flexShrink: 0, alignSelf: 'flex-start', padding: '16px 18px', borderRadius: 16,
        background: '#FFF8E1', border: '2px solid #F5D77A', fontFamily: OV.body, fontSize: 20, lineHeight: 1.45, color: OV.ink,
      }}>
        <div style={{ fontWeight: 600, marginBottom: 6 }}>Sarsha Jones</div>
        Sixty days is long for a services contract. Fourteen is market, and interest helps if they pay late.
      </div>
    </div>
  );
}

function SceneReturn() {
  const { localTime: t, duration } = useSprite();
  const rootRef = React.useRef(null);
  const downloadRef = React.useRef(null);
  const download = useLiveAnchor(downloadRef, rootRef) || { x: 1380, y: 700 };

  const downloading = t >= 2.35 && t < 3.0;
  const peek = t >= 3.0;

  const pos = cursorAt(t, [[1.3, { x: download.x - 480, y: download.y + 260 }], [2.1, download]]);
  const clicking = t > 2.25 && t < 2.42;
  const cursorOpacity = window_(t, 1.3, 3.0);

  return (
    <div ref={rootRef} style={{ position: 'absolute', inset: 0, opacity: fadeInOut(t, duration) }}>
      <ConversationPanel
        title="Services Agreement review"
        subtitle="Completed"
        composer={<DockedComposer placeholder="Reply to your lawyer…" uploadLabel="Attach a file" />}
      >
        <Appear at={0.1} t={t}>
          <div>
            <LawyerLine name="Sarsha Jones" role="Lawyer" when="Today, 2:14 pm" />
            <AgentText>
              We have reviewed the agreement. Our tracked changes and comments are in the attached Word document, ready to send back to Acme.
            </AgentText>
          </div>
        </Appear>
        <Appear at={0.7} t={t}>
          <ReturnedFile downloadRef={downloadRef} downloading={downloading} />
        </Appear>
        {peek && (
          <Appear at={3.0} t={t}>
            <TrackedChangesPeek />
          </Appear>
        )}
      </ConversationPanel>
      <BigCursor x={pos.x} y={pos.y} clicking={clicking} opacity={cursorOpacity} />
      <SceneCaption show={t > 0.3 && t < duration - 0.3} placement="top">BACK AS A WORD DOCUMENT WITH TRACKED CHANGES</SceneCaption>
    </div>
  );
}

Object.assign(window, { SceneImport, SceneSend, SceneReturn, BigCursor });
