// Mean It — eulogy demo data + screen components.

const SCRIPT = {
  recipient: 'my grandfather, Tomas',
  occasion: 'eulogy',
  form: 'a short letter — read aloud',
  guide: 'documentarian',
  mascot: 'wren',
  theme: 'quiet',

  interview: [
    { q: "What did he always say when he answered the phone?",
      a: "He'd say 'Pronto, who's calling my house?' — like he was offended you'd dare. He wasn't.",
      mood: 'curious' },
    { q: "What's a thing he did that nobody else would have done?",
      a: "He kept a notebook in his coat pocket. Wrote down strangers' names on the bus so he could greet them next time.",
      mood: 'moved' },
    { q: "When you picture his hands — what are they doing?",
      a: "Fixing the radio. Always the same radio. Tuning the dial like it was a violin string.",
      mood: 'listening' },
    { q: "Was there a phrase only he used?",
      a: "'The world is wide and the kitchen is small.' He'd say it before any meal that took effort.",
      mood: 'moved' },
    { q: "What didn't you get to say?",
      a: "That I learned the radio thing. I tune the dial the same way now. I never told him.",
      mood: 'sad' },
  ],

  spineCandidates: [
    { t: "tuning the dial like it was a violin string", from: "q3 · his hands", picked: true },
    { t: "the world is wide and the kitchen is small", from: "q4 · his phrase" },
    { t: "I tune the dial the same way now", from: "q5 · what you didn't say" },
  ],

  structure: [
    { label: 'memory', sub: 'the radio, his hands' },
    { label: 'phrase', sub: '"world is wide…"' },
    { label: 'inheritance', sub: 'the dial · the silence · what wasn\'t said' },
  ],

  draft: [
    { text: "Tomas kept a notebook in his coat pocket.", verified: true, src: 'q2' },
    { text: "He wrote down strangers' names so he could greet them next time.", verified: true, src: 'q2' },
    { text: "His hands tuned the radio dial like it was a violin string.", verified: true, src: 'q3' },
    { text: "He used to say: the world is wide and the kitchen is small.", verified: true, src: 'q4' },
    { text: "He was forever in our hearts.", verified: false, src: null, flag: 'cliche' },
    { text: "I tune the dial the same way now.", verified: true, src: 'q5' },
    { text: "I never told him.", verified: true, src: 'q5' },
  ],
};

// ─────────── PICK THE MOMENT (B+C hybrid: feeling cards → conversational parse) ───────────

function PickMoment({ go, auto }) {
  const [feeling, setFeeling] = React.useState(null);
  const [text, setText] = React.useState('');
  const [cursorPos, setCursorPos] = React.useState({ x: 0, y: 0 });
  const [cursorVisible, setCursorVisible] = React.useState(false);
  const [clicking, setClicking] = React.useState(false);
  const [callout, setCallout] = React.useState(null);
  const [revealHeard, setRevealHeard] = React.useState(false);

  const cardRefs = React.useRef([]);
  const textareaRef = React.useRef(null);
  const buttonRef = React.useRef(null);

  const feelings = [
    { id: 'goodbye',     h: 'a goodbye',     s: 'eulogy · final letter' },
    { id: 'celebration', h: 'a celebration', s: 'birthday · wedding'    },
    { id: 'thanks',      h: 'a thank you',   s: 'gratitude · just because' },
    { id: 'apology',     h: 'an apology',    s: 'making it right'       },
    { id: 'love',        h: 'a love note',   s: 'partner · friend'      },
    { id: 'else',        h: 'something else',s: 'tell me more'          },
  ];

  const DEMO_TEXT = "My grandfather, Tomas. He passed last month. The service is Saturday. I want to say something true.";
  const INTRO_MS = (typeof window !== 'undefined' && window._demoIntroShown) ? 0 : 3400;

  // manual mode: keep the original instant fill behavior
  React.useEffect(() => {
    if (auto) return;
    if (feeling === 'goodbye') setText(DEMO_TEXT);
  }, [feeling, auto]);

  // auto-demo orchestrator
  React.useEffect(() => {
    if (!auto) return;
    let cancelled = false;
    const wait = (ms) => new Promise(r => setTimeout(r, ms));
    const moveTo = (el, opts = {}) => {
      if (!el) return;
      const r = el.getBoundingClientRect();
      setCursorPos({
        x: r.left + (opts.offsetX != null ? opts.offsetX : r.width / 2),
        y: r.top + (opts.offsetY != null ? opts.offsetY : r.height / 2),
      });
    };
    const calloutAbove = (el, msg, dy = 0) => {
      if (!el) return;
      const r = el.getBoundingClientRect();
      setCallout({ x: r.left + r.width / 2, y: r.top + dy, text: msg });
    };

    (async () => {
      // ── intro: point at demo controls (only on first run) ──
      if (INTRO_MS > 0) {
        await wait(500);
        if (cancelled) return;
        const ctrl = document.getElementById('demo-controls');
        if (ctrl) {
          const r = ctrl.getBoundingClientRect();
          setCursorPos({ x: r.left - 16, y: r.top - 16 });
          setCursorVisible(true);
          setCallout({ x: r.left + r.width / 2, y: r.top, text: 'pause · restart · anytime' });
        }
        await wait(2700);
        if (cancelled) return;
        setCallout(null);
        // glide cursor up + away so it's not blocking the page
        setCursorPos({ x: window.innerWidth - 220, y: window.innerHeight - 380 });
        await wait(200);
        if (cancelled) return;
        if (typeof window !== 'undefined') window._demoIntroShown = true;
      } else {
        // skip intro on subsequent loops; cursor pre-staged
        setCursorPos({ x: window.innerWidth - 220, y: window.innerHeight - 380 });
        setCursorVisible(true);
      }

      // headers + cards are static — short breath before the first action
      await wait(700);
      if (cancelled) return;

      // step 1 — pick the feeling
      const card0 = cardRefs.current[0];
      calloutAbove(card0, 'pick how this moment feels');
      await wait(2100);
      if (cancelled) return;
      moveTo(card0);
      await wait(2250);
      if (cancelled) return;
      setClicking(true);
      await wait(420);
      if (cancelled) return;
      setFeeling('goodbye');
      await wait(570);
      setClicking(false);
      setCallout(null);

      // step 2 — describe what's going on
      await wait(1650);
      if (cancelled) return;
      const ta = textareaRef.current;
      calloutAbove(ta, "tell it what's going on");
      moveTo(ta, { offsetX: 60, offsetY: 28 });
      await wait(2250);
      if (cancelled) return;

      for (let i = 1; i <= DEMO_TEXT.length; i++) {
        if (cancelled) return;
        setText(DEMO_TEXT.slice(0, i));
        await wait(33);
      }

      await wait(800);
      if (cancelled) return;
      setCallout(null);
      setRevealHeard(true);
      await wait(850);
      if (cancelled) return;

      const btn = buttonRef.current;
      calloutAbove(btn, 'on to the next step');
      moveTo(btn);
      await wait(2250);
      if (cancelled) return;
      setClicking(true);
      await wait(480);
      if (cancelled) return;
      go();
    })();

    return () => { cancelled = true; };
  }, [auto]);

  return (
    <div className="stage" style={{ paddingTop: 56 }}>
      <div className="eyebrow">a moment that matters</div>
      <h1 className="h-display" style={{ marginTop: 8, marginBottom: 18 }}>
        What kind of moment<br/>is this?
      </h1>
      <div className="body-prose" style={{ maxWidth: 540, marginBottom: 32 }}>
        Pick by feeling. We'll figure out the form together.
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14 }}>
        {feelings.map((f, i) => (
          <button
            key={f.id}
            ref={el => cardRefs.current[i] = el}
            onClick={() => setFeeling(f.id)}
            className={'card ' + (feeling === f.id ? 'selected' : feeling ? 'bare' : 'outlined')}
            style={{
              textAlign: 'left', cursor: 'pointer', minHeight: 120,
              padding: '20px 22px',
              fontFamily: 'inherit', color: 'inherit',
              transition: 'all 300ms',
            }}
          >
            <div className="serif-italic" style={{ fontSize: 26, lineHeight: 1.1, color: 'var(--t-ink)' }}>{f.h}</div>
            <div className="eyebrow" style={{ marginTop: 8 }}>{f.s}</div>
          </button>
        ))}
      </div>

      {feeling && (
        <div style={{ marginTop: 40 }}>
          <div className="eyebrow">tell me what's going on</div>
          <textarea
            ref={textareaRef}
            className="textarea-prose"
            style={{ marginTop: 12, fontSize: 19 }}
            rows={4}
            value={text}
            onChange={e => setText(e.target.value)}
            placeholder="who · the occasion · anything specific you want to say…"
          />
          {(revealHeard || (!auto && text.length > 30)) && (
            <div style={{ marginTop: 22, animation: 'fadein 600ms ease' }}>
              <div className="eyebrow">i heard…</div>
              <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 10 }}>
                <span className="tag on">recipient · grandfather, Tomas</span>
                <span className="tag on">occasion · eulogy</span>
                <span className="tag on">when · Saturday</span>
                <span className="tag">tone · still listening</span>
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 32, alignItems: 'center' }}>
                <span className="muted" style={{ fontFamily: 'var(--t-mono)', fontSize: 11 }}>edit any pill — or keep going</span>
                <button ref={buttonRef} className="btn primary" onClick={go}>pick a guide →</button>
              </div>
            </div>
          )}
        </div>
      )}

      {auto && cursorVisible && <VirtualCursor x={cursorPos.x} y={cursorPos.y} clicking={clicking}/>}
      {auto && callout && <TourCallout x={callout.x} y={callout.y} text={callout.text}/>}
    </div>
  );
}

// ─────────── GUIDE PICKER (variant C with mascot inside) ───────────

function GuidePicker({ go, openCreateGuide, auto, modalOpen }) {
  const [pick, setPick] = React.useState(null);
  const [cursorPos, setCursorPos] = React.useState({ x: 0, y: 0 });
  const [cursorVisible, setCursorVisible] = React.useState(false);
  const [clicking, setClicking] = React.useState(false);
  const [callout, setCallout] = React.useState(null);

  const guideRefs = React.useRef({});
  const createGuideRef = React.useRef(null);
  const beginRef = React.useRef(null);

  const guides = [
    { id: 'wren',   tag: 'memory · specifics',         desc: 'pulls for moments only one person remembers. low-key, patient.', sample: '"What did he always say when he answered the phone?"' },
    { id: 'pip',    tag: 'sensory noticing',           desc: 'pulls for the smell, the sound, the small thing nobody else saw.', sample: '"What\'s a smell that means home?"' },
    { id: 'cassio', tag: 'unresolved feeling',         desc: 'pulls for what didn\'t get said. comfortable with quiet.',           sample: '"What didn\'t you get to say?"' },
  ];

  React.useEffect(() => {
    if (!auto) return;
    let cancelled = false;
    const wait = (ms) => new Promise(r => setTimeout(r, ms));
    const moveTo = (el, opts = {}) => {
      if (!el) return;
      const r = el.getBoundingClientRect();
      setCursorPos({
        x: r.left + (opts.offsetX != null ? opts.offsetX : r.width / 2),
        y: r.top + (opts.offsetY != null ? opts.offsetY : r.height / 2),
      });
    };
    const calloutAbove = (el, msg) => {
      if (!el) return;
      const r = el.getBoundingClientRect();
      setCallout({ x: r.left + r.width / 2, y: r.top, text: msg });
    };

    (async () => {
      // stage cursor near top-right
      setCursorPos({ x: window.innerWidth * 0.7, y: 200 });
      setCursorVisible(true);
      await wait(900);
      if (cancelled) return;

      // ── show "you can build your own guide" path ──
      const cg = createGuideRef.current;
      calloutAbove(cg, 'or build one of your own');
      moveTo(cg);
      await wait(1700);
      if (cancelled) return;

      setClicking(true);
      await wait(220);
      if (cancelled) return;
      setCallout(null);
      setCursorVisible(false);
      openCreateGuide();
      await wait(220);
      setClicking(false);

      // wait for the modal's auto-demo to finish (it closes itself)
      await wait(26000);
      if (cancelled) return;

      // resume guide picker — pick the documentarian (wren)
      setCursorPos({ x: window.innerWidth * 0.5, y: 180 });
      setCursorVisible(true);
      await wait(550);
      if (cancelled) return;

      const wren = guideRefs.current.wren;
      calloutAbove(wren, 'or pick a ready-made one — the documentarian');
      moveTo(wren);
      await wait(1700);
      if (cancelled) return;
      setClicking(true);
      await wait(220);
      setPick('wren');
      await wait(280);
      setClicking(false);
      setCallout(null);

      // step → click "begin with wren"
      await wait(900);
      if (cancelled) return;
      const btn = beginRef.current;
      calloutAbove(btn, 'begin');
      moveTo(btn);
      await wait(1700);
      if (cancelled) return;
      setClicking(true);
      await wait(320);
      if (cancelled) return;
      go();
    })();

    return () => { cancelled = true; };
  }, [auto]);

  return (
    <div className="stage">
      <div className="eyebrow">three ways of being listened to</div>
      <h1 className="h-display smaller" style={{ marginTop: 8, marginBottom: 8 }}>Pick the kind of attention<br/>this moment needs.</h1>
      <div className="body-prose" style={{ maxWidth: 580, marginBottom: 28 }}>
        Each one asks differently. None of them write for you. Ever.
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        {guides.map(g => {
          const M = MASCOTS[g.id];
          return (
            <button key={g.id}
              ref={el => guideRefs.current[g.id] = el}
              onClick={() => setPick(g.id)}
              className={'card ' + (pick === g.id ? 'selected' : 'outlined')}
              style={{
                display: 'grid', gridTemplateColumns: '90px 1fr auto',
                gap: 22, alignItems: 'center',
                textAlign: 'left', cursor: 'pointer', padding: '18px 22px',
                fontFamily: 'inherit', color: 'inherit',
              }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <MascotView id={g.id} emotion={pick === g.id ? 'curious' : 'listening'} size={72}/>
              </div>
              <div>
                <div className="serif-italic" style={{ fontSize: 24, color: 'var(--t-ink)' }}>{M.guide}</div>
                <div className="eyebrow" style={{ marginTop: 4 }}>pulls for · {g.tag}</div>
                <div className="body-prose" style={{ fontSize: 15, marginTop: 8, color: 'var(--t-ink-soft)' }}>{g.desc}</div>
                <div className="serif-italic" style={{ fontSize: 14, fontStyle: 'italic', marginTop: 8, color: 'var(--t-ink-faint)' }}>
                  sample · {g.sample}
                </div>
              </div>
              <div style={{ fontFamily: 'var(--t-mono)', fontSize: 10, color: 'var(--t-ink-faint)', letterSpacing: '0.14em' }}>
                {pick === g.id ? '● selected' : '○ pick'}
              </div>
            </button>
          );
        })}

        <div ref={createGuideRef} className="card bare" onClick={openCreateGuide} style={{
          display: 'flex', alignItems: 'center', gap: 16, padding: '14px 22px', cursor: 'pointer',
        }}>
          <div style={{
            width: 60, height: 60, borderRadius: '50%',
            border: '1.5px dashed var(--t-ink-faint)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'var(--t-display)', fontStyle: 'italic', fontSize: 28, color: 'var(--t-ink-faint)',
          }}>+</div>
          <div style={{ flex: 1 }}>
            <div className="serif-italic" style={{ fontSize: 20, color: 'var(--t-ink)' }}>Create your own guide</div>
            <div className="muted" style={{ fontFamily: 'var(--t-mono)', fontSize: 11, marginTop: 2 }}>
              describe how you want to be paid attention to · share it via link
            </div>
          </div>
        </div>
      </div>

      <div className="divider-flourish"/>

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <span className="muted" style={{ fontFamily: 'var(--t-mono)', fontSize: 11 }}>
          guide rules: ask · mirror · propose structure · never draft
        </span>
        <button ref={beginRef} className="btn primary" onClick={go} disabled={!pick} style={{ opacity: pick ? 1 : 0.4 }}>begin with {pick ? MASCOTS[pick].name : 'a guide'} →</button>
      </div>

      {auto && cursorVisible && !modalOpen && <VirtualCursor x={cursorPos.x} y={cursorPos.y} clicking={clicking}/>}
      {auto && callout && !modalOpen && <TourCallout x={callout.x} y={callout.y} text={callout.text}/>}
    </div>
  );
}

// ─────────── INTERVIEW (split A — with live mascot emotion) ───────────

function Interview({ go, setEmotion, auto }) {
  const [qIdx, setQIdx] = React.useState(0);
  const [answers, setAnswers] = React.useState(SCRIPT.interview.map(() => ''));
  const [showMirror, setShowMirror] = React.useState(false);
  const cur = SCRIPT.interview[qIdx];

  const [cursorPos, setCursorPos] = React.useState({ x: 0, y: 0 });
  const [cursorVisible, setCursorVisible] = React.useState(false);
  const [clicking, setClicking] = React.useState(false);
  const [callout, setCallout] = React.useState(null);

  const textareaRef = React.useRef(null);
  const nextRef = React.useRef(null);
  const mirrorRef = React.useRef(null);

  React.useEffect(() => { setEmotion(cur.mood); }, [qIdx]);

  const onChange = e => {
    const next = [...answers]; next[qIdx] = e.target.value;
    setAnswers(next);
    if (e.target.value.length > 60 && !showMirror) setShowMirror(true);
  };
  const next = () => {
    setShowMirror(false);
    if (qIdx < SCRIPT.interview.length - 1) setQIdx(qIdx + 1);
    else go();
  };

  // manual mode: pre-fill demo answers when stepping
  React.useEffect(() => {
    if (auto) return;
    if (!answers[qIdx]) {
      const t = setTimeout(() => {
        const nextAns = [...answers]; nextAns[qIdx] = SCRIPT.interview[qIdx].a;
        setAnswers(nextAns);
        setShowMirror(true);
      }, 400);
      return () => clearTimeout(t);
    }
  }, [qIdx, auto]);

  // auto-demo orchestrator — runs once per qIdx
  React.useEffect(() => {
    if (!auto) return;
    let cancelled = false;
    const wait = (ms) => new Promise(r => setTimeout(r, ms));
    const moveTo = (el, opts = {}) => {
      if (!el) return;
      const r = el.getBoundingClientRect();
      setCursorPos({
        x: r.left + (opts.offsetX != null ? opts.offsetX : r.width / 2),
        y: r.top + (opts.offsetY != null ? opts.offsetY : r.height / 2),
      });
    };
    const calloutAbove = (el, msg) => {
      if (!el) return;
      const r = el.getBoundingClientRect();
      setCallout({ x: r.left + r.width / 2, y: r.top, text: msg });
    };

    (async () => {
      // first question — no mirror yet
      if (qIdx === 0) {
        setCursorPos({ x: window.innerWidth * 0.7, y: 200 });
        setCursorVisible(true);
        await wait(600);
        if (cancelled) return;
        calloutAbove(textareaRef.current, 'the guide asks · you answer');
        await wait(1200);
        if (cancelled) return;
      } else {
        // show "holding" mirror callout briefly
        await wait(450);
        if (cancelled) return;
        if (mirrorRef.current) {
          calloutAbove(mirrorRef.current, 'still holding what you said before');
          await wait(2000);
          if (cancelled) return;
          setCallout(null);
          await wait(250);
          if (cancelled) return;
        }
      }

      // type the answer
      setCallout(null);
      moveTo(textareaRef.current, { offsetX: 60, offsetY: 30 });
      await wait(750);
      if (cancelled) return;
      const target = SCRIPT.interview[qIdx].a;
      for (let i = 1; i <= target.length; i++) {
        if (cancelled) return;
        const nextAns = [...answers]; nextAns[qIdx] = target.slice(0, i);
        setAnswers(nextAns);
        if (i > 60 && !showMirror) setShowMirror(true);
        await wait(15);
      }
      setShowMirror(true);
      await wait(700);
      if (cancelled) return;

      const isLast = qIdx === SCRIPT.interview.length - 1;

      // last question — hover the held phrase before advancing
      if (isLast && mirrorRef.current) {
        calloutAbove(mirrorRef.current, 'every phrase · still held · still yours');
        moveTo(mirrorRef.current, { offsetX: 30, offsetY: 30 });
        await wait(2400);
        if (cancelled) return;
        setCallout(null);
        await wait(350);
        if (cancelled) return;
      }

      // cursor to next button
      calloutAbove(nextRef.current, isLast ? 'find the spine' : 'next');
      moveTo(nextRef.current);
      await wait(1100);
      if (cancelled) return;
      setClicking(true);
      await wait(240);
      if (cancelled) return;
      setCallout(null);
      next();
      await wait(360);
      setClicking(false);
    })();

    return () => { cancelled = true; };
  }, [auto, qIdx]);

  return (
    <div className="stage" style={{ maxWidth: 1180 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 22 }}>
        <div className="eyebrow">interview · {MASCOTS[SCRIPT.mascot].guide}</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <span className="muted" style={{ fontFamily: 'var(--t-mono)', fontSize: 10 }}>q{qIdx + 1} / {SCRIPT.interview.length}</span>
          <div className="progress-dots">
            {SCRIPT.interview.map((_, i) => <div key={i} className={'d ' + (i <= qIdx ? 'on' : '')}/>)}
          </div>
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 56, alignItems: 'start' }}>
        {/* LEFT — guide side */}
        <div style={{ paddingTop: 8, position: 'relative' }}>
          <div style={{ marginBottom: 22 }}>
            <MascotView id={SCRIPT.mascot} emotion={cur.mood} size={84}/>
          </div>
          <div className="eyebrow" style={{ marginBottom: 10 }}>the guide is asking</div>
          <div className="serif-italic" style={{ fontSize: 36, lineHeight: 1.2, color: 'var(--t-ink)' }}>
            {cur.q}
          </div>

          {showMirror && qIdx > 0 && (
            <div ref={mirrorRef} className="card" style={{
              marginTop: 28, padding: '14px 18px',
              borderLeft: '2px solid var(--t-accent)',
              animation: 'fadein 600ms ease',
            }}>
              <div className="eyebrow" style={{ color: 'var(--t-accent)' }}>holding · from your last answer</div>
              <div className="serif-italic" style={{ fontSize: 18, fontStyle: 'italic', marginTop: 6, color: 'var(--t-ink)' }}>
                "<span className="hl">{SCRIPT.interview[qIdx-1].a.split(/[.!?]/)[0]}</span>"
              </div>
            </div>
          )}
        </div>

        {/* RIGHT — user side */}
        <div>
          <div className="eyebrow" style={{ marginBottom: 10 }}>your turn · take your time</div>
          <textarea
            ref={textareaRef}
            className="textarea-prose"
            value={answers[qIdx]}
            onChange={onChange}
            rows={7}
            placeholder="something specific. one detail is enough."
            style={{ fontSize: 19, minHeight: 200 }}
          />
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 14, alignItems: 'center' }}>
            <span className="muted" style={{ fontFamily: 'var(--t-mono)', fontSize: 10 }}>
              {answers[qIdx].split(/\s+/).filter(Boolean).length} words · all yours
            </span>
            <div style={{ display: 'flex', gap: 8 }}>
              <button className="btn ghost sm">↺ rephrase</button>
              <button ref={nextRef} className="btn primary" onClick={next}>
                {qIdx < SCRIPT.interview.length - 1 ? 'next →' : 'find the spine →'}
              </button>
            </div>
          </div>
        </div>
      </div>

      {auto && cursorVisible && <VirtualCursor x={cursorPos.x} y={cursorPos.y} clicking={clicking}/>}
      {auto && callout && <TourCallout x={callout.x} y={callout.y} text={callout.text}/>}
    </div>
  );
}

Object.assign(window, { SCRIPT, PickMoment, GuidePicker, Interview });
